• java面试题:基础知识


    类和对象

    Q:讲一下面向对象OOP思想。
    面向对象主要是抽象,封装,继承,多态。
    多态又分为重载和重写。重载主要是方法参数类型不一样,重写则是方法内容不一样。
    Q:抽象类和接口有什么区别?

    1. 抽象类中可以没有抽象方法;接口中的方法必须是public abstract抽象方法;
    2. 抽象类中可以有普通的成员变量;接口中的变量必须是public static final 类型的,必须被初始化,接口中只有常量,没有变量。
    3. 抽象类只能单继承,接口可以继承多个父接口;
    4. Java 8 中接口中会有 default 方法,即方法可以被实现。

    Q:java是值传递还是引用传递?
    java是值传递。
    因为 Java 是值传递的,也就是说,我们在调用一个需要传递参数的函数时,传递给函数的参数并不是我们传递进去的参数本身,而是它的一个副本,我们改变了数据其实只是改变了副本的数据而已,并不会对原来的参数有任何的改变。
    Q:类初始化的顺序是怎样的?
    创建类的对象的时候,先初始化静态变量和静态代码块(静态变量和静态代码块的初始化顺序按照在类中的先后顺序),然后再初始化非静态变量和非静态代码块(非静态变量和非静态代码块之间也是按照在类中的先后顺序),如果非静态变量未显示赋值会被赋值为默认值。最后执行构造函数。
    Q:final修饰符有什么作用?
    1.final修饰的类,不可以被继承。
    2.final修饰方法,可以把方法锁定,以防任何继承类修改它的含义。
    3.fianl修饰的变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
    Q:创建对象的方式有哪些?
    new,反射(包括使用Class类的newInstance方法和Constructor类的newInstance方法),clone,反序列化
    还可以使用建造者模式。

    Object

    Q:Object有哪些方法?
    getClass(),hashCode(),equals(),wait(),notify(),notifyAll(),toString(),finalize(),clone()
    Q:如何理解hashCode()?
    Q:hashCode()和equals()有什么联系?
    重写equals()必须重写hashCode()。
    首先equals与hashcode间的关系是这样的:
    1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
    2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)
    Q:clone()的深复制和浅复制,有什么区别?
    浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
    深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

    基础类型

    Q:基础类型有哪些?怎么比较?
    int,char,float,double都是基本类型。 String不是基本类型。
    基础类型直接用==比较。
    Q:Integer和int的区别?
    Integer是int的包装类。
    Integer默认值是null,int默认值是0。
    int默认是4个字节,Integer是16个字节。

    Q:Integer和int怎么比较?Integer怎么比较?
    Integer是int的包装类。Integer跟Integer不可以使用比较。
    Integer跟int可以使用
    比较,Integer会自动拆箱。

    String

    Q:String怎么比较?从内存角度讲。
    使用equals()比较。如果使用==比较的是内存,使用equals()比较的是对象的内容。
    Q:String可以继承吗?
    String用final修饰,不可以继承。
    Q:String和StringBulider、StringBuffer有什么区别?
    String长度不可变。StringBuilder、StringBuffer长度可变。
    StringBuffer是线程安全的,StringBuilder是线程不安全的。
    StringBuffer通过synchronized 关键字来实现同步操作
    Q:String里面的equals()是怎么实现的?

    IO

    Q:IO中用到了哪些设计模式?
    IO中用到了装饰器模式,适配器模式。
    装饰器模式表现如: BufferedReader reader=new BufferedReader(new FileReader( new File(fileName)));
    同样是增强对象的功能,为什么使用装饰器, 而不是继承?
    比如功能一,功能二,功能三。装饰器可以根据需要增强功能,随意组合装配。
    而由于功能的随机组合有六种,想通过继承增强功能要写六个类。当需要的功能较多时,组合总和太大,通过继承完成不太理想。

    异常

    Q:Java中的异常有哪些?
    Exception分为运行时异常和非运行时异常。
    RuntimeException, 运行时异常,特点是Java编译器不会检查它。
    非运行时异常 (编译异常): 是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
    Error:用于指示合理的应用程序不应该试图捕获的严重问题。如OutOfMemoryError、StackOverFlowError。
    Q:RuntimeException有哪些?
    空指针异常类:NullPointerException
    类型强制转换异常:ClassCastException
    数组下标越界异常:ArrayIndexOutOfBoundsException
    文件已结束异常:EOFException
    文件未找到异常:FileNotFoundException
    字符串转换为数字异常:NumberFormatException
    操作数据库异常:SQLException
    输入输出异常:IOException
    方法未找到异常:NoSuchMethodException
    Q:什么时候会出现OutOfMemoryError、StackOverFlowError?
    内存溢出OutOfMemoryError,当内存不够用时,会抛出OutOfMemoryError。需要优化代码,或者调整jvm参数,通过-Xmx将最大内存数调大。
    栈溢出StackOverFlowError,当大量嵌套递归时,可能会出现StackOverFlowError,递归从本质上讲也是栈的使用。

    Jdk

    Q:Jdk各个版本有哪些差别?
    Q:Jdk1.8以后的特性,有没有了解过?
    Jdk1.5:foreach迭代,可变参数,枚举,自动拆装箱,泛型,注解;
    Jdk1.6:轻量级HttpServer的API,使用Complier API,对脚本语言的支持;
    Jdk1.7:Switch支持字符串,泛型类型自动推断,try-with-resource资源关闭技巧(省去了自己在finally里去关闭资源),Objects工具类,ForkJoinPool
    Jdk1.8:接口的默认方法实现与静态方法,Lambda表达式,函数式接口,方法与构造函数引用,新的日期与时间API,流式处理。
    Jdk1.9:优化了HTTP Client,支持HTTP/2和HTTPS/TLS协议。
    Jigsaw模块化项目,简化进程API,轻量级JSON API,钱和货币的API,进程改善和锁机制优化,代码分段缓存。
    Jdk10:局部变量的类型推断var,改进GC和内存管理,线程本地握手,备用内存设备上的堆分配
    Jdk11:可拓展的低延迟垃圾收集器ZGC。
    Q:Java8的Lambda表达式,你会用吗?可以做哪些事情?能否手写一下?
    匿名函数式。可以进行筛选,排序,求值,查找等功能。
    Q:看过哪些Jdk源码?
    集合,多线程,并发。

    集合(重点)

    关键词:ArrayList、LinkedList、HashTable、HashMap、ConcurrentHashMap、HashSet、
    Q:List和Set有什么区别?
    List有序可重复,Set无序不重复

    ArrayList

    Q:ArrayList和LinkedList有什么区别?(常问)
    ArrayList数据结构是数组,查询比较快。LinkedList是一个双向链表,增删比较快。
    Q:ArrayList什么时候扩容?如何扩容?扩容多少?
    ArrayList在初始化的时候,是不会扩容的。比如List list=new ArrayList(20); 执行这句代码时不会进行扩容。
    ArrayList数组的初始长度是10,当数组填满后会进行扩容,每次扩容0.5倍,也就是原来的1.5倍。
    扩容的过程,由于数组的长度是不可变的,只能新建一个数组。
    扩容的过程就是数组拷贝 Arrays.copyOf的过程,每一次扩容就会开辟一块新的内存空间和数据的复制移动。

    HashSet

    Q:讲一下HashSet
    无序不重复,允许为null。
    Q:HashSet是怎么实现的?
    基于HashMap来实现的,底层采用HashMap来保存元素。
    Q:HashSet源码是怎么实现不重复的?
    HashMap的key是不能重复的,而这里HashSet的元素又是作为了map的key,当然也不能重复了。
    HashMap的key怎么保证是不能重复的?
    HashMap调用了对象的hashCode和equals方法进行的判断。

    TreeSet

    Q:TreeSet和HashSet的区别是什么?
    TreeSet是有序的,HashSet是无序的。
    Q:TreeSet的数据结构是什么?
    底层是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。
    Q:红黑树有哪些特点?
    红黑树是一种自平衡排序二叉树,树中每个节点的值,都大于或等于在它的左子树中的所有节点的值,并且小于或等于在它的右子树中的所有节点的值,这确保红黑树运行时可以快速地在树中查找和定位的所需节点。

    HashTable

    Q:HashTable是怎么实现的?数据结构是什么?
    哈希表(hash table, 也叫散列表),是种根据关键码值(Key value)而直接进行访问数据结构,它可以提供快速的插入操作和查找操作。也就是说,它通过把关键字值映射到一个位置来访问记录,以加快查找的速度。这个映射函数称为哈希函数。
    Hashtable是通过"拉链法"实现的哈希表。由一个数组实现,数组元素都是单向链表。

    HashMap(重点)

    Q:HashMap有哪些遍历方式?
    Map.Entry,EntrySet,Iterator(迭代器)
    Q:HashMap和Hashtable的区别有哪些?
    HashMap没有考虑同步,是线程不安全的;Hashtable使用了synchronized关键字,是线程安全的;
    前者允许null作为Key;后者不允许null作为Key
    HashTable继承了Dictionary类。而HashMap是基于AbstractMap
    Q:HashMap的数据结构是什么?
    HashMap数据结构是一个长度为16的数组,数组元素是链表,在jdk1.8中,当链表长度达到8时,会转换为红黑树。
    注:红黑树是一种二叉查找树,每个节点都标记红色或黑色,根节点为黑色,规律是“有红必有黑,红红不相连”
    Q:HashMap如何保证key的唯一性?如何保证key不重复?
    HashMap的元素全部存储在Hashtable 中,每次添加元素都会先判断是否有重复的元素,hashcode()方法进行比较,若一样再通过equals()方法比较,他们的底层数据结构如果也相同的话,就认为数据已经存在了,就不会添加数据。
    简单点说,就是HashMap调用了对象的hashCode和equals方法进行的判断。
    Q:HashMap什么时候扩容?扩容多少?
    HashMap中有一个负载因子loadFactor,0.75。当数组的长度达到数组长度(16)*负载因子(0.75)也就是12时,会进行扩容。
    HashMap扩容时长度会翻倍。
    Q:HashMap扩容后,是怎么查找数据的?数据的位置会变吗?Hash算法需要变吗??
    扩容后需要重新计算数据的位置。
    Q:HashMap中的Hash算法具体是怎样的?
    Hash算法本质上就是三步:取key的hashCode值、高位运算 、取模运算。
    通过Hash算法,对key计算出数组下标,把数据放在对应下标元素的链表上。
    Hash碰撞:通过Key进行Hash的计算,就可以获取Key对应的HashCode。如果出现了重复的hashCode,就称作碰撞。
    如果发生了碰撞事件,那么意味这数组的一个位置要插入两个或者多个元素,这个时候数组上面挂的链表起作用了,链表会将数组某个节点上多出的元素按照尾插法(jdk1.7及以前为头差法)的方式添加。

    Q:HashMap 的长度为什么是2的幂次方?
    在Hash算法中,需要进行以下操作:

    1. 通过将 Key 的 hash 值与 length - 1 进行 & 运算,实现了当前 Key 的定位,2 的幂次方可以减少冲突(碰撞)的次数,提高 HashMap 查询效率
    2. 如果 length 为 2 的次幂 则 length-1 转化为二进制必定是 11111……的形式,在与 h 的二进制与操作效率会非常的快,而且空间不浪费;如果 length 不是 2 的次幂,比如 length 为 15,则 length - 1 为 14,对应的二进制为 1110,在于 h 与操作,最后一位都为 0 ,而 0001,0011,0101,1001,1011,0111,1101 这几个位置永远都不能存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!这样就会造成空间的浪费。

    ConcurrentHashMap(重点)

    Q:可以在遍历ArrayList或者HashMap时,一边增删集合吗?
    不可以。集合的fail-fast原则。
    在遍历ArrayList或者HashMap时,一边增删集合会抛出ModifyCountException。
    Q:HashMap和ConcurrentHashMap的区别是什么?
    HashMap是线程不安全的。ConcurrentHashMap线程安全。
    HashMap的Key和Value可以是null。而ConcurrentHashMap不可以。
    Q:ConcurrentHashMap是如何实现的?
    在jdk1.8之前,ConcurrentHashMap使用锁分段技术的。
    在jdk1.8,ConcurrentHashMap主要使用了CAS(compareAndSwap)、volatile(保证可见性)、synchronized锁。
    Q:ConcurrentHashMap是怎么保证线程安全的?
    CAS,比较和替换,运用了乐观锁的机制。
    Q: ArrayList是线程不安全的,如果要求线程安全,应该用什么集合代替ArrayList?
    CopyOnWriteArrayList。写时拷背。

    集合排序

    集合排序,偏向算法,问的人比较少。
    Q:Collections.sort()怎么排序?默认的排序是什么?
    必须实现Comparable接口的compare方法。
    默认的排序方法是Timsort。结合了合并排序和插入排序而得出的排序算法。
    Q:Arrays.sort();默认的排序算法是什么?
    数组有序就会采用归并排序,数组无序就会采用快速排序。
    详情见:https://blog.csdn.net/timheath/article/details/68930482

    参考资料:
    《码出高效 java开发手册》
    https://www.cnblogs.com/wmyskxz/p/9016611.html

  • 相关阅读:
    idea实现快捷批量修改替换
    接口自动化测试:利用环境变量管理测试环境的切换
    接口自动化测试:pytest自定义fixture传参request
    接口自动化测试:python连接mysql方法封装
    接口自动化测试:yaml文件中变量替换
    接口自动化测试:测试数据生成的一个小技巧
    接口自动化测试:抓包方式理解三次握手与四次挥手
    selenium相关:selenium grid的简单用法
    APP测试学习:弱网测试
    APP测试学习:耗电量测试
  • 原文地址:https://www.cnblogs.com/expiator/p/10193021.html
Copyright © 2020-2023  润新知