zoukankan      html  css  js  c++  java
  • java面试集锦

    HashMap和HashTable的区别

    他们都是Map接口的实现类,实现了将唯一键值映射到特定的值上。

    这里写图片描述

    HashMap没有分类或者排序,它允许一个null和多个null值。
    HashTable类似于HashMap,但是不允许有null键和null值。它比hashMap要慢,因为它是同步的(即线程安全的)
    HashTable继承自Dictionart类,而HashMap是java1.2引进的Map接口的一个实现类。
    HashMap允许将null作为一个entry的key或者value,而HashTable不允许,HashMap还去除了hashTable的contains方法,改成了containavalue()和containskey()方法。
    两者最大的不同是,HashTable的方法是Synchronize的,而HashMap却不是,在多线程访问HashTable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供而外的同步。

    HashMap和HashTable采用hash/rehash的算法类似,因此性能不会产生很大的差异。

    重载和覆盖的区别

    对于在同一个区内被声明的几个具有不同参数列的同名函数,程序会根据不同的参数列来切定具体调用哪一个函数,这种机制叫重载(overload),重载不管系函数的返回值类型。
    覆盖(override)是指派生类中重新定义的函数,其函数名、参数列、返回值类型必须与父类中哦够的函数保持严格的一致。覆盖函数和被覆盖的只有函数体不同,宕派生类对象调用子类该同名函数时会自动调用子类中的覆盖版本,而不是父类中被覆盖的函数,这种机制叫做覆盖。

    关于覆盖的使用请参考下面的代码。

    package com.company;
    
    /**
     * Created by shugen on 17-3-3.
     */
    public class OverLoad {
    
        public static void main(String[] args) {
            A ref = new AC();
            ref.print();
            AC ref2 = new AC();
            ref2.print();
        }
    }
    class A {
    
        public void print() {
            System.out.println("this is class A");
        }
    }
    class AC extends A {
        @Override
        public void print() {
            System.out.println("this is class B");
        }
    }

    程序的执行结果如下:

    enter description here

    在上面的代码中,即使ref被声明为A类型的,但是java中存在形式类型和实际类型。此时ref的形式类型时A,但是ref的实际类型确是AC。因此ref也是调用子类AC的print方法。

    成员函数的重载的特征如下:

    (1) 相同的范围(在同一个类中)
    (2) 函数名字相同
    (3)参数不同
    (4)virtual关键字可有可无

    覆盖的特征如下:
    (1)不同的范围(分别位于父类和子类或者叫做派生类中)
    (2)函数名字相同
    (3)参数相同

    ### 静态方法的覆盖问题
    为了方便展示static方法的可覆盖性,先提供下面的基础代码:

     class STA {
        public static void print() {
            System.out.println("Hello, it's STA");
        }
        private void ge(){
            System.out.println("这是私有的方法");
        }
    }
    class STAC extends STA{
        public static void print(){
            System.out.println("Hello, it's STAC");
        }
        public void ge(){
            System.out.println("这是覆盖后的非私有方法");
        }
    }

    结论:
    (1)静态方法,不能被覆盖成非静态方法
    如下图,放尝试覆盖父类的static方法为非static方法时,IDE开始报错。

    enter description here

    (2)私有方法可以被覆盖

    enter description here

    从上图可以看出,父类的静态方法是可以被子类继承的,但是以父类作为形式类型却是不能访问被覆盖的父类的方法的。

    关于静态方法在父类和子类中的调用问题

    package com.company;
    
    /**
     * Created by shugen on 17-3-3.
     */
    public class StaticCall {
        public static void main(String[] args) {
    
            F f1 = new F();
            F f2 = new C();
            System.out.println(f1.getName());
            System.out.println(f2.getName());
        }
    }
    
    class F {
        public static String getName(){
            return "F";
        }
    }
    class C extends F{
        public static String getName(){
            return "C";
        }
    }

    程序的输出如下:
    enter description here

    出现这种现象的原因时,程序中的两个getName方法时静态方法,所以在内存中的地址空间时固定的,不存在冲突的问题。也就是折两个方法在内存中占用了不同的空间,而具体执行哪一个则要看由哪个类来调用,因为时静态方法,且两个引用变量都是F类型的,因此,这里调用的都是F类中的getName方法。

    super构造函数的位置

    如果要想在子类中使用super构造函数,则必须吧super()放在子类代码的第一行的位置。

    enter description here

    从上图中可以看到,把super放在了子类的构造函数的第二行时,编译器就会报错了。因此,如果在使用super构造函数时不将其放在代码的第一行就会造成编译器报错(即编译错误)

    抽象类相关的性质

    (1)抽象类只能作为其他类的基类,不能被直接实例化,而且对抽象类不能使用new操作。抽象类如果包含有抽象的变量或者值,则它们要么时null类型,要么包含了对非抽象类的实例的引用。
    (2)抽象类允许包含抽象成员,但不是必须的,抽象类中可以有非抽象方法。
    (3)抽象类不能时final的。因为final是不能被继承的,因此声明成fianal的抽象类没有实际意义,java是不允许的。
    (4)如果一个非抽象类从抽象类中派生,则其必须要覆盖抽象类的所有抽象方法。
    (5)抽象类可以被抽象类继承,结果仍是抽象类。
    (6)抽象类可以被声明。
    (7)抽象类可以不包含任何抽象方法或者抽成员。

    enter description here

    从上图可以看出,一个抽象类可以不包括任何成员变量或者成员方法。

  • 相关阅读:
    c++ 动态判断基类指针指向的子类类型(typeid)
    qt在GUI显示时,将调试信息输出到控制台的设置
    Qt库版查询
    Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明
    ICMP timestamp 请求响应漏洞
    linux 防火墙 ufw使用
    MySQL--binlog和relay log的生成和删除
    SSD 相关基础知识
    python36--将数据保存为excel
    MySQL 5.7并发复制和mysqldump相互阻塞引起的复制延迟
  • 原文地址:https://www.cnblogs.com/shugen/p/6862973.html
Copyright © 2011-2022 走看看