金九银十面完阿里,百度,腾讯,360之后我总结了这些面试知识点

线程并发

这就是一天坑,基本问不完,难度也是拉满的那种...

Q:进程和线程的区别?

  1. 进程是资源分配的基本单位,线程是程序执行的最小单位
  2. 进程有独立的地址空间,线程依托于进程存在,线程切换的开销小
  3. 多进程组成的服务更稳定,一个进程挂了不会对另一个进程造成影响,相反,一个线程挂了,依托该进程的所有线程都会崩溃

Q:进程间通信方式?

  • 管道
  • 信号量
  • 消息队列
  • 共享内存(IPC)
  • socket

核心目的是交换数据

Q:线程间通信方式?

  • 锁机制
  • 信号量

核心目的是同步

Q:Callable、Runnable区别?

  1. 核心区别 Callable 有返回值,Runnable 没有返回值
  2. Callable的方法是call(),而 Runnable的方法是run()
  3. Callable可以抛出异常,而 Runnable不可以抛出异常

Q:Future和Callable的关系?

  • Callable执行完后会有一个返回结果,可以通过Future类返回(异步计算的结果)。
  • 此外,应当了解下FutureTask,其实现了Runnable和Future,并存在接收Callable的构造函数

Q:创建线程的方法?

  1. 继承Thread,再通过Thread的start()
  2. 实现Runnable,再通过new Thread(runnable)包装后,start()
  3. 用ExecutorService提交

Q:volatile关键字的作用?

  1. 防止指令重排(单例模式中)
  2. 内存可见性

Q:synchronized的用法?

  1. 修饰实例方法,作用于当前对象,两个不同对象不冲突
  2. 修饰静态方法,作用于当前类,两个不同对象也冲突
  3. 修饰代码块,对指定对象加锁

Q:讲一下Java内存模型?

网上一大堆,引用前人的清明上河图

 

Q:CountDownLatch和CyclicBarrier了解吗?

  • CountDownLatch中一个线程等待其他几个线程完成。
  • CyclicBarrier中几个线程相互等待某一事件的达成。
  • CyclicBarrier可以复用。

Q:Semaphore用法?

控制一组资源的使用,通过acquire()和release()获取和释放这组锁。

Q:ThreadLocal作用?

修饰变量,控制变量作用域,使变量在同一个线程内的若干个函数中共享。

Q:单例与多例的区别?

  1. 单例非static和static变量都是线程不安全的
  2. 多例非static变量是线程安全的,但static变量依旧是线程不安全的
  3. 可以通过synchronized或ThreadLocal来完成static变量的线程安全

Q:锁释放的时机?

  1. 执行完同步代码块后
  2. 执行同步代码块途中,发生了异常,导致线程终止
  3. 执行同步代码块途中,遇到wait关键字,该线程释放对象锁,当前线程会进入线程等待池中,等待被唤醒

Q:notify唤醒时机?

notify后不会立刻唤醒处于线程等待池中的线程,而是等当前同步代码块执行完,才释放当前的对象锁,并唤醒等待线程。

Q:notify和notifyAll区别?

notify通知一个线程获取锁,而notifyAll通知所有相关的线程去竞争锁

Q:讲一下Lock?

Lock是为了弥补synchronized的缺陷而诞生的,主要解决两种场景

  1. 读写操作,读读不应该互斥
  2. 避免永久的等待某个锁

Lock是一个类,并非Java本身带的关键字,相对于synchronized而言,需要手动释放锁。

Q:锁的种类?

  1. 可重入锁,如ReentrantLock
  2. 可中断锁,lockInterruptibly()反应了Lock的可中断性
  3. 公平锁,synchronized是非公平锁,Lock默认也是非公平锁(可调整)
  4. 读写锁,如ReadWriteLock

集合

集合相对容易,常规送分题,基本都会问到HashMap

Q:TreeSet特性?

内部元素通过compare排序。

Q:LinkedHashMap特性?

内部有个双向链表维护了插入key的顺序,使得map能够依据插入key的顺序迭代。

Q:ArrayList与Vector的差别?

ArrayList是非线程安全的,Vector是线程安全的。

Q:LinkedList与ArrayList的差别?

  1. LinkedList基于链表,ArrayList基于数组
  2. LinkedList没有随机访问的特性
  3. ArrayList删除添加元素没有LinkedList高效

Q:HashMap与HashTable的差别?

  1. HashTable线程安全,HashMap线程不安全
  2. HashMap允许null key和value,而HashTable不允许

Q:Set与List的差别?各自有哪些子类?

Set不允许重复元素,List允许重复元素,List有索引

  • Set:HashSet、LinkedHashMap、TreeSet
  • List:Vector、ArrayList、LinkedList

Q:hashCode()、equals()、==区别?

  1. equals 比较两个对象是否相等,若相等则其hashCode必然相等
  2. 若两个对象的hashCode不等,则必然不equals
  3. ==比较内存地址,比较是否是同一对象

Q:Java容器中添加的对象是引用还是值?

引用

Q:Iterator和ListIterator的区别?

  1. ListIterator 能向前遍历,也能向后遍历
  2. 可以添加元素
  3. 可以定位当前index

Q:HashMap实现?

内容巨多,引用大佬面经,值得一看,目录供大家参考

  • hashing的概念
  • HashMap中解决碰撞的方法(拉链法)
  • equals()和hashCode()的应用,在HashMap中到底如何判断一个对象有无
  • 不可变对象的好处
  • HashMap多线程的条件竞争
  • 重新调整HashMap的大小

PS:HashSet是通过HashMap实现的

Q:ConcurrentHashMap和HashTable区别?

  1. HashTable通过synchronized来实现线程安全
  2. ConcurrentHashMap通过分段锁,仅锁定map的某一部分

GC

这块主要介绍JVM内存的划分以及GC算法

Q:什么是内存泄漏和内存溢出?

  • 内存泄漏:无法释放已申请的内存空间,一次内存泄露危害可以忽略,但堆积后果很严重,无论多少内存,迟早会被漏光。
  • 内存溢出:没有足够的内存空间供其使用。

内存泄漏最后会导致没有足够的空间分配对象,从而导致内存溢出,当然也可能开始分配过大的对象导致内存溢出

Q:导致内存溢出的因素?

  1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
  2. 集合类中有对象的引用,使用完后未清空,使得JVM不能回收。
  3. 代码中存在死循环或循环产生过多重复的对象实体。
  4. 启动参数内存值设定的过小。

Q:JVM内存划分?

  • 堆:对象
  • 方法区:类、静态变量和常量
  • 栈:局部变量表

基本说出上面三条就可以了,更详细的见下图

 

Q:简单说一下垃圾回收?

这可不简单...

垃圾定义:

  • 引用计数法:循环引用会bug
  • 可达性算法:GC Roots,如 栈中的引用对象、方法区静态、常量对象、本地方法区内的对象,不在堆中就可以

堆中内存分布:

  • 新生代(33%):小对象,Eden:From Survivor:To Survivor=8:1:1
  • 老年代(66%):大对象、长期存活的对象
  • 永生代(三界之外):通常利用永生代来实现方法区

垃圾回收算法:

  • 标记清除算法
  • 复制清除(新生代)
  • 标记整理清除(老年代)

Q:Minor GC、Major GC和 Full GC的区别?

  • Minor GC是对新生代做垃圾回收
  • Major GC是对老年代做垃圾回收
  • Full GC是对整个堆做垃圾回收

Q:Full GC触发时机?

  1. System.gc(),并非一定触发,只是建议
  2. 老年代空间不足(核心触发点,其他方案都是从这里衍生出来)
  3. 永生代空间不足(当将方法区放在永生代中时)
  4. Minor GC后晋升到老年代中的大小>老年代剩余空间(其实就是2.老年代空间不足的一种表现)
  5. 堆中分配大对象(大对象可以直接进入老年代,导致老年代空间不足)

Q:什么是常量池?

常量池分为静态常量池和运行时常量池。

  • 静态常量池:指的是在*.class文件中的常量池
  • 运行常量池:指的是将*.class文件中的常量装载到内存中方法区的位置(当方法区放在永生代时,也可以理解为内存中的永生代)

包含的信息:

  • 字符串字面量
  • 类、方法信息

该问题一般会引出字符串常量比较

    String s1 = "Hello";
    String s2 = "Hello";
    String s3 = "Hel" + "lo";
    String s4 = "Hel";
    String s5 = "lo";
    String s6 = s4 + s5;
    String s7 = "Hel" + new String("lo");
    String s8 = new String("Hello");
    String s9 = s8.intern();

    System.out.println(s1 == s2);  // true,直接取自常量池
    System.out.println(s1 == s3);  // true,在编译时会优化成常量池内字符串的拼接,区别 s6
    System.out.println(s1 == s6);  // false,本质上是变量拼接,区别 s3
    System.out.println(s1 == s7);  // false,含有对象 new String("lo")
    System.out.println(s1 == s8);  // false,对象与字符串常量比较
    System.out.println(s1 == s9);  // true,字面量比较
复制代码

类加载

面试时有人问到过,回去大概查了下

Q:讲一下类加载过程?

  1. 加载:将*.class文件通过各种类加载器装载到内存中

  2. 链接:分为三步

    1. 验证:保证加载进来的字节流符合JVM的规范,我理解成语法上的验证(可能不严谨)
    2. 准备:为类变量(非实例变量)分配内存,赋予初值(该初值是JVM自已约定的初值,非用户自定义初值,除非是常量,用final static修饰的)
    3. 解析:将符号引用替换成直接引用(A.a()=> 某一内存地址)
  3. 初始化:对类变量初始化,执行类变量的构造器

Q:Java初始化顺序?

这是在爱奇艺碰到的一面试道题,当时差点两眼一抹黑过去了...头一次发现这么多东西要初始化

  1. 一个类中初始化顺序(先类后实例)

类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

  1. 继承关系的两个类中初始化顺序(先类后实例,再先父后子)

父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

Q:Java类加载器的种类?

  1. 启动Boostrap类加载器:加载路径<JAVA_HOME>/lib
  2. 扩展Extension类加载器:加载路径<JAVA_HOME>/lib/ext
  3. 系统System类加载器:加载路径 -classpath

Q:双亲委派模式了解吗?

我理解的深度比较浅,个人理解,委派就是加载类时先看上层加载过没,如果加载过了,当前就不加载了,直接使用当成加载器加载的类。

其次是加载顺序,System->Extension->Boostrap

优点:

  • 避免重复加载类
  • 核心API不会被改动

面向对象

这些问题很弱鸡,但考的也比较多

Q:面向对象的三大特性?

顺口溜一般的背出来:封装、继承、多态

然后会让你讲讲这三个特性如何体现,大家自己想想吧,言之有理即可

Q:Java中接口和抽象类区别?

  1. 可以实现多个接口(implement),但只能继承一个抽象类(extend)
  2. 接口中的方法不能实现,抽象类中可以实现部分方法
  3. 接口中数据全是public static final类型的,方法全是public abstract的
  4. 本质上,接口是说对象能干什么,抽象类是说对象是什么

Q:重载和重写?

猪脑子,老记混

  • 重载:同一个类中,函数名一样,但接受的参数一定不同,返回的结果可以不同
  • 重写:不同类中,函数名一样,参数一样,结果也一样

设计模式

Q:例举一下你了解的设计模式?

一般说5、6个,有个样例就行了

  • 组合模式:集合的addAll
  • 装饰者模式:stream的各种嵌套
  • 抽象工厂:JDBC中driver创建新连接
  • 建造者模式:StringBuilder或SQL中PreparedStatement
  • 责任链:structs2中对请求的处理各种Filter
  • 解释器:正则表达式
  • 观察者:swing中的事件监听各种Listener

Q:手撸单例?

撸完,让你讲讲内部细节,volatile或多例问题

    public class Singleton {
        private volatile static Singleton singleton;
        private Singleton(){}
        public static Singleton getSingleton(){
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
复制代码

网络协议

Q:TCP3次握手4次挥手?

基本画张图就K.O.了,内部的问题也建议看一下

Q:TCP为什么是一定要是3次握手,而不是2次或3次以上?

2次挥手的问题

在第1次建立过程中,client请求链接在网络中滞留过久,导致client发送第2次请求,建立完毕后,这时第1次的请求到达server,server接收又维护一链接,但该链接实际上已经作废,浪费了server端的资源。

3次以上的方案

理论上,做到3次以上是可行的,但真正想做到一个完美可靠的通信是不可能的,因为每次答复都是对上次请求的响应,但该次答复在不可靠的信道中仍是会丢失的,考虑到现实效率问题,3次足以。

Q:TCP为什么是4次挥手,而不是3次呢?

  • 握手的第二次携带了,响应ACK和请求SYN信息
  • 挥手过程中不能一次性携带这两种信息,因为server方可能还有数据没传输完。

Q:TCP半连接池与全连接池?

  • 半连接池:接受client握手第一步请求时,将该次链接放到半连接池中,Synflood的主要攻击对象
  • 全连接池:接受client握手第二步请求时,将该次链接从半连接池中取出放到全连接池中。

Q:TCP和UDP的区别?

  1. TCP基于连接,而UDP基于无连接
  2. TCP由于有握手和挥手的过程消费资源相对较多
  3. TCP是传输数据流,而UDP是数据报
  4. TCP保证数据正确性和顺序性,而UDP可能丢包,不保证有序

Q:TCP和UDP的应用?

  • TCP:FTP、HTTP、POP、IMAP、SMTP、TELNET、SSH
  • UDP:视频流、网络语音电话

Q:TCP/IP与OSI模型?

TCP/IP模型,自下而上

  1. 链路层
  2. 网络层(IP、ICMP、IGMP)
  3. 运输层(TCP、UDP)
  4. 应用层(Telnet、FTP)

OSI模型,自下而上

  1. 物理层
  2. 数据链路层
  3. 网络层
  4. 运输层
  5. 会话层
  6. 表示层
  7. 应用层

Q:ping命令基于哪种协议?

ICMP

Q:阻塞式和非阻塞式IO区别?

阻塞式

  • 每来一个连接都会开启一个线程来处理,10个线程对应10个请求
  • 线程大多时候都在等在数据的到来,浪费资源
  • 适合并发量小,数据量大的应用

非阻塞式

  • 基本思想,将所有连接放在一张table中,然后轮询处理
  • 实现上可以用事件通知机制,可以用10个线程处理100个请求
  • 适合并发量大,数据量小的应用

数据库

用数据库做过开发,但是了解的不深入,面试问我会不会写SQL时,我多答“简单的可以,复杂的尝试一下”...SQL复杂起来真不是人写的...

Q:聚集索引和非聚集索引区别?

  • 聚集索引:叶子节点是实际数据,表中只能有一个聚集索引
  • 非聚集索引:叶子节点是地址,需要再跳转一次,表中可以有多个非聚集索引

Q:where、group by、having执行顺序?

  1. where 过滤行数据
  2. group by 分组
  3. having 过滤分组

Q:星型、雪花结构?

  • 星型:存在部分冗余
  • 雪花:表切分的十分细,没有冗余

Q:SQL纵向转横向,横向转纵列?

基本上,除了 group by + 聚集函数 外,这是最难的 SQL 题了

  • 纵向转横向

sum(case when A='a' then B else 0 end) as D

这里需要用sum或其他聚集函数,因为作用在一个group中

  • 横向转纵向

核心用union

记住这两条做到举一反三就可以了

Q:脏读、不可重复读、幻读?

  • 脏读:事务A读取了事务B提交的值
  • 不可重复读:事务A两次读取了事务B的值,事务B在该过程中修改并提交过,导致A两次读取值不一致
  • 幻读:事务A修改 a 到 b ,事务B在该过程中添加了新的a,导致新添加的a,没有修改成b

这引出事务隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

Q:join如何实现的?

等我有空来填坑...

需要面试方面的资料的朋友可以加一下交流分享群:838498680

猜你喜欢

转载自blog.csdn.net/qq_41534566/article/details/82707862