Java面试札记
java
在最深的夜里,即便是你的影子也会离你而去。面试
背景:愿某人在中秋节以前吃上大厂月饼!!!@CDZredis
一、Java的八种基本数据类型?算法
整型:byte、int、short、long;shell
浮点型:float、double;数据库
布尔类型:boolean;设计模式
字符型:char。数组
二、什么是重入锁?缓存
java.util.concurrent.ReentrantLock,这个是JDK1.5添加的一种颗粒度更小的锁,它彻底能够替代synchronized关键字来实现它的全部功能,并且ReentrantLock锁的灵活度要远远大于synchronized关键字。安全
三、Controller是单例仍是多例?
Spring管理的Controller,即加入@Controller注入的类,默认是单例的,所以建议:
一、不要在Controller中定义成员变量;
二、若必需要在Controller中定义一个非静态成员变量,则经过注解@Scope("prototype"),将其设置为多例模式;
四、StringBuffer和StringBuilder的区别?
StringBuffer是线程同步安全的,StringBuilder是非线程安全的通常用于单线程;
五、为何要加双重锁?
一、为何要进行第一次判空?
单例模式只有第一次执行create()方法的时候才会走synchronized中的代码,后面再次访问的时候直接返回single对象;若是说咱们没有第一次校验,每个线程都要走sychronized中的代码,
而每一次线程都要去拿到同步锁才能执行;在多线程状况下,每个线程要拿到single对象都要排队等待同步锁释放,所以第一次校验就是为了提升程序的效率。
二、为何要进行第二次判空?
举个例子:假如如今没有第二次校验,线程A执行带第一次校验那里,它判断到single==null,此时它的资源被线程B抢占了,B执行程序,进入同步代码块建立对象,而后释放同步锁,此时线程
A又拿到了资源,也拿到了同步锁,而后执行同步代码块,由于以前线程A它判断到single==null,所以它会直接建立新的对象,因此就违反了咱们设计的最终目的。
六、5L的桶和3L的桶如何量出4L的水?
把3L的桶装满水,而后所有倒入5L桶中,此时5L桶中有3L水;再把3L桶装满水,而后倒入装有3L水的5L桶中直至满,此时3L桶中有1L水;把5L桶中的水倒完,再把3L桶中剩余的1L水倒入
5L桶中,此时5L桶中有1L水;再把3L桶装满水,所有倒入装有1L水的5L桶中,此时5L桶中有4L水。
七、如何给一条数据库记录加锁?
一、共享锁:select * from table_name where ...... lock in share mode;
二、排他锁:select * from emp where empid > 100 for update;
加锁后其余人不可操做,直到加锁用户解锁,用commit或rollback解锁。
八、如何捕获线程异常?
方式1(setUncaughtExceptionHandler):
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler();
方式2:
使用Executors建立线程时,还能够在ThreadFactory中设置:
t.setUncaughtExceptionHandler(new MyUncheckedExceptionHandler());
该方法还须要提交线程异常:exec.execute(new ExceptionThread());
方式3:
利用线程池提交线程时返回的Future引用:
Integer result = future.get();
九、JDK1.8的日期类有哪些?
获取当前时间:LocalDateTime、LocalTime、LocalDate
LocalDateTime d0 = LocalDateTime.now(); System.out.println(DataConvertUtil.localDateTimeToStr(d0,"yyyy-MM-dd HH:mm:ss"));
十、Redis集群策略
Redis包含三种集群策略:主从复制、哨兵、集群;
主从复制特色:
主数据库负责读写操做,当读写操做致使数据变化时会自动将数据同步给从数据库;从数据库通常是只读的,而且接受主数据库同步过来的数据;一个master能够拥有多个slave,可是一个slave只能对应一个master。
主从复制工做机制:
当slave启动后,主动向master发送SYNC命令,而后将保存的快照文件和缓存的命令发送给slave,slave接收到快照文件和命令后加载快照文件和缓存的执行命令;复制初始化后,master每次接收到的写命令都会同步发送给slave,保证数据库一致性。
主从复制配置:
Redis默认主数据库,因此master无需配置,只须要修改slave的配置便可;在slave中设置须要链接的master的ip端口:slaveof 10.58.166.207 6379。
哨兵:
哨兵的做用是监控redis系统的运行情况,其功能以下:
一、master出现故障时,自动将slave转化为master;
二、多个哨兵能够监控同一个redis;
三、多哨兵配置时,哨兵之间会自动监控。
集群:
使用Redis集群,只须要将每一个数据库节点的cluster-enable配置打卡便可;每一个集群中至少须要三个主数据库才能正常运行。
十一、快排思想?
快速排序是对冒泡排序的一种改进,经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另外一部分的全部数据都要小。
十二、桶排序算法?
桶排序是常见排序算法中速度最快的一种,假设有一个大小为n的数组int arr[n] ,遍历数组找到最大值M,而后申请一个大小为M+1的数组int m[M+1],刚开始的时候将m[0]~m[M+1]都值都初始化为0,而后遍历数组n,把对应的arr[n]填入日子m[M+1]都对应位置,若是有重复的元素则在此位置的基础上+1。
1三、MySQL的四种读写机制?
一、未提交读 Read Uncommitted:容许脏读,也就是可能读取到其它会话中未提交事务修改的内容;
二、提交读 Read Committed:只能读取到已经提交了的数据;(不重复读,Oracle数据库默认该级别)
三、可重复读 Repeated Read:在同一个事务内的查询都是事务开始一刻一致的,InnoDB默认级别;(MySQL数据库默认该级别)
四、串行读 Serializeble:彻底串行化的读,每次读都须要得到表级共享锁,读写相互都会阻塞,级别最高。
1四、使用什么方法替代代码中的if-else?
一、使用工厂模式去耦合;
二、尽量抽象方法、优化代码逻辑,减小判断方法;
三、从业务逻辑上优化减小if-else或用switch。
1五、Linux内部命令和外部命令的区别?
内外部命令的功能基本相同,但存在的位置有差别,能够经过type来查看是内部命令仍是外建命令。
图.内部命令/外部命令
内部命令:
内部命令是shell程序的一部分命令,包含一些简单的Linux系统命令,内部命令是在bashy源码中,其执行速度一般比外部命令要快;
外部命令:
每一个外部命令对应系统中的一个文件,外部命令不包含在shell中,可是其命令执行过程是由shell程序控制的,如管理外部命令执行的路径查找、加载存放和控制命令的执行,外部命令一般存放在/bin、/usr/sbin目录下。
1六、JVM算法?
三种算法:标记-清除算法、复制算法、标记整理算法;
标记清除算法:
采用从根集合进行扫描,对存活的对象进行标记,标记完毕后再扫描整个空间中未被标记的对象,并对其进行直接回收;该算法不须要进行对象的移动,而且仅对不存活的对象进行处理,在存活的对象较多的状况下极为高效;但因为该算法只回收不存活的对象,并无对存活的对象进行整理,所以会致使内存碎片。
复制算法:
将内存划为两个分区,使用此算法时,全部动态分配的对象只能分配其中的一个区间(活动区间),而另一个区间则是空闲区间;其采用从根集合扫描,将存活的对象复制到空闲区间,当扫描
完毕活动区间后,会将活动区间一次性回收,此时本来的空闲区间变成了活动区间,下次GC的时候又会重复刚才的操做,如此循环;可是,此方法须要克服50%内存的浪费。
标记整理算法:
采用标记-清除算法同样的方式进行对象的标记、清除,但在回收不存活的对象占用的空间后,该算法会将全部存活的对象往左端空闲区间移动,并更新对应的指针,其是在标记-清除算法之上又
进行了对象的移动排序整理,所以成本更高,但也解决了内存碎片的问题。
1七、HashMap简单介绍下?
HashMap是用于存储key-value键值对的集合,它是根据键的hashCode值存储数据,能够直接定位到它的值,因此具备很快的访问速度,是非线程安全的;从总体结构上看HashMap是由数组+链表+红黑树实现的。(简单讲下get、put、remove和扩容,扩容为原数组大小两倍的新数组,新数组的索引位置要么在原位置不变,要么是原位置+旧数组长度)
1八、经常使用设计模式?
单例模式、工厂模式、代理模式、观察者模式、装饰者模式、适配器模式、模版模式、策略模式、访问者模式。
在最深的夜里,即便是你的影子也会离你而去。