1、说说你做过的项目,项目遇到哪些困难?是如何解决的?
做过一个完整项目是关于一个负责大数据平台计算层和存储层解耦的中间层的开发工作。我负责的是其中Filter和Order By两种HiveSQL的语法信息的下推,也就是将Filter和Order By信息下推给存储层。项目难点就是没有开源的方案供参考,文档和需求是反复讨论然后确认的,中间也经过了很多次迭代。解决方法是,目标清晰地进行敏捷开发。我们这个中间层的功能可以总结为两点:其一,为存储层提供优化相关的参考信息,其二,针对多个不同的存储,加入中间环节,减少计算层和多个存储之间的耦合。事实上,各个存储之间有很多数据格式、事务支持方面的不同,可以提早获知,方便地加以解决,增加了系统的可用性。另外,客户也可以定制化需求,比如查询的null值的前后顺序等等。
2、技术相关
1)Java的自动装箱和拆箱
首先,Java中的数据类型分为基本类型和包装类型,基本类型包括8类,int, bool, char, byte, short, long, float, double,其均有对应的包装类型。包装类型融入了面对对象思想,丰富了基本类型的操作。包装类型是引用类型,当包装类型指向基本类型时,JVM自动把对应的基本类型装箱,再指向boxing。拆箱时,刚好反过来,基本类型要获取包装类型的值,包装类型中调用相应的api,比如intValue()。
2)讲一下Java的垃圾回收机制。
Java的垃圾回收,主要针对的是对象,其次是方法区。针对对象的回收,有三点,第一,何时会进行GC?第二,GC针对的是哪些对象?第三,GC主要做什么事情?
针对第一个问题,首先,现在的垃圾收集器主要采用的分代收集算法,将堆内存分为新生代和老生代。对新生代的回收叫做MinorGC,当新生代的eden区满的时候,触发MinorGC,将存活对象复制到第一块survivor中,并交换两块survivor。对老生代的回收叫MajorGC,因常伴随MinorGC,也称之为FullGC,FullGC的触发条件有几个:老年代空间不足,老年代担保失败,调用system.gc(),CMS收集器出现因并发标记时产生浮动垃圾,导致Concurrent Mode Failure,永久代空间不足。
针对第二个问题,GC的判断方式有两种,一种是引用计数法,对一个对象进行引用计数,计数为0则考虑清理,可能会因为循环引用进入死循环,第二种是可达性分析,也就是定义GC Roots,也就是JVM栈中的Thread Local里的对象,方法区的静态变量,常量,以及JNI。GC Roots不能抵达的对象考虑清理,当不可达时,有两次标记过程,第一次标记将对象放入F-Queue中,第二次标记再进行清理。可达性分析在JVM中的实现用到了OopMap,存储对象内的偏移量,对根节点进行枚举,由此确定是否需要清理,同时设置安全点,只有到达安全点时,才会STW,安全点一般采用主动检测,针对线程的Sleep和Blocked态,还会用到安全区域,即引用关系不发生变化的区域。
针对第三个问题,GC有几个层次,一个是算法,以上已经提的差不多了,一个是工具,HotSpot用的GC收集器有新生代、老年代的划分,以及G1收集器。新生代收集器有SerialNew,ParNew,ParScanvenger三种,相对应的,老年代收集器有SerialOld,ParOld,CMS三种。SerialNew是单线程串行的GC,缺点在于效率和吞吐量,优点在于简单。ParNew只是SerialOld的并行版本,优点在于可以与CMS配合使用。ParScavenger是吞吐量优先的,GC占比越小,吞吐量越大。有自适应算法。
SerialOld在CMS发送Concurrent Mode Failure时作为备用方案使用,ParOld常和ParScavenger配合。CMS可以并发地执行工作线程和GC线程,分为几步,初步标记,并发标记,重新标记,并发清除,并发标记和并发清除都可以并发使用。尽可能减少STW的影响。
G1收集器作为新生代,老生代通用的收集器,同时有复制算法和标记清除、整理算法。是集大成者。
3)Java如何使用线程?重写run方法和实现runnable接口有什么不同?
使用线程的方式有三个:继承Thread,实现Runnable或Callable接口,使用Executor框架。
前两者的不同在于继承Thread就要绑定Thread的各种资源,子类与父类耦合度高,在不需要这么强的绑定关系或没有明显的继承关系的时候,实现Runnable接口更有利。实际上,Thread类也是Runnable接口的一种实现。实际上,Thread类也实现了Runnable接口,同时也可以通过一个Runnable的实现类来构造。
4)如何进行线程管理?
5)设计模式
State设计模式,是用组合方式替代继承方式
6)TCP和UDP的区别
TCP和UDP的区别主要是有连接通信和无连接通信的区别。TCP通信之初要建立连接,结束通信要释放连接,而UDP则不需要建立连接。TCP相比UDP,不仅有FCS检验,还有针对无序、丢包、错包、流量控制、拥塞控制等场景的特殊处理。比如首部添加序号和确认号,ACK和SYN,来保证包的发送和接收是有序的,利用滑动窗口来控制发送方和接收方的流量,在提升效率的同时,保证可靠传输。还有慢开始,拥塞避免,快重传,快恢复的拥塞处理方法。当TCP建立之初,采用慢开始算法,即拥塞窗口从1起每次扩大一倍,当到达门限时,开始加法递增,当出现拥塞时,旧时采用拥塞避免,即将门限设为拥塞临界值的一半,窗口从1开始递增;现在多用快重传,快恢复算法,即当连续收到接收方三条重传消息时,将窗口降到临界值的一半,开始加法递增。
7)http和https的区别
https比http多了一个s,这个s指的是SSL,即安全套接字层,https发送的报文是https报文,即SSL流量通过http隧道进行盲转发,SSL是加密层,主要功能是加密,加密之前需要进行SSL握手,在双向认证后,可以穿过防火墙进行传输。
8)浏览器输入网址到显示网页的全部网络交互过程
输入网址,网址通常包含应用层协议,http/https/ftp等,和域名。域名通过域名系统进行解析,域名系统由本地的域名缓存和若干分布式的服务器构成,其中就包含了本地域名服务器,权限域名服务器,顶级域名服务器,根域名服务器。域名系统允许将域名解析工作委派给其他域名服务器。通常用到的域名解析算法有两种,一种是递归,一种是迭代。递归是从本地DNS开始,逐层进行递归调用,根域名服务器无法解析时,向下依次由顶级域名服务器,权限域名服务器进行解析,最后调用本地域名服务器进行解析。迭代是由本地域名服务器依次请求相应的DNS服务器解析域名。
在http协议框架下,应用层是通过http报文传递信息的,但前提是建立了TCP连接,建立TCP连接的过程可以归纳为三次握手,三次握手是通过客户端和服务器端之间发送TCP报文进行的,一般客户端是主动方,起初都是连接关闭状态。发送请求报文,即向服务端发出连接请求,该报文的SYN=1,其余控制位为0,还有相应的序号seq,发送后进入SYN-SENT状态。服务端收到报文时,如果接受连接请求,则发送连接接受报文,该报文的SYN=1,ACK=1,还有相应的seq和ack,其中ack确认号被定义成所收到连接请求报文的seq+1,即滑动窗口向右偏移一位,此时服务端进入SYN-RCVD状态。当客户端收到服务端的连接接受报文后,发送该报文的确认报文,其ACK=1,其余控制位为0,还有相应的seq和ack,seq+1,ack为收到的seq+1,客户端进入了连接建立状态。服务端收到该报文后也进入连接建立状态。
TCP连接建立后,就通过HTTP协议客户端发送请求和服务端响应。客户端发送的请求头部由请求方法、资源位置和http版本号组成。服务端收到后,由服务端软件web服务器,比如apache进行http解析,生成http request对象,将该对象交给响应的请求处理器进行处理,比如SpringMVC框架下的DispatcherServlet中央控制器,通过HandlerAdapter适配响应的处理器,得到ModelAndView,调用ViewResolver进行解析,渲染,返回web页面。再通过HTTP响应报文发送给客户端。响应报文通常包括响应行、首部和实体三部分,响应行是协议版本号+状态码+状态信息,首部是实体的type和length信息,实体是要发送的数据,这里是web页面。更流行的方式是,利用REST进行前后端分离设计,将客户端请求资源简化为浏览器发送Ajax请求,服务端收到后,利用REST生成JSON发送给浏览器端,由浏览器端进行渲染。这样就简化了请求响应的流程,分离了后端业务逻辑和前端页面渲染,性能得到了极大优化。
9)线程状态之间的转化
线程分为5个状态,创建、就绪、执行、阻塞、死亡。调用start方法,进入就绪队列,在得到CPU资源时,进入执行状态,执行状态中遇到中断、sleep、wait、join、显式锁等会进入阻塞态,由于相应原因阻塞态终止,进入就绪队列。当遇到yield的时候,由执行态进入就绪态,resume反之。当执行正常结束或发生异常时,线程终止。
10)Java线程池
11)冒泡排序
两次从前往后的遍历,逆序则交换。
12)new 一个对象后,JVM的内存分配情况
JVM内存分为堆和栈,堆里放对象和类变量、常量、Class信息,JIT编译好的运行时的符号引用和字面量,栈(JVM栈)里存执行过程中的局部变量、操作数、动态连接和方法出口。此外还包括本地方法栈和PC。因此new 一个对象后,在堆中申请空间进行存放,方法中通过符号引用进行调用。如果是字符串对象,则放入方法区中的常量池里。
3、你有什么问题要问我吗?
如果可以提前入职的话,公司会不会有相应的培训或者带新人的制度?新入职的应届生有什么需要注意的?作为一个职场和技术上的前辈,您对我们有什么忠告吗?
4)本科学习,爱好,最好的一门课程
5)你觉得自己的优势是什么?
我觉得我最大的优势是真心地期待进步吧。可能很多人无法体会实习期间加班到10点,最晚一次接近12点才一个人回到寝室。有时候要完成课程实践小组的既定任务,大家每天讨论到接近凌晨2点。一定要把事情做完,一定要做点东西出来,既是信念,也是动力。越发觉得,恒心比聪明更重要。
6)你觉得自己最大的劣势是什么?
7)你的职业规划是什么?