剑指Offer——京东校招笔试题+知识点总结
笔试感言
经过一系列的笔试,发觉自己的基础知识还是比较薄弱的,尤其是数据结构和网络,还有操作系统。工作量还是很大的。做到精确制导的好方法就是在网上刷题,包括牛客和赛马网。另外,赛马网的编程IDE实在是不敢恭维。在本地运行正确,在他那居然提示全部数据未通过。
关键是在京东投的是Android岗,我只能说总体上Android确实比Java岗容易,但是自己的重心还是放在Java后台研发的。
网络方面,其中考到FTP端口。TCP、HTTP等。
默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。但是,是否使用20作为传输数据的端口与FTP使用的传输模式有关,如果采用主动模式,那么数据传输端口就是20;如果采用被动模式,则具体最终使用哪个端口要服务器端和客户端协商决定。
默认HTTP的端口号为80,HTTPS的端口号为443;
TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯。
TCP提供的是一种可靠的数据流服务,采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。
UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。
UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。
UDP与TCP位于同一层,但它不管数据包的顺序、错误或重发。因此,UDP不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。相对于FTP或Telnet,这些服务需要交换的信息量较小。使用UDP的服务包括NTP(网络时间协议)和DNS(DNS也使用TCP)。
SMTP:简单邮件传输协议,使用TCP连接,端口号为25;
SNMP:简单网络管理协议,使用UDP 161端口;
对于一个已经建立的连接,TCP使用改进的三次握手来建立连接(使用一个带有FIN附加标记的报文段),使用四次挥手释放连接;
cookie是存储在客户端 session是存储在服务端;
DNS协议运行在UDP协议之上,使用端口号53;
UDP报头只有四个域:源端口号,目的端口号,数据报长度,检验和。
UDP是无连接,无超时重发,大数据传输容易造成数据重复或者数据中断等,无法保证数据包不损坏.
UDP是无连接的用户数据报协议,传输过程无阻塞不重发,只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地,所以没有可靠性.
UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
TCP协议才是窗口机制的三次握手连接会话.
数据结构方面设计到二叉排序树(二叉查找树)、字典树(Trie树)、散列表(Hash表)等知识点。
简答题
1.jvm垃圾收集基本原理
主要从三个方面(Which、When、How)进行解答:1.哪些内存需要回收?2.什么时候回收?3.如何回收?
确定哪些内存需要回收,主要采用引用计数法和可达性分析方法。
引用计数(Reference Counting)
比较古老的回收算法。原理是给对象添加一个引用计数器,此对象有一个引用,计数器值加1;引用失效时,计数器值减1。垃圾回收时,只用收集计数为0的对象。此算法最致命的缺点是无法处理循环引用的问题。
可达性分析方法(Reachability Analysis)
基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为“引用链(Reference Chain)”,当一个对象到GC Roots没有任何引用链时(用图论的话说,就是GC Roots到这个对象不可达),则证明该对象是不可用的。
垃圾收集算法
回收算法主要采用标记-清除算法、复制算法(新生代)、标记整理算法(老年代)、分代收集算法。
标记-清除(Mark-Sweep)
此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。 故存在效率、空间浪费问题。
复制(Copying)
此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要内存空间缩小为原来的一半。 现在的商业虚拟机都采用这种收集算法来回收新生代。
标记-整理(Mark-Compact)
此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把所有存活对象“压缩”到堆的其中一块,按顺序排放,然后直接清理掉边界之外的内存。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。 主要用来回收老年代。
增量收集(Incremental Collecting)
实时垃圾回收算法,即:在应用进行的同时进行垃圾回收。不知道什么原因JDK5.0中的收集器没有使用这种算法。
分代(Generational Collection)
基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法的。
2.单例模式
写出单例模式的2种方式(其实就是懒汉式与饿汉式啊,自己居然想成了加锁的不同形式,太菜了~);
单例模式的两种实现方式
package cn.edu.ujn.practice; // 懒汉式 public class Singleton { private static Singleton singleton; private Singleton(){} public static Singleton getInstance(){ if(singleton == null){ synchronized(Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton; } } // 饿汉式 class SingletonHungry{ private final static SingletonHungry singletonHungry = new SingletonHungry(); private SingletonHungry(){} // 务必使用static声明为类所属方法 public static SingletonHungry getInstance(){ return singletonHungry; } }
编程题
Android岗中2道编程题如下: