前言

2020金九银十马上完结,现为大家整顿了这次金九银十面试阿里的面试题总结,都是我从敌人那拿到的面试真题,话不多说,满满的干货分享给大家!

int a=10是原子操作吗?

是的。
 留神点:

  • i++(或++i)是非原子操作,i++是一个多步操作,而且是能够被中断的。i++能够被宰割成3步,第一步读取i的值,第二步计算i+1;第三部将最终值赋值给i。

 * int a = b;不是原子操作。从语法的级别来看,这是也是一条语句,是原子的;然而从理论执行的二进制指令来看,因为古代计算机CPU架构体系的限度,数据不能够间接从内存搬运到另外一块内存,必须借助寄存器中断,这条语句个别对应两条计算机指令,行将变量b的值搬运到某个寄存器(如eax)中,再从该寄存器搬运到变量a的内存地址:

mov eax, dword ptr [b]  mov dword ptr [a], eax 

既然是两条指令,那么多个线程在执行这两条指令时,某个线程可能会在第一条指令执行结束后被剥夺CPU工夫片,切换到另外一个线程而产生不确定的状况。

innodb反对全文索引吗?

5.6版本之后InnoDB存储引擎开始反对全文索引,5.7版本之后通过应用ngram插件开始反对中文。之前仅反对英文,因为是通过空格作为分词的分隔符,对于中文来说是不适合的。MySQL容许在char、varchar、text类型上建设全文索引。

innodb反对表锁吗?

反对,补充:一般的增删改 是表锁,退出索引的增删改是行锁,执行查问时不加任何锁的。

HTTP短连贯怎么变成长连贯。

在header中退出 --Connection:keep-alive。

调用yeild()会阻塞吗?

 阻塞指的是暂停一个线程的执行以期待某个条件产生(如某资源就绪)。
yield() 办法:yield() 使得线程放弃以后分得的 CPU 工夫,然而不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 工夫。调用 yield() 的成果等价于调度程序认为该线程已执行了足够的工夫从而转到另一个线程。yield()只是使以后线程从新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。sleep()可使优先级低的线程失去执行的机会,当然也能够让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。

虚拟机栈是线程共享的吗?

 不是。

 JVM初始运行的时候都会调配好 Method Area(办法区) 和Heap(堆) ,而JVM 每遇到一个线程,就为其调配一个 Program Counter Register(程序计数器) , VM Stack(虚拟机栈)和Native Method Stack (本地办法栈), 当线程终止时,三者(虚拟机栈,本地办法栈和程序计数器)所占用的内存空间也会被开释掉。这也是为什么我把内存区域分为线程共享和非线程共享的起因,非线程共享的那三个区域的生命周期与所属线程雷同,而线程共享的区域与JAVA程序运行的生命周期雷同,所以这也是零碎垃圾回收的场合只产生在线程共享的区域(实际上对大部分虚拟机来说只产生在Heap上)的起因。

栈区:
  • 每个线程蕴含一个栈区,栈中只保留根底数据类型的值(比方int i=1中1就是根底类型的对象)和对象的援用以及根底数据的援用
  • 每个栈中的数据(根底数据类型和对象援用)都是公有的,其余栈不能拜访。
  • 栈分为3个局部:根本类型变量区、执行环境上下文、操作指令区(寄存操作指令)。
堆区:
  • 存储的全副是对象,每个对象都蕴含一个与之对应的class的信息。(class的目标是失去操作指令)
  • jvm只有一个堆区(heap)被所有线程共享,堆中不寄存根本类型和对象援用,只寄存对象自身 。
办法区:
  • 又叫动态区,跟堆一样,被所有的线程共享。办法区蕴含所有的class和static变量。
  • 办法区中蕴含的都是在整个程序中永远惟一的元素,如class,static变量。(两者区别为堆区寄存new进去的对象信息,办法区寄存自身就具备的类信息)

常量寄存在JVM的那个区域?

办法区: 又叫动态区,跟堆一样,被所有的线程共享。它用于存储曾经被虚拟机加载的类信息、常量、动态变量、即时编译器编译后的代码等数据。

window.postMessage() 办法能够平安地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具备雷同的协定(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为雷同的值) 时,这两个脚本能力互相通信。window.postMessage() 办法提供了一种受控机制来躲避此限度,只有正确的应用,这种办法就很平安。

所有的对象都调配到堆中吗?

      答:不肯定。

CopyOnWriteArrayList是线程平安的吗?

 答:是的。
 CopyOnWriteArrayList应用了一种叫写时复制的办法,当有新元素增加到CopyOnWriteArrayList时,先从原有的数组中拷贝一份进去,而后在新的数组做写操作,写完之后,再将原来的数组援用指向到新数组。创立新数组,并往新数组中退出一个新元素,这个时候,array这个援用依然是指向原数组的。当元素在新数组增加胜利后,将array这个援用指向新数组。
      CopyOnWriteArrayList的整个add操作都是在锁的爱护下进行的。这样做是为了防止在多线程并发add的时候,复制出多个正本进去,把数据搞乱了,导致最终的数组数据不是咱们冀望的。

    public boolean add(E e) {        //1、先加锁        final ReentrantLock lock = this.lock;        lock.lock();        try {            Object[] elements = getArray();            int len = elements.length;            //2、拷贝数组            Object[] newElements = Arrays.copyOf(elements, len + 1);            //3、将元素退出到新数组中            newElements[len] = e;            //4、将array援用指向到新数组            setArray(newElements);            return true;        } finally {            //5、解锁            lock.unlock();        }    }

因为所有的写操作都是在新数组进行的,这个时候如果有线程并发的写,则通过锁来管制,如果有线程并发的读,则分几种状况:

  • 如果写操作未实现,那么间接读取原数组的数据;
  • 如果写操作实现,然而援用还未指向新数组,那么也是读取原数组数据;
  • 如果写操作实现,并且援用曾经指向了新的数组,那么间接从新数组中读取数据。

可见,CopyOnWriteArrayList的读操作是能够不必加锁的。
CopyOnWriteArrayList 有几个毛病:
因为写操作的时候,须要拷贝数组,会耗费内存,
如果原数组的内容比拟多的状况下,可能导致young gc或者full gc
不能用于实时读的场景,像拷贝数组、新增元素都须要工夫,
所以调用一个set操作后,读取到数据可能还是旧的,
尽管CopyOnWriteArrayList 能做到最终一致性,然而还是没法满足实时性要求;
CopyOnWriteArrayList 适合读多写少的场景,不过这类慎用
因为谁也没法保障CopyOnWriteArrayList 到底要搁置多少数据,
万一数据略微有点多,每次add/set都要从新复制数组,这个代价切实太昂扬了。
在高性能的互联网利用中,这种操作分分钟引起故障。
CopyOnWriteArrayList走漏的思维

  • 读写拆散,读和写离开
  • 最终一致性
  • 应用另外开拓空间的思路,来解决并发抵触

数组越界问题

一般来讲咱们应用时,会用一个线程向容器中增加元素,一个线程来读取元素,而读取的操作往往更加频繁。写操作加锁保障了线程平安,读写拆散保障了读操作的效率,几乎完满。
如果这时候有第三个线程进行删除元素操作,读线程去读取容器中最初一个元素,读之前的时候容器大小为i,当去读的时候删除线程忽然删除了一个元素,这个时候容器大小变为了i-1,读线程依然去读取第i个元素,这时候就会产生数组越界。
测试一下,首先向CopyOnWriteArrayList外面塞10000个测试数据,启动两个线程,一个一直的删除元素,一个一直的读取容器中最初一个数据。

    public void test(){        for(int i = 0; i<10000; i++){            list.add("string" + i);        }        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    if (list.size() > 0) {                        String content = list.get(list.size() - 1);                    }else {                        break;                    }                }            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    if(list.size() <= 0){                        break;                    }                    list.remove(0);                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }

Java接口能够多继承吗?

 java类是单继承的。classB extends classA
java接口能够多继承。Interface3 extends Interface0, Interface1, interface……
不容许类多重继承的次要起因是,如果A同时继承B和C,而B和C同时有一个D办法,A如何决定该继承那一个呢?
 但接口不存在这样的问题,接口全都是形象办法继承谁都无所谓,所以接口能够继承多个接口。

(byte)300==(byte)100+(short)200?

答:false。
java中byte的取值范畴是-128~127,产生上溢下溢时要模256;130>127上溢,故模256得130,仍溢出,再减256得-126,所以s=-126。300>127上溢,故模256得44,44在byte取值范畴内,故s=44.
300 的 二进制是:100101100;byte强制转换后从右往左取8位为:00101100;因为第八位为0所以为负数,又晓得负数的原反补码都雷同;所以00101100转换为十进制是:44(32+8+4)
 (byte)100+(short)200,byte和short的后果会主动转为short不会溢出。所以(byte)100+(short)200=(short)300,而(byte)300的后果是44.即两者不相等。

操作系统具备过程治理,存储管理,文件治理和设施治理的性能,下列无关形容中,哪一项是不正确的? (A)

A.过程治理次要是对程序进行治理
B.存储管理次要治理内存资源
C.文件治理能够无效的反对对文件的操作,解决文件共享、窃密和爱护问题
D. 设施治理是指计算机系统中除了CPU和内存以外的所有输入输出设施的治理

this和super正确的是(C):

A、都能够用在main()办法中         B、都是指一个内存地址 
C、不能用在main()办法中            D、意义雷同
public static void main(String[] args),main办法是静态方法,不能够应用对象特有的this或super关键字。

援用计数法是JVM GC算法吗?

答:是。

能在try{}catch(){}finally{}构造的finally{}中再次抛出异样吗?

 答:能。
Exception in thread “main” java.lang.Exception: 异样4
at com.test.FinallyTry.f(FinallyTry.java:16)
at com.test.FinallyTry.main(FinallyTry.java:5)

--------在finally中抛异样或者return 会覆盖之前的异样

HTTP2新个性?

答:缩小头部的体积、增加申请优先级、服务器推送、多路复用。

索引能够将随机IO变成程序IO吗?

 答:对。
随机IO:假如咱们所须要的数据是随机扩散在磁盘的不同页的不同扇区中的,那么找到相应的数据须要等到磁臂(寻址作用)旋转到指定的页,而后盘片寻找到对应的扇区,能力找到咱们所须要的一块数据,顺次进行此过程直到找完所有数据,这个就是随机IO,读取数据速度较慢。
程序IO:假如咱们曾经找到了第一块数据,并且其余所需的数据就在这一块数据后边,那么就不须要从新寻址,能够顺次拿到咱们所需的数据,这个就叫程序IO。

transient润饰的变量是长期变量吗?

答:对。

  • 一旦变量被transient润饰,变量将不再是对象长久化的一部分,该变量内容在序列化后无奈取得拜访。
  • transient关键字只能润饰变量,而不能润饰办法和类。留神,本地变量是不能被transient关键字润饰的。变量如果是用户自定义类变量,则该类须要实现SERIALIZABLE接口。
  • 被transient关键字润饰的变量不再能被序列化,一个动态变量不论是否被transient润饰,均不能被序列化。

      留神点:在Java中,对象的序列化能够通过实现两种接口来实现,若实现的是SERIALIZABLE接口,则所有的序列化将会主动进行,若实现的是Externalizable接口,则没有任何货色能够主动序列化,须要在writeExternal办法中进行手工指定所要序列化的变量,这与是否被transient润饰无关。

高、中、低三级调度。

 高级调度:即作业调度,依照肯定策略将抉择磁盘上的程序装入内存,并建设过程。(存在与多道批处理零碎中)
  中级调度:即替换调度,依照肯定策略在内外存之间进行数据交换。
低级调度:即CPU调度(过程调度),依照肯定策略抉择就绪过程,占用cpu执行。
 其中低度调度是必须的。

上面那个查看80端口是否被占用?

  • 形式一:ps -ef |grep 80
  •  形式二:netstat -anp |grep :80
  •  形式三:lsof -i:80
  •  形式四:netstat -tunlp |grep :80
  •  形式五:netstat -an |grep :80

C++弱援用指针是那个?

 weak_ptr也是一个援用计数型智能指针,然而它不减少对象的援用计数,即弱援用。与之绝对,shared_ptr是强援用,只有有一个指向对象的shared_ptr存在,该对象就不会析构,直到指向对象的最初一个shared_ptr析构或reset()时才会被销毁。
利用weak_ptr,咱们能够解决常见的空悬指针问题以及循环援用问题。

上面不属于类的构造方法具备的特点是( )。

  • A.没有返回值
  • B.用户能够通过new主动调用。
  • C.构造方法名必须和类名雷同
  • D.用户能够间接调用
  • D [解析] 构造方法是类中的一种非凡办法,是为对象初始化操作编写的办法,用它来定义对象的初始状态。在Java语言中的每个类都有构造方法,它也是由办法名、参数和办法体组成。构造方法名必须与类名雷同,它没有返回值,用户不能间接调用它,只能通过new主动调用。

spx协定工作在哪一层?

 SPX(Sequenced Packet Exchange protocol,程序包交换)协定是Novell开发的用在NetWare中的协定,用来确保信息胜利传送。SPX应用NetWare的IPX协定作为它的传递机制并在网络结点间提供客户服务器和层对层的交互通信。它工作在传输层。

TCP第四次挥手后为什么要期待2MSL后才断开链接?等待时间为什么是2MSL?

  •   答:1.为了保障客户端最初一次挥手的报文可能达到服务器,若第4次挥手的报文段失落了,服务器就会超时重传第3次挥手的报文段,所以客户端此时不是间接进入CLOSED,而是放弃TIME_WAIT(期待2MSL就是TIME_WAIT)。当客户端再次收到服务器因为超时重传而发送的第3次挥手的申请时,客户端就会从新给服务器发送第4次挥手的报文(保障服务器可能收到客户端的回应报文)。最初,客户端、服务器才真正断开连接。说白了,期待2MSL就是为了确保服务器可能受到客户端最初的回应。

  * 2.如果客户端间接CLOSED,而后又再次向服务器发动一个新连贯,谁也不能保障新发动的连贯和刚敞开的连贯的端口号是不同的,有可能新、老连贯的端口号就是一样的。假如新、老连贯端口号统一,若老连贯的一些数据仍滞留在网络中,这些滞留数据在新连贯建设后才达到服务器,鉴于前后端口号统一,TCP协定就默认这些数据属于新连贯,于是数据就这样乱成一锅粥了。所以TCP连贯还要在TIME_WAIT状态下期待2MSL,确保所有老连贯的数据都在网络中隐没!

  • 3.首先阐明什么是MSL,MSL是Maximum Segment Lifetime的缩写,译为报文最大生存工夫,也就是任何报文在网络上存活的最大工夫,一旦超过该工夫,报文就会被抛弃。2MSL也就是指的2倍MSL的工夫。

为什么是2倍呢?

  • 被动断开的一侧为A,被动断开的一侧为B。
  • 第一个音讯:A发FIN
  • 第二个音讯:B回复ACK
  •  第三个音讯:B收回FIN此时此刻:B单方面认为本人与A达成了共识,即单方都批准敞开连贯。此时,B能开释这个TCP连贯占用的内存资源吗?不能,B肯定要确保A收到本人的ACK、FIN。所以B须要静静地期待A的第四个音讯的到来:
  • 第四个音讯:A收回ACK,用于确认收到B的FIN

当B接管到此音讯,即认为单方达成了同步:单方都晓得连贯能够开释了,此时B能够平安地开释此TCP连贯所占用的内存资源、端口号。所以被动敞开的B无需任何wait time,间接开释资源。但,A并不知道B是否接到本人的ACK,A是这么想的:
      1)如果B没有收到本人的ACK,会超时重传FiN那么A再次接到重传的FIN,会再次发送ACK
      2)如果B收到本人的ACK,也不会再发任何音讯,包含ACK
无论是1还是2,A都须要期待,要取这两种状况等待时间的最大值,以应答最坏的状况产生,这个最坏状况是:
      去向ACK音讯最大存活工夫(MSL) + 来向FIN音讯的最大存活工夫(MSL)。这恰好就是2MSL( Maximum Segment Life)。期待2MSL工夫,A就能够释怀地开释TCP占用的资源、端口号,此时能够应用该端口号连贯任何服务器。同时也能保障网络中老的链接全副隐没。

过程有那些状态,并简略形容一下?

  • 过程其根本状态有5种,即创立状态、就绪状态、运行状态、阻塞状态、终止状态。
  •   创立状态:过程在创立时须要申请一个空白PCB,向其中填写管制和治理过程的信息,实现资源分配。
  •  就绪状态:过程曾经筹备好,已调配到所需资源,只有调配到CPU就可能立刻运行。
  •   执行状态:过程处于就绪状态被调度后,过程进入执行状态。
  •    阻塞状态:正在执行的过程因为某些事件而临时无奈运行,过程受到阻塞。
  •  终止状态:过程完结,或呈现谬误,或被零碎终止,进入终止状态,无奈再执行。
  •  过程是指计算机中的程序对于某数据汇合上的一次运行流动,是零碎进行资源分配和调度的根本单位。
  • 过程状态是指一个过程的生命周期能够划分为一组状态,这些状态刻画了整个过程,过程状态即体现一个过程的生命状态。

创立NIO客户端代码。

package com.cn.niochat;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Scanner;/** * 用Java实现nio的客户端 */public class NioClient {    public void start() throws IOException {        /**         * 链接服务器端         */        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8000));        //向服务器端发送数据        //从命令行获取数据,获取键盘的输出        Scanner scanner = new Scanner(System.in);        while (scanner.hasNextLine()){            //获取这一行数据           String request =  scanner.nextLine();           //如果有数据,则发送,且数据不为空           if(request != null && request.length() > 0){               socketChannel.write(Charset.forName("UTF-8").encode(request));           }        }    }    public static void main(String[] args) throws IOException {        NioClient nioClient = new NioClient();        nioClient.start();    }}

获取一个类的class实例的办法有那些?

  • (1).调用运行时类自身的.class属性

    Class clazz = String.class;

  • (2),通过运行时类的对象获取

    public final Class<?> getClass()是非静态方法.
    Person p = new Person();
    Class clazz = p.getClass();

  • (3)通过Class的静态方法获取:体现反射的动态性

    String className = “java.util.commons”;
    Class clazz = Class.forName(className);

  • (4)通过类的加载器

    String className = “java.util.commons”;
    ClassLoader classLoader = this.getClass().getClassLoader();
    Class claz = classLoader.loadClass(className);

a、b、c、d、e、f字符呈现的次数别离为16、5、12、17、10、25。编码的起码字节是多少?

(25+16+17)×2+12×3+(5+10)×4=212。

MySQL中取得后果集的记录并在此记录上做非凡的操作的最佳对象是?

游标。

System.out.println(1+1+“1”)输入21。System.out.println(“1”+1+1);输入111。

Java的+表达式计算是从左往右的。若是两个整形,会求值,若其中之一是String,会拼接,且后果为String。1+1+“1”,先计算1+1,因为两个都是整形,求值=2,而后2+“1”,拼接,所以是
21,而“1”+1+1,先计算“1”+1,因为有String,后果为’11",再“11”+1就是“111”。

成员变量,静态方法看右边;非静态方法:编译看右边,运行看左边。

意思是:当父类变量援用子类对象时(Fu f = new Zi();
),在这个援用变量f指向的对象中,他的成员变量和静态方法与父类是统一的,他的非静态方法,在编译时是与父类统一的,运行时却与子类统一(产生了复写)。

class Fu {    intnum = 5;    static void method4() {         System.out.println("fu method_4");    }    void method3() {         System.out.println("fu method_3");    }}class Zi extends Fu {    intnum = 8;    static void method4() {//留神点:静态方法不能重写         System.out.println("zi method_4");     }    void method3() {         System.out.println("zi method_3");    }}class DuoTaiDemo4 {     public static void main(String[] args) {         Fu f = new Zi();         System.out.println(f.num);//与父类统一         f.method4();//与父类统一         f.method3();//编译时与父类统一,运行时与子类统一         Zi z = new Zi();         System.out.println(z.num);         z.method4();         z.method3();     }}

1结尾的http状态码

  • 示意长期响应并须要请求者继续执行操作的状态代码。
  • 100 (持续) 请求者该当持续提出申请。 服务器返回此代码示意已收到申请的第一局部,正在期待其余部分。
  • 101 (切换协定) 请求者已要求服务器切换协定,服务器已确认并筹备切换。

2结尾的http状态码

  • 示意申请胜利
  • 200 胜利解决了申请,个别状况下都是返回此状态码;
  • 201 申请胜利并且服务器创立了新的资源。
  • 202 承受申请但没创立资源;
  • 203 返回另一资源的申请;
  • 204 服务器胜利解决了申请,但没有返回任何内容;
  • 205 服务器胜利解决了申请,但没有返回任何内容;
  • 206 解决局部申请;

3xx (重定向)

  • 重定向代码,也是常见的代码
  • 300 (多种抉择) 针对申请,服务器可执行多种操作。 服务器可依据请求者 (user agent) 抉择一项操作,或提供操作列表供请求者抉择。
  • 301 (永恒挪动) 申请的网页已永恒挪动到新地位。 服务器返回此响应(对 GET 或 HEAD 申请的响应)时,会主动将请求者转到新地位。
  • 302 (长期挪动) 服务器目前从不同地位的网页响应申请,但请求者应持续应用原有地位来进行当前的申请。
  • 303 (查看其余地位) 请求者该当对不同的地位应用独自的 GET 申请来检索响应时,服务器返回此代码。
  • 304 (未修改) 自从上次申请后,申请的网页未修改过。 服务器返回此响应时,不会返回网页内容。
  • 305 (应用代理) 请求者只能应用代理拜访申请的网页。 如果服务器返回此响应,还示意请求者应应用代理。
  • 307 (长期重定向) 服务器目前从不同地位的网页响应申请,但请求者应持续应用原有地位来进行当前的申请。

4结尾的http状态码示意申请出错

  • 400 服务器不了解申请的语法。
  • 401 申请要求身份验证。 对于须要登录的网页,服务器可能返回此响应。
  • 403 服务器拒绝请求。
  • 404 服务器找不到申请的网页。
  • 405 禁用申请中指定的办法。
  • 406 无奈应用申请的内容个性响应申请的网页。
  • 407 此状态代码与 401相似,但指定请求者该当受权应用代理。
  • 408 服务器等待申请时产生超时。
  • 409 服务器在实现申请时发生冲突。 服务器必须在响应中蕴含无关抵触的信息。
  • 410 如果申请的资源已永恒删除,服务器就会返回此响应。
  • 411 服务器不承受不含无效内容长度标头字段的申请。
  • 412 服务器未满足请求者在申请中设置的其中一个前提条件。
  • 413 服务器无奈解决申请,因为申请实体过大,超出服务器的解决能力。
  • 414 申请的 URI(通常为网址)过长,服务器无奈解决。
  • 415 申请的格局不受申请页面的反对。
  • 416 如果页面无奈提供申请的范畴,则服务器会返回此状态代码。
  • 417 服务器未满足”冀望”申请标头字段的要求。

5结尾状态码并不常见,然而咱们应该晓得

  • 500 (服务器外部谬误) 服务器遇到谬误,无奈实现申请。
  • 501 (尚未施行) 服务器不具备实现申请的性能。 例如,服务器无奈辨认申请办法时可能会返回此代码。
  • 502 (谬误网关) 服务器作为网关或代理,从上游服务器收到有效响应。
  • 503 (服务不可用) 服务器目前无奈应用(因为超载或停机保护)。 通常,这只是临时状态。
  • 504 (网关超时) 服务器作为网关或代理,然而没有及时从上游服务器收到申请。
  • 505 (HTTP 版本不受反对) 服务器不反对申请中所用的 HTTP 协定版本。
  • 记忆口诀:1临(长期响应)2成(申请胜利)3定向(重定向)4请(申请出错)5服(服务器谬误)

最初

欢送关注公众号:前程有光,支付一线大厂Java面试题总结+各知识点学习思维导+一份300页pdf文档的Java外围知识点总结! 这些材料的内容都是面试时面试官必问的知识点,篇章包含了很多知识点,其中包含了有基础知识、Java汇合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。