转载本文请联系Java极客技术公众号。阿芬最近接到了一个面试,但是面试的结果并不是很理想,因为虽然有些问题回答的很好,但是因为面试官问了一些后序内容,阿芬不会,所以被打疯了挂了良久,他失望归来。面试题一:HashMap和ConcurrentHashMap的区别我们都知道HashMap不是线程安全的。当我们在并发情况下使用HashMap的put和get方法时,CPU会直接飙升,Thread的安全也没办法保证,但是更安全的HashTable呢?因为HashTable中的put和get方法都不是同步的。虽然保证了线程安全,但是效率比较低。并发访问时,一次只能有一个线程运行,其他线程只能阻塞执行。因此,其效率相对较低。这时候,我们就有了ConcurrentHashMap。ConcurrentHashMap使用锁分段(减少锁范围)、CAS(乐观锁,减少上下文切换开销,非阻塞)等技术。这时候,你回答了,一系列的操作就出现了。那你就分开说吧。在JDK1.7中,ConcurrentHashMap使用的锁分段技术,将数据分片存储,然后为每一段数据分配一个锁。当线程占用锁访问一段数据时,其他段的数据也被锁定。可以被其他线程访问。在JDK1.8中,ConcurrentHashMap使用CAS和synchronized方法来处理并发。以put操作为例,CAS方法确定key的数组下标,synchronized保证链表节点的同步效果。阿芬墨水不多,就说,你能给我一张纸吗?于是阿芬画了一张之前在网上看到的。图片。阿芬给面试官介绍的时候,直接从图片介绍,阿芬直接分析源码的时候,一开始Segment继承ReentrantLock的时候,面试官打断了我接下来要描述的,问我就可以了直接说1.8。在1.8中:首先创建一个新的哈希表(nextTable),它的大小是原来的两倍。后续的rehash操作都是针对这个新的哈希表,不涉及原来的哈希表(表)。然后对原哈希表(表)中的每一个链表进行rehash,然后尝试获取头节点的锁。这一步保证rehash过程中不能对链表进行put操作。通过sizeCtl控制,扩容过程中不会创建多个新的哈希表。最后,将所有键值对重新哈希到新表(nextTable)后,将表替换为nextTable。这样就避免了在HashMap中get和expansion并发时获取到null的问题。整个过程中,共享变量的存储和读取都是通过volatile或者CAS完成的,保证了线程安全。至于分析源码,阿粉不再分析,遇到面试分析源码的时候会继续告诉大家。毕竟下面还有很多内容。面试题2:你怎么看待这两种方式?为什么1.8变了?有什么好处?阿芬猜到你可能会问这个问题。毕竟你已经入门了,1.7和1.8你也已经分清楚了,难免??会有面试官问你这个问题,阿芬是这样回答的。(1)减少内存开销假设使用可重入锁,每个节点都需要继承AQS,但并不是每个节点都需要同步支持。只需要同步链表的头节点(红黑树的根节点)。无疑会消耗大量的内存。(2)JVM支持的可重入锁毕竟是API层面的,后续性能优化空间不大。Synchronized直接由JVM支持,JVM可以在运行时做出相应的优化措施:锁粗化、锁消除、锁自旋等。这使得synchronized随着JDK版本的升级,无需更改代码即可提升性能。也多亏阿芬,面试前看了很多这样的文章,比较了很多东西,所以第二题就结束了。面试题3:如何避免SQL注入?阿芬看到这个问题,第一反应肯定是按照我简历上写的来问的,因为阿芬之前的公司对安全要求比较高,像SQL注入,像跨站攻击,所以阿芬芬开始说话了。阿芬以前用的最多的就是在where条件后面加1=1然后继续写自己的参数。确认每个数据的类型,比如数字,数据库必须使用int类型存储一些数据库权限过滤参数中严格限制的数据库关键字,比如过滤一些and,char,这些是数据库语句word中的关键字。也有可能是面试官对这些数据安全方面没有太重视,所以阿芬回答了这些方法之后,也就算是结束了,也就没有继续深究了。面试题4:说说MySQL常用的引擎有哪些?数据库存储引擎是数据库的底层软件组织,数据库管理系统(DBMS)使用数据引擎来创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技术、锁定级别等功能,使用不同的存储引擎也可以获得特定的功能。许多不同的数据库管理系统现在支持许多不同的数据引擎。主要的存储引擎有:1.MyIsam,2.InnoDB,3.Memory,4.Archive,5.Federated。这个阿凡我就不跟你说了,给你整理几张图:面试题5:简历上说你用过redis,那说说redis的持久化方式。RDB持久化方法可以在指定的时间间隔存储数据的快照。AOF持久化方式记录每一次对服务器的写操作。当服务器重新启动时,这些命令将被重新执行以恢复原始数据。AOF命令使用redis协议将每次写操作追加保存到文件末尾。Redis还可以在后台重写AOF文件,这样AOF文件的体积就不会太大。RDB实际上是将数据以快照的形式保存在磁盘上。什么是快照?你可以理解为对当前时刻的数据拍照并保存。RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。它也是默认的持久化方法。该方法是将内存中的数据作为快照写入二进制文件。默认文件名为dump.rdb。至于如何触发,直接修改redis.conf配置文件即可。AOF持久化,其实就是将每次写操作追加保存到文件末尾。也有可能阿芬在实际使用Redis的时候并没有进行任何持久化操作。这里没有其他要回答的了。而后面面试官问的关于Redis的几个问题也不是特别好回答,所以还是要在Redis上下功夫。面试题6:JVM的内存结构,以及不同代的算法。阿粉之前的文章已经分析的很透彻了,这里阿粉把之前的链接发上来,大家可以看看。面试的时候按照这个套路回答JavaGC相关的问题,你一定能过!
