ArrayList和LinkedList的区别?
1 二者的区别
底层数据结构:
ArrayList底层是通过动态数组实现的
LinkedList底层是通过双向链表实现的
随机访问
ArrayList的随机访问get和set要优于LinkedList,因为LinkedList需要遍历移动指针
LinkedList的随机访问时间复杂度是$O(N)$,ArrayList的随机访问时间复杂度是$O(1)$
插入和删除操作
对于插入和删除操作而言,LinkedList并不比ArrayList快,因为LinkedList需要定位到某个插入或者删除的位置(index)也需要$O(N)$的时间复杂度,数据量越大,LinkedList较ArrayList的性能就越低(后面的测试用例可证明这一点)。
2 源码分析2.1 ArrayList中的随机访问、添加和删除部分源码如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445//获取index位置的元素值public E get(int index) { rang ...
使用枚举创建单例对象
1 枚举的基本用法枚举可以有成员方法、成员属性和构造方法。定义一个枚举:
123enum eType{ A,B,C,D;//成员属性}
创建枚举时,$JVM$会自动创建一个继承自java.lang.Enum的类,上面的enum可以看做如下:
1234enum eType extends Enum{ public static final eType A; ...}
对于上面的枚举,可以看做是一个类,类名是eType,其中A、B、C、D可以看做eType的四个实例。但是该实例不需要手动创建,且枚举的构造方法时私有的,所有我们也不能够调用,只能有$JVM$进行调用。
由于A、B、C、D可以看做eType的四个实例,所以可以在enum中定义实例的变量和方法:
1234567891011enum eType{ A,B,C,D; //成员属性 static int value; //静态变量 public static int getValue() { //静态方法 return v ...
java多态总结
1.定义多态:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
2.实现多态的技术称为动态绑定(dynamicbinding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
3.作用消除类型之间的耦合关系。
4.现实中,关于多态的例子不胜枚举比方说按下F1键这个动作,如果当前在Flash界面下弹出的就是AS3的帮助文档;如果当前在Word下弹出的就是Word帮助;在Windows下弹出的就是Windows帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
5.多态存在的三个必要条件
要有继承;
要有重写;
父类引用指向子类对象。
6.多态的好处:
可替换性(substitutability):多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如 ...
java多态面试题
多态分两种:
(1) 编译时多态(设计时多态):方法重载。
(2) 运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。(我们平时说得多的事运行时多态,所以多态主要也是指运行时多态)
运行时多态存在的三个必要条件:
要有继承(包括接口的实现);
要有重写;
父类引用指向子类对象。
多态的好处:
可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeV ...
java多线程中的锁机制
reference
Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。
Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。下面给出本文内容的总体分类目录:
1. 乐观锁 VS 悲观锁乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有此概念对应的实际应用。
先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。
而乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新, ...
TCP/IP协议的三次握手为什么是三次而不是两次?
简单来说,三次握手的目的是为了让双方验证各自的接收能力和发送能力。
第一次握手,A 发送SYN到B,B接收到了后,能确认什么呢?
显然,B能确认A的发送能力和B的接收能力;
第二次握手,B发送SYNACK到A,A接收到后,能确认什么呢?
A能确认B的发送能力和A自己的接收能力,此外,A收到了SYNACK,那么说明前面A发的SYN成功到达B的手中,所以也能确认A自己的发送能力和B的接收能力;至此,A已经确认了双方各自的发送能力和接收能力都是OK的,因此转为ESTABLISHED状态;
第三次握手,A发送ACK到B,B接收后,能确认什么呢?
直接的,B能确认A的发送能力和B的接收能力,另外由于B能收到ACK说明前面发送的SYNACK已经成功被接受了,说明能确认A的接收能力和B的发送能力。
如果使用两次握手,就不能确认上述所说的四种能力,那么就会导致问题。
假定不采用第三次报文握手,那么只要B发出确认,新的连接就建立了。
现假定一种异常情况,即A发出的SYN报文段并没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放后的某个时间才到达B。本来这是一个早已失效 ...
Diffience between Stack and Heap Memery in java ?
reference
Sr. No.
Key
Stack
Heap Memory
1
Basic
Stack memory is used to store items which have a very short life like local variables, a reference variable of objects
Heap memory is allocated to store objects and JRE classes.
2
Ordering
The stack is always reserved in a LIFO (last in first out) order
Heap memory is dynamic allocation there is no fixed pattern for allocating and deallocating blocks in memory
3
Size
We can increase stack memory size by using JVM parameter -XSS
We can inc ...
C++中栈和堆的区别?
在计算机领域,堆栈是一个不容忽视的概念,我们编写的 C 语言程序基本上都要用到。但对于很多的初学着来说,堆栈是一个很模糊的概念。堆栈:一种数据结构、一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈。我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝赐教,这对于大家学习会有很大帮助。
1 数据结构的栈和堆首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。堆和栈都是一种数据项按序排列的数据结构。
2 栈就像装数据的桶或箱子我们先从大家比较熟悉的栈说起吧,它是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。这就如同我们要取出放在箱子里面底下的东西(放入的比较早的物体),我们首先要移开压在它上面的物体(放入的比较晚的物体)。
3 堆像一棵倒过来的树而堆就不同了,堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根 ...
tcp和udp有什么区别?面试题。
1 UDP和TCP的区别
如果是两台主机用UDP协议发送数据,那么他们在任意时刻都可以向对方发送数据,因为UDP是无连接的协议,而如果使用TCP协议进行通信,那么两台主机在通信之前需要进行三次握手建立连接,断开连接时需要进行四次挥手断开连接,TCP协议是面向连接的。(注意:这里所说的连接是指逻辑连接,而不是只物理连接。)
UDP支持单播、多播、广播通信,而TCP只支持单播通信。
UDP是面向应用报文的协议,TCP是面向字节流的协议
也就是说发送方使用UDP协议发送数据时会给该数据报文添加一个UDP头部,接收方接收到该数据报文后去掉其UDP头部直接交给应用进程,中间不做任何操作。
应用进程将需要发送的数据交给下面的TCP协议(传输层),需要发送的数据会首先放在TCP缓存中,TCP协议会根据一定的策略从TCP缓存中提取一定数量的字节并加上TCP头部发送给接收方,接收方收到数据后提取并去掉TCP头部先存放在TCP缓存中,然后将一部分数据交给应用进程。(TCP协议不能保证发送的每个字节都是有意义的,这个需要应用进程进行解析成有意义的字段。)
TCP和UDP都是全双工协议, ...
TCP/IP协议中的拥塞控制面试题
1 TCP拥塞控制
别看放在最后,因为是压轴的知识点,很重要!
1.1 慢启动和拥塞避免(1)慢启动慢启动指先把拥塞窗口cwnd设置为一个最大报文段MSS的数值,发送方在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值,在每经过一个往返时间RTT,拥塞窗口wcnd就加倍。
慢启动的“慢”并不是指cwnd的增长速度慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是探测一下网络的拥塞情况)
(2)拥塞避免算法让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。
(3)步骤
当cwnd < ssthresh时,使用上述的慢启动算法;
当cwnd > ssthresh时,停止使用慢启动算法而改用拥塞避免算法;
当cwnd = ssthresh时,即可使用慢启动算法,也可以使用拥塞避免算法;
1.2 快速重传和快速恢复
当发送方向接收方发送数据时,中间可能会有个别数据包丢失,但是这不是网络拥塞,如果使用上面的慢启动+拥塞避免算法的话, ...