腾讯软件开发-后台开发实习生-一面凉经

1.自我介绍

2.介绍论文的具体内容

3.java回收机制,怎么知道他是需要回收的,如何回收,什么时候回收

怎么判断需要回收:

a.死亡对象:

引用计数法

可达性分析

可以作为根:

GC Roots 的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈(Native 方法)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 所有被同步锁持有的对象

即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。

b.废弃常量

假如在字符串常量池中存在字符串 "abc",如果当前没有任何 String 对象引用该字符串常量的话,就说明常量 "abc" 就是废弃常量,如果这时发生内存回收的话而且有必要的话,"abc" 就会被系统清理出常量池了。

c.无用类

类需要同时满足下面 3 个条件才能算是 “无用的类” :

  • 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
  • 加载该类的 ClassLoader 已经被回收。
  • 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

回收时机:

a.堆内存满时候触发GC

当 eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC.

 老年代满了:full GC

b.当应用程序空闲时,即没有应用线程在运行时,GC会被调用。

如何回收:

1.回收算法:

标记-清除,标记-复制,标记-整理

分代回收

在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。

而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集

2.垃圾收集器

serial收集器:

新生代采用标记-复制算法,老年代采用标记-整理算法

parNew:

ParNew 收集器其实就是 Serial 收集器的多线程版本

Parnew scavenge:更关注吞吐量

Parallel Scavenge 收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量

CMS:

收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用

它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。

  • 初始标记: 暂停所有的其他线程,并记录下直接与 root 相连的对象,速度很快 ;
  • 并发标记: 同时开启 GC 和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为用户线程可能会不断的更新引用域,所以 GC 线程无法保证可达性分析的实时性。所以这个算法里会跟踪记录这些发生引用更新的地方。
  • 重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短
  • 并发清除: 开启用户线程,同时 GC 线程开始对未标记的区域做清扫。

从它的名字就可以看出它是一款优秀的垃圾收集器,主要优点:并发收集、低停顿。但是它有下面三个明显的缺点:

  • 对 CPU 资源敏感;
  • 无法处理浮动垃圾;
  • 它使用的回收算法-“标记-清除”算法会导致收集结束时会有大量空间碎片产生。

G1收集器

1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征.

被视为 JDK1.7 中 HotSpot 虚拟机的一个重要进化特征。它具备一下特点:

  • 并行与并发:G1 能充分利用 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 java 程序继续执行。
  • 分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但是还是保留了分代的概念。
  • 空间整合:与 CMS 的“标记-清理”算法不同,G1 从整体来看是基于“标记-整理”算法实现的收集器;从局部上来看是基于“标记-复制”算法实现的。
  • 可预测的停顿:这是 G1 相对于 CMS 的另一个大优势,降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内。

G1 收集器的运作大致分为以下几个步骤:

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来) 。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。

4.进程和线程区别,什么时候用线程,什么时候用进程

区别

多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)**资源,但是每个线程有自己的程序计数器、虚拟机栈** 和 本地方法栈。

总结: 线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。

证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法栈是线程私有的

程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。

堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (几乎所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

5.线程池进程池

6.tcp和udp区别,tcp为什么是可靠的,tcp一定能保证对方收到嘛,怎么让udp变得可靠

区别:

UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等

TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。

可靠性:

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  4. TCP 的接收端会丢弃重复的数据。
  5. 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  6. 拥塞控制: 当网络拥塞时,减少数据的发送。
  7. ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  8. 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

TCP三次握手最后的ACK丢失:

如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。 Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5。 如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。 但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包(用于强制关闭tcp连接)响应,方能感知到Server的错误。

TCP一定是可靠的吗:

不一定,一种机端情况,收到后还没被应用程序拿走就崩溃了,网络断开,主机崩溃,无论TCP如何努力,都无法将数据传给对方

TCP确认一直丢失但内容服务器收到了:

如果收到了更序号的确认则不用重传了,否则超时重传

当发送一个数据段时,同时启动连接的定时器,如果在定时器超时前确认到达,则记录所需要的时间(M),并修正[2]  RTT的值,如果定时器超时前没有收到确认,则将RTT的值增加1倍。

UDP怎么变得可靠:

实现确认机制、重传机制、窗口确认机制,实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。

那么必须实现如下功能:

发送:包的分片、包确认、包的重发

接收:包的调序、包的序号确认

7.快速排序原理,最糟糕情况复杂度,为什么

 一个基准,左右两个哨兵,和基准交换,递归左右

时间复杂度:最好情况O(n*logn)——Partition函数每次恰好能均分序列,其递归树的深度就为.log2n.+1(.x.表示不大于x的最大整数),即仅需递归log2n次; 最坏情况O(n^2),每次划分只能将序列分为一个元素与其他元素两部分,只有左子树或者右子树

8.mysql事务是怎么实现的,断电复原机制

https://www.cnblogs.com/ffdsj/p/12266539.html

总的说来实现事务采取了哪些技术以及思想?原子性使用 undo log ,从而达到回滚;持久性:用 redo log,从而达到故障后恢复;隔离性使用锁以及MVCC,运用的优化思想有读写分离,读读并行,读写并行;一致性:通过回滚,以及恢复,和在并发环境下的隔离做到一致性

使用MVCC(多版本并发控制)。InnoDB为每行记录添加了一个事务ID,每当修改数据时,将当事务ID写入。
在读取事务开始时,系统会给事务一个当前版本号(事务ID),事务会读取版本号<=当前版本号的数据,这时就算另一个事务插入一个数据,并立马提交,新插入这条数据的版本号会比读取事务的版本号高,因此读取事务读的数据还是不会变。

7.开放问题:QQ发送消息如何得到反馈对方是否收到

8.算法题:十六进制转十进制,如果是负数怎么处理

原文地址:https://www.cnblogs.com/jieyi/p/14448191.html