zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    PAT B1027 打印沙漏 (20 分)
    PAT B1025 反转链表 (25 分)
    PAT B1022 D进制的A+B (20 分)
    PAT B1018 锤子剪刀布 (20 分)
    PAT B1017 A除以B (20 分)
    PAT B1015 德才论 (25 分)
    PAT B1013 数素数 (20 分)
    PAT B1010 一元多项式求导 (25 分)
    HDU 1405 The Last Practice
    HDU 1165 Eddy's research II
  • 原文地址:https://www.cnblogs.com/expiator/p/10193021.html
Copyright © 2011-2022 走看看