Last active
September 25, 2015 01:29
-
-
Save steven-zou/7ce14e01d2ad7cd07091 to your computer and use it in GitHub Desktop.
Record all the interview questions I met before
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 引用计数法(Reference Counting): | |
| 1. 有引用,计数器+1, 引用失效,则计数器-1 | |
| 2. 实现简单,判定效率高 | |
| 3. 未在主流虚拟机中使用,因为解决不了循环引用的问题 | |
| 可达性分析(Reachability Analysis): | |
| 1. 以GC root对象作为起点,向下搜索 | |
| 2. 所走过的路径为引用链, | |
| 3. 当一个对象到GC root 没有任何的引用链的时候,则不可达,可以回收 | |
| 4. 可作为GC root的对象 | |
| 4.1 虚拟机栈中引用对象 | |
| 4.2 方法区中的静态属性引用的对象 | |
| 4.3 方法区中的常量引用对象 | |
| 4.4 本地方法栈中的JNI引用对象 | |
| 垃圾收集算法: | |
| 1. 标记-清除 (Mark-Sweep) | |
| 问题:效率不高,会产生大量不连续的内存碎片 | |
| 2. 复制算法 | |
| 等大的内存块,讲存活的对象复制到另外一块,再把已使用过的内存空间一次清理掉 | |
| 现代商业虚拟机都依靠此技术来回收新生代 | |
| 问题:如果对象存活率较高时,进行太多的复制,效率变低 | |
| 3. 标记-整理算法 | |
| 先标记,之后所有存活对象向一边移动,然后直接清理掉端边界以外的内存 | |
| 现代商业虚拟机都采用的是分代收集算法 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Java Thread <-> Work memory | | | |
| | | | |
| Java Thread <-> Work memory <-> | Save &Load | Major Memory | |
| | | | |
| Java Thread <-> Work memory | | | |
| Memory operations: | |
| lock -> major memory | |
| unlock-> major memory | |
| read -> major | |
| load -> work memory | |
| use -> work | |
| assign -> work | |
| store ->work | |
| write -> major |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| http://www.360doc.com/content/12/0113/08/1073512_179088229.shtml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。 | |
| Read Uncommitted(读取未提交内容) | |
| 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未 | |
| 提交的数据,也被称之为脏读(Dirty Read)。 | |
| Read Committed(读取提交内容) | |
| 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔 | |
| 离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能 | |
| 返回不同结果。 | |
| Repeatable Read(可重读) | |
| 这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题: | |
| 幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时 | |
| ,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 | |
| Serializable(可串行化) | |
| 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个 | |
| 级别,可能导致大量的超时现象和锁竞争。 | |
| References: http://xm-king.iteye.com/blog/770721 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| OAuth 2.0 的基本流程 | |
| OAuth 2.0 相对于1.0的主要改进 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| TCP连接是面向连接的,所谓的面向连接就是,当计算机双向通信时必需先建立连接,然后才能进行数据的传输,最后还要拆除连接。而同在一个 | |
| 网络层的UDP传输,是面向非连接的传输,也不是可靠的。 | |
| 位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急) | |
| Client <------------> Server | |
| ->SYN=j | |
| SYN=J+1&ACK=K<- | |
| ->ACK=K+1 | |
| 实例: | |
| IP 192.168.1.116.3337 > 192.168.1.123.7788: S 3626544836:3626544836 | |
| IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837 | |
| IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1 | |
| 第一次握手:192.168.1.116发送位码syn=1,随机产生seq number=3626544836的数据包到192.168.1.123,192.168.1.123由SYN=1知道 | |
| 192.168.1.116要求建立联机; | |
| 第二次握手:192.168.1.123收到请求后要确认联机信息,向192.168.1.116发送ack number=3626544837,syn=1,ack=1,随机产生seq=1739326486 | |
| 的包; | |
| 第三次握手:192.168.1.116收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确, | |
| 192.168.1.116会再发送ack number=1739326487,ack=1,192.168.1.123收到后确认seq=seq+1,ack=1则连接建立成功。 | |
| 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来 | |
| 终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭 | |
| 的一方将执行主动关闭,而另一方执行被动关闭。 | |
| Client <------------> Server | |
| -->FIN | |
| ACK<-- | |
| CLOSE< | |
| FIN<-- | |
| -->ACK | |
| >CLOSE | |
| ======================= | |
| CLOSED: 这个没什么好说的了,表示初始状态。 | |
| LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。 | |
| SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态, | |
| 很短暂,基本 上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。 | |
| 因此这种状态 时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。 | |
| SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态, | |
| 并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。 | |
| ESTABLISHED:这个容易理解了,表示连接已经建立了。 | |
| FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是: | |
| FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。 | |
| 而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马 上回应ACK报文,所以 | |
| FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。 | |
| FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方, | |
| 我暂时还有点数据需要传送给你,稍后再关闭连接。 | |
| TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时 | |
| 带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。 | |
| CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先 | |
| 收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收 | |
| 到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么 | |
| 就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。 | |
| CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个 | |
| ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么 | |
| 你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。 | |
| LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到 | |
| CLOSED可用状态了。 | |
| ====================== | |
| 1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢? | |
| 这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。 | |
| 但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上 | |
| 会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文 | |
| 多数情况下都是分开发送的. | |
| 2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态? | |
| 这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样); | |
| 但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未 | |
| 收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Weak references | |
| A weak reference, simply put, is a reference that isn't strong enough to force an object to remain in memory. Weak references | |
| allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do it yourself. | |
| You create a weak reference like this: | |
| ===================================================== | |
| WeakReference weakWidget = new WeakReference(widget); | |
| ===================================================== | |
| and then elsewhere in the code you can use weakWidget.get() to get the actual Widget object. Of course the weak reference | |
| isn't strong enough to prevent garbage collection, so you may find (if there are no strong references to the widget) | |
| that weakWidget.get() suddenly starts returning null. | |
| Soft references | |
| A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. | |
| An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next | |
| garbage collection cycle, but an object which is softly reachable will generally stick around for a while. | |
| SoftReferences aren't required to behave any differently than WeakReferences, but in practice softly reachable objects are | |
| generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache, such as the | |
| image cache described above, since you can let the garbage collector worry about both how reachable the objects are | |
| (a strongly reachable object will never be removed from the cache) and how badly it needs the memory they are consuming. | |
| Soft Reference 虽然和 Weak Reference 很类似,但是用途却不同。 被 Soft Reference 指到的对象,即使没有任何 Direct Reference, | |
| 也不会被清除。一直要到 JVM 内存不足时且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。 | |
| 如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。我觉得 Soft Reference | |
| 也适合拿来实作 pooling 的技巧。 | |
| Comments: | |
| ----------- | |
| The Sun JRE does treat SoftReferences differently from WeakReferences. We attempt to hold on to object referenced by a | |
| SoftReference if there isn't pressure on the available memory. One detail: the policy for the | |
| "-client" and "-server" JRE's are different: the -client JRE tries to keep your footprint small by | |
| preferring to clear SoftReferences rather than expand the heap, whereas the -server JRE tries to keep your performance | |
| high by preferring to expand the heap (if possible) rather than clear SoftReferences. One size does not fit all. | |
| Strong referebce(强引用): 默认的引用形式,只要引用存在,则永远不会被回收 | |
| Phantom Reference: 虚引用,完全不会对其生存时间构成影响,唯一的目的就是能在这个对象被收集器回收时收到一个系统通知 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
JDK动态代理:
包含一个类和一个接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
参数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException 参数说明: ClassLoader loader:类加载器 Class[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
Ps:类加载器
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器;
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的;
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。