目录
基础知识:
Java集合相关:
Java面试:
1. java中的基本数据类型有哪些?
答:byte, short, int, long, float, double, char, boolean. 剩下的都是引用类型(reference type)
2. String类可以被继承吗?
答:不可以. 因为String类是final类.
3. String和StringBuilder,StringBuffer的区别?
答:String是只读字符串,String引用的字符串内容是不能被改变的.而StringBuffer和StringBuilder是可变字符串.StringBuilder和StringBuffer的用法相同, 区别是StringBuffer被synchronized修饰,是线程安全的,但效率比StringBuilder低。
4.构造器是否可以被重写?
答: 构造器不能被继承,因此不能被重写,但是可以被重载.
5.抽象类和接口的相同点和不同点.
答: 1)抽象类和接口都不能实例化对象,但是可以定义抽象类和接口类型的引用.
2)继承抽象类和实现接口都要对其中的抽象方法全部实现
3)接口比抽象类更加抽象,抽象类中可以定义构造器,可以有抽象方法和具体方法.
4)接口中方法全部都是抽象方法.
5)抽象类中的成员可以是private,protected,public,接口全部都是public
6)抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量.
7)有抽象方法的类必须声明为抽象类,而抽象类未必要有抽象方法.
6. java中会存在内存泄露吗?
答:理论上java不会存在内存泄露的问题,应为有垃圾回收机制(GC).然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此会导致内存泄露. 例如hibernated的Session中的对象属于持久态,垃圾回收器不会回收这些对象,这些对象中有可能存在无用的垃圾对象.如果关闭不及时,一级缓存就可能导致内存泄露.
7.final,finally, finalize有什么区别?
答:
8. List,Map,Set 三个接口存取元素时,各自有什么特点?
答:
9. 线程的sleep()方法和yield()方法有什么区别?
答:
10. 转发(forward)和重定向(redirect)的区别?
答:forward是容器中控制权的转向,是服务器请求资源,服务器直接访问目标地址的URL,把那个URL 的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址redirect就是服务器端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,因此从浏览器的地址栏中可以看到跳转后的链接地址,很明显redirect无法访问到服务器保护起来资源,但是可以从一个网站redirect到其他网站。
11.Cookie和Session的区别:
1)cookie数据存放在客户的浏览器上,session数据放在服务器上。
2)cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4)单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
所以个人建议:将登陆信息等重要信息存放为session;其他信息如果需要保留,可以放在cookie中。
12.位运算符可能会出现的笔试题目:
1)交换两个变量的值,不准出现第三方变量。例如:int a = 3;int b = 5;
/*
第一种方式: 定义第三方变量。
int temp = a; //3
a = b; //a = 5
b = temp;
方式2:相加法, 缺点: 两个int类型的数据相加,有可能会出现超出int的表示范围。
a = a+b; // a =8
b = a-b; //b = 8 - 5 = 3
a = a-b; // a = 8 - 3 = 5
方式3: 可以使用异或。 缺点: 逻辑不清晰。
*/
a = a^b; // a = 3^5
b = a^b; // b = (3^5)^5 = 3
a = a^b; // a = (5^3)^3 = 5
2)取出一个二进制数据的指定位数。要求读取该二进制数据的低4位。则用与的方式来做,即低4位用1去与,其他位用0去与运算。
13.解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。
答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。
如:String str =
new
String(
"hello");
语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而”hello”这个字面量放在静态区。
14.为什么使用数据索引能提高效率?
答:
1)数据索引的存储是有序的
2)在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
3)极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)
15.重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。
16.抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
17.请说出与线程同步以及线程调度相关的方法。
答:
提示:关于Java多线程和并发编程的问题,建议大家看我的另一篇文章《关于Java并发编程的总结和思考》。
补充:Java 5通过Lock接口提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;此外,Java 5还提供了信号量机制(semaphore),信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)。
18. 编写多线程程序有几种实现方式?
答:Java 5以前实现多线程有两种实现方法:一种是继承Thread类;另一种是实现Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活。
补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值,代码如下所示:
19. Java中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。
20.Java中有几种类型的流?
答:字节流和字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。
关于Java的I/O需要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。另外Java中的流不同于C#的是它只有一个维度一个方向。
21.如何通过反射创建对象?
答:
22. MyBatis中使用#和$书写占位符有什么区别?
答:#将传入的数据都当成一个字符串,会对传入的数据自动加上引号;$将传入的数据直接显示生成在SQL中。注意:使用$占位符可能会导致SQL注射攻击,能用#的地方就不要使用$,写order by子句的时候应该用$而不是#。
23.MyBatis中的动态SQL是什么意思?
答:对于一些复杂的查询,我们可能会指定多个查询条件,但是这些条件可能存在也可能不存在,例如在58同城上面找房子,我们可能会指定面积、楼层和所在位置来查找房源,也可能会指定面积、价格、户型和所在位置来查找房源,此时就需要根据用户指定的条件动态生成SQL语句。如果不使用持久层框架我们可能需要自己拼装SQL语句,还好MyBatis提供了动态SQL的功能来解决这个问题。MyBatis中用于实现动态SQL的元素主要有:
24.什么是IoC和DI?DI是如何实现的?
答:IoC叫控制反转,是Inversion of Control的缩写,DI(Dependency Injection)叫依赖注入,是对IoC更简单的诠释。控制反转是把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的”控制反转”就是对组件对象控制权的转移,从程序代码本身转移到了外部容器,由容器来创建对象并管理对象之间的依赖关系。IoC体现了好莱坞原则 – “Don’t call me, we will call you”。依赖注入的基本原则是应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由容器负责,查找资源的逻辑应该从应用组件的代码中抽取出来,交给容器来完成。DI是对IoC更准确的描述,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
举个例子:一个类A需要用到接口B中的方法,那么就需要为类A和接口B建立关联或依赖关系,最原始的方法是在类A中创建一个接口B的实现类C的实例,但这种方法需要开发人员自行维护二者的依赖关系,也就是说当依赖关系发生变动的时候需要修改代码并重新构建整个系统。如果通过一个容器来管理这些对象以及对象的依赖关系,则只需要在类A中定义好用于关联接口B的方法(构造器或setter方法),将类A和接口B的实现类C放入容器中,通过对容器的配置来实现二者的关联。
依赖注入可以通过setter方法注入(设值注入)、构造器注入和接口注入三种方式来实现,Spring支持setter注入和构造器注入,通常使用构造器注入来注入必须的依赖关系,对于可选的依赖关系,则setter注入是更好的选择,setter注入需要类提供无参构造器或者无参的静态工厂方法来创建对象。
25.解释一下什么叫AOP(面向切面编程)?
答:AOP(Aspect-Oriented Programming)指一种程序设计范型,该范型以一种称为切面(aspect)的语言构造为基础,切面是一种新的模块化机制,用来描述分散在对象、类或方法中的横切关注点(crosscutting concern)。
”横切关注”是会影响到整个应用程序的关注功能,它跟正常的业务逻辑是正交的,没有必然的联系,但是几乎所有的业务逻辑都会涉及到这些关注功能。通常,事务、日志、安全性等关注就是应用中的横切关注功能。
26.Spring中自动装配的方式有哪些?
答:
说明:自动装配没有自定义装配方式那么精确,而且不能自动装配简单属性(基本类型、字符串等),在使用时应注意。
27.Spring中的自动装配有哪些限制?
答:
28. 线程和进程的区别?
答:线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
29.B+树索引和哈希索引的区别?
答:
1)B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的;
2)哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可,是无序的。
30.Runnable接口和Callable接口的区别?
答:Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。
31.volatile关键字的作用?
答:
1)使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读取到volatile变量,一定是最新的数据。
2)对任意单个volatile关键字修饰的变量的读/写具有原子性,即不可被中断的一个或一系列操作。
32.sleep方法和wait方法有什么区别 ?
答:sleep方法和wait方法都可以用来放弃CPU一定的时间,不同点在于如果线程持有某个对象的监视器,sleep方法不会放弃这个对象的监视器,wait方法会放弃这个对象的监视器。
33.什么是乐观锁和悲观锁?
答:
1)乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁;
2)悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁。
34.垃圾回收的优点和原理,并考虑2种回收机制?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
答:
1)优点:可以有效的防止内存泄漏,有效的使用可以使用的内存;
2)原理:对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆中的所有对象。通过这种方式确定哪些对象是“可达的”,哪些对象是“不可达的”。当GC确定一些对象为“不可达”时,GC就有责任回收这些内存空间。
3)回收机制:分代复制垃圾回收、标记垃圾回收和增量垃圾回收。
4)垃圾回收器可以马上回收内存。
5)程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定执行。
35.请说出 ArrayList和Vector的区别?
答:主要从两方面来说:
1)同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的。
2)数据增长:当需要增长时,Vector默认增长为原来的一倍,而ArrayList却是原来的一半。
36.HashMap和Hashtable的区别?
答:
37. 动态代理的概念,实现动态代理的方式以及区别?
答:动态代理是指运行时动态生成代理类。方式包含:JDK和Cglib动态代理;区别:JDK动态代理是通过接口的方式实现的,而Cglib动态代理是通过继承当前类的子类实现的。
38. 如何避免SQL注入?
答:
39. Spring常用的注入方式有哪些?
答:
40. Spring事务实现方式?
答:
41. 为什么要用 spring boot?
答:
42. spring cloud 断路器的作用是什么?
答:在分布式架构中,断路器模式的作用是类似的,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。
43. spring cloud 的核心组件有哪些?
答:
44. 进程之间的通信方式?管道和命名管道的区别?
答:
(1)进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。
(2)主要区别在于被创建和访问的方式上。 命名管道可以在无关的进程之间交换数据,管道只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间);管道不属于其他任何文件系统,并且只存在于内存中,而命名管道有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
45. 什么是死锁?死锁产生的原因?死锁的四个必要条件?怎么破坏死锁?
答:
(1)多个并发进程因争夺系统资源而产生相互等待的现象。
(2)原因:
(3)必要条件:
当以上四个条件均满足,必然会造成死锁,发生死锁的进程无法进行下去,它们所持有的资源也无法释放。这样会导致CPU的吞吐量下降。所以死锁情况是会浪费系统资源和影响计算机的使用性能的。
(4)解除办法:
1. 常用的集合有哪些?
2. HashMap和HashTable的区别?
3. HashMap的工作原理?
HashMap基于hashing原理,通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
4. HashMap的put方法的原理或过程?
HashMap在调用put方法的时候,HashMap使用Key的hashCode()和哈希算法来找出存储key-value对的索引。如果索引处为空,则直接插入到对应的数组中,否则,判断key是否相等,相等就将value替换,不相等就判断是否是红黑树,若是,则以红黑树方式插入,否则遍历链表,找到key那么就修改value,没找到就新建节点插到链表尾部,最后判断链表长度是否大于8,来判断是否需要将链表转为红黑树。
5. HashMap的get方法的原理或过程?
HashMap在调用put方法的时候,HashMap使用Key的hashCode()和哈希算法来找出存储key-value对的索引,如果索引处为空,则直接返回空,否则,判断key是否相等,相等就直接返回value,不相等则判断是否是红黑树,是则遍历整棵树来查找,不是则遍历这个链表来查找。
6. 为什么HashMap中链表长度大于8就要转为红黑树?
HashMap中的元素初始化是链表保存的,其查找性能是O(n),而树结构能将查找性能提升到O(log(n))。当链表长度很小时,遍历速度也非常快,但当链表长度不断变长,查找性能会有一定影响,所以需要转成红黑树。
7. HashMap的扩容机制?
当HashMap中的元素个数超过数组容量大小*负载因子(默认为0.75),就会进行数组扩容,默认情况数组大小为16,即当HashMap中的元素个数超过16*0.75=12时,就会把数组的大小扩展为2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常耗性能的操作。
8. HashMap在JDK1.7和JDK1.8中有哪些不同?
9. HashMap是怎么解决哈希冲突的?
10. ConcurrentHashMap和Hashtable的区别?
11. ArrayList与Vector的区别?
12. ArrayList与LinkedList 的区别?
13. Array 和 ArrayList 有什么区别?什么时候该应 Array 而不是 ArrayList 呢?
(1)区别:
(2)对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
14. HashSet是如何保证数据不可重复的?
HashSet的底层其实就是HashMap,HashSet实现Set接口并把数据作为HashMap的key,而value值一直使用一个相同的虚值来保存,HashMap的key本身就不允许重复,从而保证了数据的不可重复性。
红黑树详解链接:https://blog.csdn.net/u011240877/article/details/53329023
一、Java 基础知识
二、Java 核心知识
三、Java 必问专题
四、Java 框架
五、分布式系统基础中间件
六、MySQL
七、JVM
八、如何准备技术面试
1. 面向对象的特性有哪些?
答:封装、继承、多态。
2. Java 中 Override 和 Overload 有什么区别?
追问:什么情况下方法不能被重写?
答:方法被定义为 final 的时候不能被重写。
3. 抽象类和接口有什么区别?
(1)抽象类:
(2)接口:
追问:什么情况下选择接口,什么情况下选择抽象类?
答:当要创建不带任何方法定义和成员变量的基类,应该选择接口;当有方法定义和成员变量的时候,应该选择抽象类。
4. JRE、JDK、JVM 有什么区别?
5. 值传递和引用传递有什么区别?
6. JDK 中常用的包有哪些?
7. 访问修饰符 public、protected、 default、private 的区别?
在这里插入图片描述
8. 数据基础类型有哪些?
答:基础类型有 8 种:byte、boolean、char、short、int、float、long、double,注意 String 不属于基础类型, 属于对象。
9. final 有什么用?
答:用于修饰类、属性和方法;凡是引用 final 关键字的地方皆不可修改!
10. 常用的集合类有哪些?
答:最常用的集合类是 List 和 Map。
11. HashMap 和 Hashtable 有什么区别?
12. HashMap 的实现原理是什么?
答:HashMap 基于 Hash 算法实现的,我们通过 put(key,value) 存储,get(key) 来获取。当传入 key 时,HashMap 会根据 key. hashCode() 计算出 hash 值,存储时,如果出现 hash 值相同的 key,此时有两种情况,如果 key 相同,则覆盖原始值;如果 key 不同,即出现冲突,则将当前的 key-value 放入链表中。获取时,直接找到 hash 值对应的下标,在进一步判断 key 是否相同,从而找到对应值。
13. ConcurrentHashMap 的实现原理是什么?
ConcurrentHashMap 是 Java1.5 中引用的一个线程安全的支持高并发的 HashMap 集合类。该类包含两个静态内部类 HashEntry 和 Segment,前者用来封装映射表的键值对,后者用来充当锁的角色。Segment 采用了非常精妙的“分段锁”策略,每个 Segment 对应一个 HashEntry 数组,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment 锁。
14. ArrayList 和 LinkedList 的区别是什么?
15. 如何实现 Array 和 List 之间的转换?
16. 在 Queue 中 poll() 和 remove() 有什么区别?
答:两者都是返回第一个元素,并在队列中删除返回的对象。不同的是如果没有元素 poll() 会返回 null,而 remove() 会直接抛出异常。
17. 哪些集合类是线程安全的?
答:Vector、Hashtable 都是线程安全的,而 HashMap 是非线程安全的,不过 Java. util. concurrent 并发包中,ConcurrentHashMap 是线程安全的。
18. 什么是 Java 反射?
答:在 Java 运行时环境中,对于任意一个类,能够知道这个类有哪些属性和方法,对于任意一个对象,能够调用它的任意一个方法。
19. Java 怎么实现动态代理?
答:Java 中,常用的动态代理实现方式有两种,一种是利用 JDK 反射机制生成代理,另外一种是使用 CGLIB 代理。JDK 代理必须要提供接口,而 CGLIB 则不需要,可以直接代理类,是基于继承当前类的子类实现的。
20. 进程和线程有什么区别?
追问:GC(垃圾回收)知道吗?
答:垃圾回收线程是特殊的守护线程,守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
21. 创建线程有哪几种方式?
答:创建线程有三种方式:
22. 什么是多线程,多线程的优劣?
答:(1)多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。
(2)多线程的好处:
(3)多线程的劣势:
23. 你知道怎么创建线程池吗?
答 :创建线程池的方式有多种,这里你只需要答 ThreadPoolExecutor 即可。
ThreadPoolExecutor() 是最原始的线程池创建,也是阿里巴巴 Java 开发手册中明确规范的创建线程池的方式。
24. 线程池的常用参数有了解吗?
答:ThreadPoolExecutor 包含以下七个参数:
前两个参数可以这么理解,如果运行的线程少于 corePoolSize,Executor 则可以不排队直接添加新的线程;如果大于等于 corePoolSize,则将请求加入队列,如果无法加入,则创建新线程;如果超出 maxinumPoolSize,任务被拒绝。
25. 怎么保证线程安全?
26. synchronized 和 Lock 有什么区别?
27. 什么是死锁?
答:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。
追问:怎么避免?
28. ThreadLocal 是什么?有哪些使用场景?
答:
(1)当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
(2)ThreadLocal 的经典使用场景是 session 管理(不同的线程对应不同的 session)和数据库链接(为每个线程创建不同的链接)。
29. 你了解哪些设计模式?
30. 简单工厂模式和抽象工厂模式有什么区别?
31. Spring 框架的优点有哪些?
32. 什么是 Spring AOP?
答:即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。主要体现在事务处理、日志管理、权限控制、异常处理等方面。
33. 什么是 Spring IoC?
答:即 inverse of control(控制反转),是 Spring 的核心,是一种创建对象的思想。将创建对象的权力交给 Spring 容器,其实就是让 Spring 容器帮你创建对象,而你不需要在 Java 代码中 new 对象了。
34. Spring 常用的注入方式有哪些?
35. Spring 自动装配 bean 有哪些方式?
Spring 配置文件中 节点的 autowire 参数可以控制 bean 自动装配的方式:
36. @Autowired 是做什么用?
答:@Autowired 是一个注释,它可以对类成员变量、方法及构造函数进行标注,让 Spring 完成 bean 自动装配的工作。
37. Spring Boot 有什么优势?
38. Spring Boot 配置文件有哪几种类型?
答:配置文件有 . properties 格式和 . yml 格式,它们主要的区别是书法风格不同。
39. Spring Cloud 是什么?
答:Spring Cloud 是基于 Spring Boot 的一整套实现微服务的框架。它它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。
40. Spring Cloud 的核心组件有哪些?
当然,除了以上还有很多,就不一一列举了。
41. MyBatis 和 Hibernate 的区别有哪些?
42. ZooKeeper 是什么?
答:ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
43. ZooKeeper 集群选主和同步的机制是什么?
答:ZooKeeper 的核心是原子广播,这个机制保证了各个 Server 之间的同步,实现这个机制的协议叫做 ZAB 协议。ZAB 协议有两种模式:分别是恢复模式和广播模式。
44. 集群中有 3 台服务器,宕机 1 台,这个时候 ZooKeeper 还可以使用吗?
答:可以,根据选票过半的选举原则,因此集群节点最好为奇数;单数服务器只要没超过一半的宕机就可以继续使用;所以 ZooKeeper 集群的容灾数量 =(集群总节点数 - 1)/2;也就是说 3 台服务器集群的话,最多允许 1 台宕机。
45. Redis 是什么?都有哪些使用场景?
答:
(1)Redis 是一个使用 C 语言开发的高效缓存内存数据库。
(2)Redis 使用场景:
46. 你使用过 Redis 的哪些常用功能?
47. Redis 支持的数据类型有哪些?
答:Redis 支持的数据类型:string、list、hash、set、zset(sorted set)。
48. Redis 和 Memcache 有什么区别?
49. 什么是缓存穿透?怎么解决?
答:
(1)缓存穿透:
指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
(2)解决方案:
缓存空对象。如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
50. 缓存和数据库之间怎么保证双写一致性?
51. Redis 持久化有几种方式?
52. Redis 怎么实现分布式锁?
答:Redis 分布式锁一般使用 setnx(set if not exists)指令,只允许被一个程序占有,占用成功了就可以继续执行,失败了就只能放弃或稍后重试,使用完调用 del 释放锁。
伪代码示例(这里只是简述,实际应用没有那么简单的,感兴趣的同学可以详细查一下资料):
加锁:setnx(key,threadId)
设置超时时间:expire(key,60)
解锁:del(key)
53. 消息队列的使用场景有哪些?
54. 消息队列包含哪些核心角色?
55. JMS 和消息队列的关系?
答:JMS(Java Messaging Service)是 Java 平台上有关面向消息中间件的技术规范,通过提供标准的产生、发送、接收消息的接口简化企业应用的开发,翻译为 Java 消息服务。它是 Java EE 中定义的一组标准 API,它自身并不是一个消息服务系统。
56. ActiveMQ 的基本使用?
57. ActiveMQ 消息传输模式
在点对点模型中,一个消费者对应一个生产者,生产者将消息放入队列中,当消费者请求队列中的消息时,消息会从队列中取出,并投递给消费者,消息投递后会从队列中删除,这样就可以保证消息只能投递给一个接收者。而且消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在任何时刻发送信息到队列,而不需要知道接收客户端是不是在运行。
一个生产者产生消息发送后,可以被多个消费者进行接收。消息会发送给一个主题,与队列类似,多个接收者都可以监听一个主题。但与队列不同的是,消息主题的所有订阅者都会接收到此消息。并且必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。
58. ActiveMQ 的消息持久化策略
59. 数据库的三范式是什么?
60. ACID 分别指的是什么?
61. SQL 的内连接、左连接、右连接有什么区别?
答:内连接是把匹配的关联字段显示出来;左连接会读取左边数据表的全部数据,即使右边数据表没有对应数据。右连接会读取右边数据表的全部数据,即使左边数据表没有对应数据。
62. MySQL 索引是怎么实现的?
答:MySQL 官方对索引的定义为:索引(Index)是帮助 MySQL 高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是一种数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。目前主流的数据库引擎的索引都是 B+ 树实现的,索引的性能也是更好的。
63. 怎么验证 MySQL 的索引是否满足需求?
答:需要根据查询需求来判断配置哪种索引,确定索引后,可以通过 explain 命令来查看执行计划,确认是否满足需求。explain 语法:explain select * from table。
64. 说一下数据库的乐观锁和悲观锁?
65. MySQL 问题排查都有哪些手段?
66. 如何做 MySQL 的性能优化?
67. 你了解类加载过程吗?
答:类加载的过程包括了加载、验证、准备、解析、初始化五个阶段:
68. 什么是双亲委派模型?
当收到加载一个类的请求时,子类加载器并不会马上去加载,而是依次去请求父类加载器加载,一直往上请求到最高类加载器:启动类加载器。当启动类加载器加载不了的时候,依次往下让子类加载器进行加载。当达到最底下的时候,如果还是加载不到该类,就会出现 ClassNotFound 的异常。
69. 你熟悉 JVM 哪些垃圾回收算法?
70. 你熟悉 JVM 哪些垃圾回收器?
答:这里简述几个经典常用的即可:
71. 你熟悉 JVM 哪些调优参数?
1. 明确技术方向,匹配岗位要求
学历、工作年限、技能、项目经历、软实力。找准定位,是要做技术还是偏管理。划重点:做技术就不要提管理。面试官非常讨厌技术不扎实的人,明明是面试技术,却总是提管理。这里不是说不需要管理能力,而是要分清楚主次,只有你的技术使面试官满意了,管理能力才能为你加分。
2. 盘点个人价值,找亮点
在 HR 们的眼中,我们都是商品,你要把自己的价值以最直观的方式体现出来,不要扯其他没用的。明确了自己有什么价值,你需要问自己一个问题:以行业标准衡量,你觉得你是哪个领域的专家?因为你只有是某个领域或者方向的专家,性价比高,HR 们才会觉得这笔买卖很划算。不要自惭形秽,你之所以平庸,是因为你没有深挖自己的亮点,在简历最后一栏自我评价里,把亮点一一列举出来,如果你实在是找不到,那总做过项目吧,能吃苦吧,善与人相处吧,逐条写出来。
划重点:项目经验多不代表能力强,要总结而不是叙述,千万不要逐个项目长篇叙述业务模块,面试官对你做过的项目业务逻辑根本不感兴趣,你需要把项目中你用过的技术列举出来,最好是只写最近的或者你最有成就感的项目,把你了解的技术栈全都写上。
3. 内推和猎头,机会大很多
选择公司也很重要,是互联网公司还是传统企业,传统企业相对重视业务,而互联网公司比较重视技术。公司主要是做什么产品、用的什么技术 。如果你的资历不够,学历双非,但技术很强,想去大厂也不是没机会。划重点:找内推、找猎头推荐要比自己投简历要机会大得多。
4. 知己知彼百战不殆
薪资、福利、平台优势、晋升机制、工作环境、人际关系、工作强度、社会地位等等,把这些全都列出来,做个表格,排好优先级。现在业界对于跳槽涨薪的幅度大都控制在 30% 以内,了解一下你的城市、这个企业这个技术方向的平均薪酬来参考。划重点:知己知彼才好跟 HR 谈薪。
5. 一份简历闯天下?不可取
不同的企业、岗位需要的技能不同,你需要制定有针对性的简历。
划重点:
不要随便写与岗位不匹配的技能;
只写项目中你负责的工作即可;
简历中的内容不要坑自己,每一句都要做到心中有数;
把项目成果最好能量化体现。
6. 练习自我介绍
直接划重点:
最后,拿得出手的经典项目准备一个,刷刷面试题,还要准备一些非技术类问题,比如这个必问的经典问题:你为什么离职?关于这个问题,说心里话,没必要那么固执。不要回答“上个公司加班太多,工作生活不能兼顾诸如此类 “,这样回答虽然没毛病,但是却不是标准答案,试问哪个互联网公司不加班?如果有,谁不想去?这个问题标准答案是:我的个人职业规划的原因,我需要一个更大的平台来施展,不断地见识、学习和成长。
最后还要准备一两个问面试官的问题,标准答案:贵公司当前使用的主流技术栈有哪些?如果我顺利通过面试,我将会加入哪个团队?我未来的工作方向是什么?千万别扯别的,诸如你们公司薪酬大概是多少?(保密的不知道吗),你们加班多不多?(废话)。管住好奇心,这些问题等你过了技术面试,留着 HR 来回答你。
大家看看,面试前都要准备那么多,如果是资深工程师岗位或者技术专家岗位,你可能起码要准备 3 个月,即便是初/中级工程师,面试前也要认真准备 1 个月,这样你的面试成功率才会高很多。