1.序

本人211小硕一枚,经历了春招秋招拿到不少offer,特此把自己从小白到今天的成长经历与面试经历分享与大家,希望能有所帮助。成功上岸腾讯、百度、京东、快手、斗鱼、华为传入接送部、华为公共软件开发部、海康威视、烽火科技、玄武科技等。

2.接近30场面试过程

2.1 快手

快手1面 (60分钟)

1 题目 两数之和
https://blog.csdn.net/weixin_41563161/article/details/104762344
2 Socket协议用什么协议(Socket底层)
https://blog.csdn.net/weixin_41563161/article/details/104779605
3 Java和python的区别
https://blog.csdn.net/weixin_41563161/article/details/104780661
如果让我接触新的语言,我可以接受,并且我会尽快入门,然后参与开发。因为我学习能力还是挺强的。

是以项目驱动技术的,而且我想的是java都没有达到一定的深度,但是如果有需求的我能以最短的时间上手。
4 为什么不全用unity做
因为航天方面的软件有一款公认的也是目前唯一的承认的STK,就是那个传统的客户端,简单的界面,不是全部unity仿真,如果70%的任务全部是非仿真的,所以开发较快,用了WPF;

5组件不是因为svn的问题
是因为模块化,以后需要的话直接拿来复用,因为实验室经常接这种航天类项目,航天类项目的话有一些是可复用的,比如轨道计算,星座覆盖,链路,这些等等。所以用组件的模式
6 java中集合有哪些 Hashmap 和TreeMap区别
7 红黑树的特点
8 mysql数据库索引数据结构 为什么用B+树
9 主键索引和普通索引的区别
10 Arrays.sort()的底层实现
Java Arrays中提供了对所有类型的排序。其中主要分为Primitive(8种基本类型)和Object两大类。
  基本类型:采用调优的快速排序
  对象类型:采用改进的归并排序
源码中的快速排序,主要做了以下几个方面的优化:
  1)当待排序的数组中的元素个数较少时,源码中的阀值为7,采用的是插入排序。尽管插入排序的时间复杂度为0(n^2),但是当数组元素较少时,插入排序优于快速排序,因为这时快速排序的递归操作影响性能。
  2)较好的选择了划分元(基准元素)。能够将数组分成大致两个相等的部分,避免出现最坏的情况。例如当数组有序的的情况下,选择第一个元素作为划分元,将使得算法的时间复杂度达到O(n^2).
  3)根据划分元 v ,形成不变式 v*
 1)当数组大小为 size=7 时 ,取数组中间元素作为划分元。int n=m>>1;(此方法值得借鉴)。
 2)当数组大小size大于7小于等于40时,取首、中、末三个元素中间大小的元素作为划分元。
 3)当数组大小 size>40 时 ,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。
11 文档编写
软件需求书 软件使用说明书 技术说明书 测试报告

12提问的问题
(1)贵司的培养模式
(2)公司内部是否支持内部转岗这样的政策
(3)公司的竞升机制是怎么样的
(4)这是我第一次面试,如果可以,希望您能给我提点建议。如果不方便的话,那就辛苦您花时间来面试我了。谢谢
(5)目前我去了做什么工作。
13为什么没有用到服务式
因为第一个目前没有掌握服务式开发,第二是没有网,那些地方不通网,只能用单机版,而且数据是保密的,不允许外传。
14 如果被问到C#和Vue怎么说
CLR是公共语言运行池。

可能对您要坦白的是前端自从研一接触了4个月之后就没有接触了,因为当时师兄们走,前端差不多也做完了,所以扛起了后台和数据库的任务。前端当时是基于师兄的框架上做的,因为后来因为项目的需要也没有再接触过前端,所以也没有深挖,只是知道怎么用,但是对于自己来说如果有机会进入腾讯的话我可以接受前端,并且自己也喜欢去做前端,相信自己在有后台的基础上可以对前端的开发更加深入。
其实昨天下午收到通知的时候有在想要不要看一下前端的东西,但是想了一下只知道表面的意思没有用的,何况只有一天时间,所以就跟您坦白一下,但是我可以在短时间内入手。

15其它
我喜欢努力极致的做目前所做的事情,就比如大学期间侧重于学生工作,所以就做到了一定的层次然后锻炼了我遇到问题解决问题的能力了。 研究生期间也一样,既然选择了做研究做学问那么就一心把它做好,这也是当时为什么我本科期间基础并不是很好学历也不是很好,但是能在很短的时间内迅速提升起来并且有幸去北京钱学森实验室参与并负责一个项目的原

2.2 腾讯

2.2.1 微信1面 (120分钟)

题目算法
旋转数字的最小数字(注意(1,0,1,1,1))这种情况
合并两个排序链表
二叉搜索树中的第3大个结点 (在面试官提示下进行剪枝)O(1)空间复杂度
1假如没有数据了三次挥手行不行
https://blog.csdn.net/weixin_41563161/article/details/104941167
2 服务器怎么就知道自己没数据了
https://blog.csdn.net/weixin_41563161/article/details/104941167
3 tcp和http有什么联系

HTTP是应用层协议,定义的是传输数据的内容的规范

不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

TCP即传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通讯协议。
HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受计算连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传输给IP层,有它来通过网络将包传送给接收端实体的TCP层。

当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文。之后TCP把数据包传递给IP层,由它来通过网络将包传送给接收端实体的TCP层。
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
https://blog.csdn.net/weixin_41563161/article/details/104941167
4 http请求方法 (深入的)head是干什么的
https://blog.csdn.net/weixin_41563161/article/details/104946065
5 线程如何结束
https://blog.csdn.net/weixin_41563161/article/details/104942044
1使用标志位
这种方法是我尝试终止线程时最初采用的方法,使用起来很方便,原理也很简单,只要在while循环里持续判断一个Boolean变量的值就可以了,一旦满足离开循环的条件,那么就可以离开线程的方法体,结束线程。
2 使用Interrupt方法(中断)

1.线程处于阻塞状态,如使用了sleep,同步锁的wait,socket中的receiver,accept等方法时,会使线程处于阻塞状态。当调用线程的interrupt()方法时,会抛出InterruptException异常。阻塞中的那个方法抛出这个异常,通过代码捕获该异常,然后break跳出循环状态,从而让我们有机会结束这个线程的执行。通常很多人认为只要调用interrupt方法线程就会结束,实际上是错的, 一定要先捕获InterruptedException异常之后通过break来跳出循环,才能正常结束run方法。
2.线程未处于阻塞状态,使用isInterrupted()判断线程的中断标志来退出循环。当使用interrupt()方法时,中断标志就会置true,和使用自定义的标志来控制循环是一样的道理。

3为什么要区分进入阻塞状态和和非阻塞状态两种情况了,是因为当阻塞状态时,如果有interrupt()发生,系统除了会抛出InterruptedException异常外,还会调用interrupted()函数,调用时能获取到中断状态是true的状态,调用完之后会复位中断状态为false,所以异常抛出之后通过isInterrupted()是获取不到中断状态是true的状态,从而不能退出循环,

6 如何保证线程安全性
1、synchronized 锁(偏向锁,轻量级锁,重量级锁)
2、volatile 英[ˈvɒlətaɪl]锁,只能保证线程之间的可见性,但不能保证数据的原子性
3、jdk1.5 并发包中提供的 Atomic 原子类 CAS
4、Lock 锁
5. 多实例、或者是多副本(ThreadLocal): 当使用 ThreadLocal 维护变量时,ThreadLocal
为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副
本,而不会影响其它线程所对应的副本
6.1实现线程同步的几种方式总结
1 通过Object的wait和notify
2 通过Condition的awiat和signal
3 通过一个阻塞队列
4通过同步辅助类CountDownLatch
5 通过同步辅助类CyclicBarrier
7 深拷贝浅拷贝
https://blog.csdn.net/weixin_41563161/article/details/101628243
1哪些地方用到深拷贝 浅拷贝
深拷贝和浅拷贝相当于是对象拷贝,引用拷贝的话是共用同一个对象,地址是相同的,对象拷贝的是创建了新的对象。又分为深拷贝和浅拷贝。

浅拷贝 (浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。"里面的对象“会在原来的对象和它的副本之间共享。

深拷贝 对引用类型的成员变量也进行引用对象的复制 clone() 实现Serializable

8 线程池
9 核心线程是干嘛的
10 voliate 只用它保持线程安全行不行
11 GC
12 Full Gc期间整个虚拟机是什么状态

CMS那一块
13 Java 有哪些锁 p131
在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性。synchronized机制是给共享资源上锁,只有拿到锁的线程才可以访问共享资源,这样就可以强制使得对共享资源的访问都是顺序的,因为对于共享资源属性访问是必要也是必须的。
对象锁和类锁
根据使用方式的不同一般我们会将锁分为对象锁和类锁,两个锁是有很大差别的,对象锁是作用在实例方法或者一个对象实例上面的,而类锁是作用在静态方法或者Class对象上面的。一个类可以有多个实例对象,因此一个类的对象锁可能会有多个,但是每个类只有一个Class对象,所以类锁只有一个。 类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定的是实例方法还是静态方法区别的 。

对象锁 类锁
同一对象 不同加锁的非静态方法 互斥
同一对象 一个加锁 一个不加锁非静态方法 不互斥
不同对象 不同加锁的非静态方法 不互斥

两个对象 两个静态加锁方法 (与对象无关) 互斥
把一个方法写成静态, 一个不静态, 都加锁(静态与非静态方法不共用锁) 不互斥

1可重入锁

2可中断锁
lockInterruptibly()的用法时已经体现了Lock的可中断性。
3公平锁
公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。
非公平锁即无法保证锁的获取是按照请求锁的顺序进行的。这样就可能导致某个或者一些线程永远获取不到锁。
在Java中,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。

4 读写锁
读写锁将对一个资源(比如文件)的访问分成了2个锁,一个读锁和一个写锁。
正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。
ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。
可以通过readLock()获取读锁,通过writeLock()获取写锁。

读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。
https://www.cnblogs.com/aspirant/p/6930436.html

5 自旋锁
如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。

首先是一种锁,与互斥锁相似,基本作用是用于线程(进程)之间的同步。与普通锁不同的是,一个线程A在获得普通锁后,如果再有线程B试图获取锁,那么这个线程B将会挂起(阻塞);试想下,如果两个线程资源竞争不是特别激烈,而处理器阻塞一个线程引起的线程上下文的切换的代价高于等待资源的代价的时候(锁的已保持者保持锁时间比较短),那么线程B可以不放弃CPU时间片,而是在“原地”忙等,直到锁的持有者释放了该锁,这就是自旋锁的原理,可见自旋锁是一种非阻塞锁。

二、自旋锁可能引起的问题:
1.过多占据CPU时间:如果锁的当前持有者长时间不释放该锁,那么等待者将长时间的占据cpu时间片,导致CPU资源的浪费,因此可以设定一个时间,当锁持有者超过这个时间不释放锁时,等待者会放弃CPU时间片阻塞;
2.死锁问题:试想一下,有一个线程连续两次试图获得自旋锁(比如在递归程序中),第一次这个线程获得了该锁,当第二次试图加锁的时候,检测到锁已被占用(其实是被自己占用),那么这时,线程会一直等待自己释放该锁,而不能继续执行,这样就引起了死锁。因此递归程序使用自旋锁应该遵循以下原则:递归程序决不能在持有自旋锁时调用它自己,也决不能在递归调用时试图获得相同的自旋锁。
14 Wait 和notify分别是干嘛的

Object.nofity() 的文档明确说一个随机的线程将被唤醒,但具体情况将由实现者决定,因为Object.nofity()是一个native方法。(具体的jvm来实现)
Condition.signal() 的文档则说一个被选定的线程将被唤醒。

可以清晰的看到notify()方法是按先进先出的顺序唤醒的,即是公平的。本实验在Java 1.8 HotSpot 下测试,可以看出Java 1.8 HotSpot把notify()实现为公平的方式。

15 类加载
16 双亲委派模型

17 Socket如何解决丢包
18 其它 网络通信的方式

heissen,dubbo,webservice,thrift
dubbo
Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 [1] Spring框架无缝集成。
webservice
Web Service是一个平***立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。
Thrift
是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
19 CAS Synchronized Voliate
synchronized
synchronized英[ˈsɪŋkrənaɪzd] 同步代码块的语义底层是基于对象内部的监视器锁(monitor),分别是使用 monitorenter 和 monitorexit 指令完成。其实 wait/notify 也依赖于 monitor 对象,所以其一般要在 synchronized 同步的方法或代码块内使用。monitorenter 指令在编译为字节码后插入到同步代码块的开始位置,monitorexit 指令在编译为字节码后插入到方法结束处和异常处。JVM 要保证每个 monitorenter 必须有对应的 moniorexit。
cas

volatile

2.2.2 腾讯云盘1面(40分钟)

1 打印字节数
https://blog.csdn.net/weixin_41563161/article/details/104993568

2 arraycopy

public class Test6 {
   
    public static void main(String[] args) {
   
        int[] formArray={
   101,102,103,104,105,106};
        int[] toArray={
   201,202,203,204,205,206,207};
        System.arraycopy(formArray, 2, toArray, 3, 2);
        for(int i=0;i<toArray.length;i++){
   
            System.out.println(i+":"+toArray[i]);
        }
    }

    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
   
     // TODO 请完成实现部分
    }

}

3 旋转数组
4 多线程

2.2.3 腾讯一面 PCG 90分钟

1 题目
:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key):如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) : 如果密钥不存在,则写入(设置或插入)其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
评价:对 LRU 机制比较熟悉,算法阐述比较清晰,写代码过程没有像第一题一样的混乱。

解决方案:
//定义链表节点
class Node{
   
int key;
int value;
Node pre;
Node next;
public Node(int key,int value){
   
this.key = key;
this.value = value;
}
}
public class LRUCache{
   
Map<Integer,Node> cacheMap = new HashMap<>();
//定义哈希表
Node head = null;
//定义头节点
Node tail = null;
//定义尾节点
int nodeLength =0;
//容量
//put操作
public int get(int key){
   
if(cacheMap.containsKey(key)){
   
//如果存在的话
Node node =cacheMap.get(key);
removeNode(node);
//进行移除
setHead(node);
//把节点放到首部
return node.value;
//返回节点
}
return -1//不存在返回-1;
}
//移除链表中的节点
public void removeNode(Node node){
   
if(node.pre != null){
   
//如果前节点不为空
node.pre.next = node.next;
}else{
   
//前节点为空
head = node.next;
}
if(node.next != null){
   
//后节点不为空
node.next.pre = node.pre;
}else{
   
后节点为空
tail = node.pre;
}
}
//把节点放到链表的头部
public void setHead(Node node){
   
node.next = head;
node.pre = null;
if(head != null){
   
//如果头结点不为空
head.pre = node;
}else{
   
head = node;
//头结点为空
}
if(tail == null){
   
//如果尾部节点为空
tail = head;
}
}
//put操作
public void put(int key,int value){
   
if(cacheMap.containsKey(key)){
   
//如果包含key的话
Node oldNode = cacheMap.get(key);
//取出旧的值
oldNode.value = value;
//替换旧的值
remove(oldNode);
//移除链表中的旧的值
setHead(oldNode);
//把旧的值放到首部
}else{
   
//不包含的情况
Node newNode = new Node(key,value);
//考虑容量是否足够
if(cacheMap.size() >= nodeLength){
   
//容量不够的话
cacheMap.remove(tail.key);
//哈希表去掉尾部值
remove(tail);
//删除链表尾部
setHead(newNode);
//把新的链表放到头部位置
}else{
   
setHead(newNode);
容量够的话
}
cacheMap.put(key,newNode);
//放入到hashmap中
}
}	
}

2.2.4 腾讯测开1面 (80分钟)

1封装继承多态

2 GC
3两个链表的公共入口
时间复杂度 m+n
4三次握手四次挥手中

细节
当第一个没有收到的话,那么情况是什么样子的呀
https://blog.csdn.net/weixin_41563161/article/details/105479415
5数据库索引
6引擎
7连接池

连接池的应用场景
8 char() varchar()区别
varchar(50) 是什么意思
9 垃圾回收
10 TCP 与UDP

2.2.5 腾讯2面(40分钟)

1 关系型数据库 非关系型数据库
https://blog.csdn.net/weixin_41563161/article/details/105619871

3查询语句 排序语句
“select * from say order by id desc limit 100,15”

4TreeMap优势
先说说红黑树的五点

1 红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。

2红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。

3结合TreeMap
TreeMap 实现了 SortMap 接口,其能够根据键排序,默认是按键的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时得到的记录是排过序的,TreeMap 取出来的是排序后的键值
4 红黑树占用的内存更小(仅需要为其存在的节点分配内存),而Hash事先应该分配足够的内存存储散列表,即使有些槽可能弃用
5堆和栈的区别

栈:主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。

堆内存主要作用是存放运行时创建(new)的对象。
(主要用于存放对象,存取速度慢,可以运行时动态分配内存,生存期不需要提前确定)

堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。

C++

6内存分配默认是多少

7Jvm是干什么的
JVM:
JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,它是整个 java实现跨平台的最核心的部分,所有的 java 程序会首先被编译为.class 的类文件,这种类文件可以在虚拟机上执行,也就是说 class 并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。JVM 是 Java 平台的基础,和实际的机器一样,它也有自己的指令集,并且在运行时操作不同的内存区域。 JVM 通过抽象操作系统和 CPU 结构,提供了一种与平台无关的代码执行方法,即与特殊的实现方法、主机硬件、主机操作系统无关。JVM 的主要工作是解释自己的指令集(即字节码)到 CPU 的指令集或对应的系统调用,保护用户免被恶意程序骚扰。 JVM 对上层的 Java 源文件是不关心的

结构和操作系统有关,是运行 Java 程序必不可少的(除非用其他一些编译环境编译成.exe 可执行文件……),JRE 的地位就象一台 PC 机一样,我们写好的 Win32 应用程序需要操作系统帮我们运行,同样的,我们编写的 Java程序也必须要 JRE 才能运行。

JVM是java字节码执行的引擎,还能优化java字节码,使之转化成效率更高的机器指令。
JVM中类的装载是由类加载器和它的子类来实现的,类加载是java运行时一个重要的系统组件,负责在运行时查找和装入类文件的类。
不同的平台对应着不同的JVM,在执行字节码(class文件)时,JVM负责将每一条要执行的字节码送给解释器,解释器再将其翻译成特定平台换将的机器指令并执行,这样就实现了跨平台运行。

内存区域
1,程序计数器
程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,可以理解为是当前线程的行号指示器。它是线程私有(一个线程就有一个程序计数器)的。
2,虚拟机栈
一个线程的每个方法在执行的同时,都会创建一个栈帧(Statck Frame),栈帧中存储的有局部变量表、操作站、动态链接、方法出口等,当方法被调用时,栈帧在JVM栈中入栈,当方法执行完成时,栈帧出栈。
每个线程对应着一个虚拟机栈,因此虚拟机栈也是线程私有的。

栈:主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。

3,本地方法栈
本地方法栈在作用,运行机制,异常类型等方面都与虚拟机栈相同,唯一的区别是:虚拟机栈是执行Java方法的,而本地方法栈是用来执行native方法的,
4,堆区
堆内存主要作用是存放运行时创建(new)的对象。
(主要用于存放对象,存取速度慢,可以运行时动态分配内存,生存期不需要提前确定)

堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。
5,方法区
方法区是各个线程共享的区域,用于存储已经被虚拟机加载的类信息(即加载类时需要加载的信息,包括版本、field、方法、接口等信息)、final常量、静态变量、编译器即时编译的代码等。
8struct 和 c++的类怎么区分
C/C++结构体的区别
C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数。

结构体定义中默认情况下的成员是public,而类定义中的默认情况下的成员是private的。类中的非static成员函数有this指针,(而struct中没有是错误的,一直被误导啊,经过测试struct的成员函数一样具有this指针),类的关键字class能作为template模板的关键字 即template class A{}; 而struct不可以。

C的结构体只是把数据变量给包裹起来了,并不涉及算法。
而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。

C语言中是没有类的概念的,但是C语言可以通过结构体内创建函数指针实现面向对象思想。

8 项目被打断
9 TCP UDP
10垃圾回收
11工作线程
12 Linux 查看进程 创建文件

14游标
游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。

游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;

15存储过程
存储过程(Stored Procedure),计算机用语,是一组为了完成特定功能的SQL语句集,是利用SQL Server所提供的Transact-SQL语言所编写的程序。经编译后存储在数据库中。存储过程是数据库中的一个重要对象,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,存储过程可由应用程序通过一个调用来执行,而且允许用户声明变量 。同时,存储过程可以接收和输出参数、返回执行存储过程的状态值,也可以嵌套调用。

16二叉搜索树的时间复杂度 冒泡排序时间复杂度

17 进程间通信
1 管道

2 消息队列

这种通信方式有缺点吗?答是有的,如果 a 进程发送的数据占的内存比较大,并且两个进程之间的通信特别频繁的话,消息队列模型就不大适合了。因为 a 发送的数据很大的话,意味发送消息(拷贝)这个过程需要花很多时间来读内存。
3共享内存

18 流量控制,拥塞控制

2.2.6 腾讯3面(40分钟)成功上岸“光子工作室”

1如何把大量的文件快速读完

2这个地方整理一下项目是如何讲重点
1 与美国的对比
2 实验室15年的心血
310万代码
4自己的算法部分
5组件解耦部分

2.3 百度

2.3.1 百度1面(70分钟)

1单例模式 (解释)
2Volatile
3 synchronized

3那个里面的锁能不能用this替代 (类锁和对象锁)

/**
* 静态内部类,使用双重校验锁,线程安全【推荐】
*/
public static class Singleton7 {
private volatile static Singleton7 instance = null;

    private Singleton7() {

    }

    public static Singleton7 getInstance() {
        if (instance == null) {
            synchronized (Singleton7.class) {
                if (instance == null) {
                    instance = new Singleton7();
                }
            }
        }

        return instance;
    }
}

4 lock
5 aqs
6 线程池以及调优
7 4种线程池以及为什么不建议用
8 快排
9 根据先序中序求后序

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
   
        if(pre == null || in == null){
   
            return null;
        }
      return  helper(pre,in,0,0,pre.length-1);
        
    }
    public TreeNode helper(int [] pre,int [] in,int preStart,int inStart,int inEnd){
   
        if(inStart > inEnd){
   
            return null;
        }
        int temp = pre[preStart];
        TreeNode root = new TreeNode(temp);
        int index =0;
        for(int i =inStart;i<=inEnd;i++){
   
            if(in[i] == temp){
   
                index = i;
                break;
            }
        }
        TreeNode leftNode = helper(pre,in,preStart+1,inStart,index-1);
        TreeNode rightNode = helper(pre,in,preStart+index+1-inStart,index+1,inEnd);
        root.left = leftNode;
        root.right = rightNode;
        return root;
    }

10数据库整个索引
11虚拟机整个GC以及GC回收器有哪些
12mvcc
13 jvm内存结构
14 java内存模型

15 B+树的分页过程
https://blog.csdn.net/weixin_41563161/article/details/105483950
16 CAS

2.3.2 百度2面(50分钟)

1 3个项目讲一下
2 红黑树
规则1:节点是红色或黑色的;
规则2:根节点是黑色的;
规则3:每个叶子节点都是黑色的空节点(NIL节点);
规则4:每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不可能有两个连续的红色节点);
规则5:从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点;

3 左旋右旋
4集合
5Hashmap的细节(自己复习的不够细)

1
2 全部与1的数进行按位与操作,速度会大大提升。
3
6 树的深度

public static int maxDepth(TreeNode root) {
   
    if (root == null) {
   
        return 0;
    } else {
   
        int left_height = maxDepth(root.left);
        int right_height = maxDepth(root.right);
        return java.lang.Math.max(left_height, right_height) + 1;
    }

7 平衡二叉树

public static boolean isBalanced(TreeNode root) {
   
        if(root == null){
   
            return true;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        int diff = left-right;
        if(diff >1 || diff<-1){
   
            return false;
        }
        return isBalanced(root.left) && isBalanced(root.right);
    }
    public static int maxDepth(TreeNode root) {
   
        if(root == null){
   
            return 0;
        }
 
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        return (left > right) ? (left+1) : (right+1);
    }


1旋转数组
2/**

  • @Auther: liuhaidong
  • Data: 2020/4/7 0007、16:24
  • Description:
  • @version: 1.0
    /
    public class Test24 {
    /
    • 给定一个N*N的整形矩阵Matrix,把这个矩阵顺时针旋转90度,输入(打印)元素值。
    • 例如:
    • 1 2 3 4
    • 5 6 7 8
    • 9 10 11 12
    • 13 14 15 16
    • 输出结果为:
    • 13 9  5 1
      
    • 14 10 6 2
    • 15 11 7 3
    • 16 12 8 4
    • 要求:额外空间复杂度为O(1)
    • */
public static void main(String[] args) {
   
//初始化一个 4*4的整形矩阵,从第一行第一列从左向右,第二行,第三行,直到第四行依次赋值 1,2,...16.
        int[][] matrixDemo=new int[4][4];
        matrixDemo=createMatrix();
        printMatrix(matrixDemo);

        System.out.println();
        //顺时针旋转90度打印
        rotate(matrixDemo);
        printMatrix(matrixDemo);
    }
    //顺时针旋转90度打印
    private static void rotate(int[][] matrix) {
   
        // TODO Auto-generated method stub
        int topRow=0;
        int topCol=0;
        int dowmRow = matrix.length-1;
        int dowmCol = matrix[0].length-1;
        while(topRow <= dowmRow) {
   
            rotateEdge(matrix, topRow++, topCol++, dowmRow--,dowmCol--);
        }
    }
    //顺时针旋转90度打印
    private static void rotateEdge(int[][] matrix, int topRow, int topCol, int dowmRow, int dowmCol) {
   
        // TODO Auto-generated method stub
        int times=dowmRow-topRow;
        // timies就是总的组数
        int temp=0;
        for(int i=0; i!=times;i++) {
   
            //一次循环就是一组调整
            temp=matrix[topRow][topCol+i];
            matrix[topRow][topCol+i]=matrix[dowmRow-i][topCol];
            matrix[dowmRow-i][topCol]=matrix[dowmRow][dowmCol-i];
            matrix[dowmRow][dowmCol-i]=matrix[topRow+i][dowmCol];
            matrix[topRow+i][dowmCol]=temp;
        }
    }

    //生成矩阵
    private static int[][] createMatrix() {
   
        // TODO Auto-generated method stub
        int matrix[][]=new int[4][4];
        int k=1;
        for(int i=0;i<4;i++) {
   
            for(int j=0;j<4;j++) {
   
                matrix[i][j]=k;
                k++;
            }
        }
        return matrix;
    }
    //顺序打印矩阵元素
    private static void printMatrix(int[][] matrix) {
   
        for(int i=0;i<4;i++) {
   
            for(int j=0;j<4;j++) {
   
                System.out.print(matrix[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

3项目

2.4 美团

2.4.1 美团1面(65分钟)

1 A题
两个顺序链表
循环打印矩阵
2Linux系统命令 部署服务器
3TCP 三次握手四次挥手何时建立连接 第三个丢了怎么办
有什么缺陷 怎么解决
1 序列号seq:

占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生,给字节编上序号后,就给每一个报文段指派一个序号,序列号seq就是这个报文段中的第一个字节的数据编号。

2 确认号ack:

占4个字节,期待收到对方下一个报文段的第一个数据字节的序号,序列号表示报文段携带数据的第一个字节的编号,而确认号指的是期望接受到下一个字节的编号,因此挡墙报文段最后一个字节的编号+1即是确认号。

Server 端

第三次的ACK在网络中丢失,那么Server 端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。

而Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5.

如果重发指定次数之后,仍然未收到 client 的ACK应答,那么一段时间后,Server自动关闭这个连接。

4为什么要重写equal() HashCode()
总结:默认情况下也就是从超类Object继承而来的equals方法与‘==’是完全等价的,比较的都是对象的内存地址,但我们可以重写equals方法,使其按照我们的需求的方式进行比较,如String类重写了equals方法,使其比较的是字符的序列,而不再是内存地址。

6集合怎么选pojo

7索引的坏处

8TreeMap什么时候用

9进程 线程 协程之间的
https://blog.csdn.net/weixin_41563161/article/details/104983775

10你的职业规划是什么
我喜欢就是大家一起为了一件事或者一个目标把它从0 到1实现的过程,特别特别享受整个过程。把一件事做好,做到自己认为满意为主。所以自己将来的职业规划就是在一个很好的团队里面然后大家为了一个同一个目标而努力。

2.4.2 美团2面 (70分钟)

1题目
1 二分查找

二分查找,有序数组,找到返回下标,未找到返回-1

2最好一样
给出一个序列包含n个正整数的序列A,然后给出一个正整数x,你可以对序列进行任意次操作的,每次操作你可以选择序列中的一个数字,让其与x做按位或运算。你的目的是让这个序列中的众数出现的次数最多。
请问众数最多出现多少次。
输入描述
输入第一行仅包含两个正整数n和x,表示给出的序列的长度和给定的正整数。(1<=n<=100000,1<=x<=1000)
接下来一行有n个正整数,即这个序列,中间用空格隔开。(1<=a_i<=1000)
输出描述
输出仅包含一个正整数,表示众数最多出现的次数。
示例1
输入
5 2
2 1 3 2 5
输出
2
说明
例如如果序列中所有数字都不修改时,众数为3,3出现的次数为2,如果我们把两个3都做如题操作,序列会变为1,1,1,2,5,此时众数为1,出现次数为3,所以我们选择后者方案,输出众数出现的次数,即3。

2 链地址法和开放地址法 各自优势对比

3 (解释)磁盘预读性原理

4 用hashmap实现范围查询
Hashmap + 双向链表 找到两个节点,然后直接取中间的这一段
5主讲项目(项目中的难点,解决,优化)
6 分布式建议学习一下
7 数据库整个讲了一遍(索引 事务 引擎 两阶段锁 MVCC)
8 hashmap底层(插入 红黑树 8 扩容 等等全部细节)
9垃圾回收处理

10 CMS G1 GCRoot StopWord (如何解决CMS的碎片问题 包括改进)

2.4.3 美团3面 (60分钟)

1选课系统如何设计 事务 字段 表
2
3课程表和学生表是分开的。所以设计的时候学生选课的时候要开启事务,如果课程没了怎么办。

2切蛋糕递归题目

public class Main3 {
   
    public static void main(String[] args) {
   
        System.out.println(getNum(3));
    }
    static int dp = 1;
    public static int getNum(int n) {
   
        if (n == 1) {
   
            return 1;
        }
        dp = 1 + getNum(n - (n / 3 + 1));
        return dp;
    }
}

3数组中最大值

public class Main3 {
   
    public static void main(String[] args) {
   
        int[] nums = {
   2,8,9,3,4,1};
        System.out.println(getMax(nums,6));
    }
    static int res = Integer.MIN_VALUE;
    public static int getMax(int[] nums, int n) {
   
        if (n == 0) {
   
            return res;
        }
        res = Math.max(nums[n-1], getMax(nums, n - 1));
        return res;
    }
}

4 Scoket sendMessage消息传递函数怎么设计的
4选你的最大优势特点
第一
1自己对于目标的实现度很强 责任心 不是自己的工作全部主动去负责
第二
2 快速成长能力 项目中从0到撑起一个项目 (就跟部门的那个人说的)
第三
3自己的为人处世 这一块我学生工作让自己提升起来,能很好的处理人际关系与事情。
5前两面的最大的一个感受
所以一定要好好准备一下之前的一个问题

7 计算机网络Socket TCP IP之间的区别
8 为什么想要来美团

其实这个问题的话是我自己的一个目标吧,就比如您也看到我的简历了,本科是长江大学的,但是我不甘心,不像是芸芸众多大学生一样每天游戏一样的生活,所以每天砥砺前行,所以不断的读书,一点一点的进步,一步一步走到了学生主席的位置。后来发现在这个环境下无法再有很大的提升,于是自己想着换个平台吧,所以就考到了地大,到了地大发现原来高手这么多,自己是最菜的一个,所以又重新开始,一步一步向前爬,终于在自己的努力下又获得了一点点小成绩,独立负责项目,现在呢,我想要进美团的原因一样,我想要和更厉害的人在一起,我渴望这种进步,我从不畏惧困难,。一个人的成长不就是从一个舒服的环境到另一个更高的平台前进吗??

2.5 阿里1面(60分钟)

A题
1 替换字符串中的通配符?
/*

  • 给定字符串(合法字符只包括0,1,?),替换字符串中的通配符?为0或者1,生成所有可能的字符串。
  • Input str = “1??0?101”
  • Output:
  •   10000101
    
  •   10001101
    
  •   10100101
    
  •   10101101
    
  •   11000101
    
  •   11001101
    
  •   11100101
    
  •   11101101
    

*/

其实这道题用到了深度优先搜索,深度优先搜索呢是这样的,建立在图上的数据结构,是图的搜索算法之一,在深度优先搜索算法中,每条边最多会被访问两次,一次是遍历,一次是回退。回溯的过程,然后所以时间复杂度是 O(E)。 它的空间复杂度因为递归函数调用不会栈的深度不会超过顶点的个数,所以深度优先搜索的空间复杂度为 O(V)。

public class Test22 {
   
        public static void main(String[] args){
   
            String s = "1??0?101";
            System.out.println(generateString(s));
        }
        private static List<String> result;
        private static char[] sc;

        public static List<String> generateString(String s) {
   
            result = new ArrayList<>();
            sc = s.toCharArray();
            helper(0);
            return result;
        }

        private static void helper(int index) {
   
            if (index == sc.length) {
   
                result.add(new String(sc));
                return;
            }
            if (sc[index] == '?') {
   
                sc[index] = '0';
                helper(index + 1);
                sc[index] = '1';
                helper(index + 1);
                sc[index] = '?';
            } else {
   
                helper(index + 1);
            }
        }

    }

/*
给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入: 1 1
/ \ /
2 3 2 3

    [1,2,3],   [1,2,3]

输出: true
示例 2:

输入: 1 1
/
2 2

    [1,2],     [1,null,2]

输出: false
示例 3:

输入: 1 1
/ \ /
2 1 1 2

    [1,2,1],   [1,1,2]

输出: false
*/

/**

  • Definition for a binary tree node.
  • public class TreeNode {
  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }
    */

class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && p == null) {
return true;
}
if (p == null || q == null) {
return false;
}

    if (p.val != q.val) {
    	return false;
    }
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}

}

1垃圾回收
2 集合
3项目(难点解决)
4看过java方面的书籍
5编码的艺术(阿里人的一丝不苟)

2.6 CVTE (60分钟)

1 100万数据封装继承多态
讲一下电厂项目的表设计
索引
B+树
索引失效
联合索引 8个表如何写在一个Sql里面
如何保持事务的 (MVCC binlog 一二三四级协议)
如何快速生产100万个对象(除了多线程 克隆)
输入url TCP 数据格式 怎么渲染的

HTTP https
ArrayList 底层 扩容
HashMap CurrentHashMap hashMap 1.7 1.8区别
封装继承多态
内存溢出了怎么办
字符中如何找到第四大重复的数
线程同步,线程安全 线程通信
线程池
有8条线程结束后唤醒主线程
生产100万个对象如何保证安全的。

死锁3连:你觉得什么是死锁 -》怎么找到死锁 -》 怎么避免死锁 ====== 就差让我写个死锁了。。。。

2.7

2.7.1 网易雷火(1面 40分钟)

1 时间复杂度 (重点)

快速排序

2 概率题目

3项目

2.7.2 网易雷火(2面 40分钟)

1 硬币的分配 尽可能的分成两堆
https://blog.csdn.net/weixin_41563161/article/details/105645882
2算法里面01的个数相等
https://blog.csdn.net/weixin_41563161/article/details/105635697
3完全二叉树最少和最多是多少(重点)

4UDP实现TCP(重点)

5二叉树的序列化
https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/javaceng-xu-bian-li-dfsqian-xu-bian-li-by-ggyzzz/

https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/

https://leetcode-cn.com/problems/serialize-and-deserialize-bst/
6项目

2.8 字节跳动

2.8.1面 (50分钟)

1概率

设甲先抛。设甲胜率为x。则第一次甲抛了反面后,乙胜率为x,从而甲胜率+乙胜率=x+0.5x=1,从而x=2/3。

2 握手方式
12n个人围成一圈, 两两握手, 形成n条握手的线段, 线段没有交点, 一共多少种握手方式?

#include <iostream>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
typedef long long LL;
const LL mod=1e9+7;
using namespace std;
const int N=1e2+100;
int a[N][N];
//a[i][0]存的是第i个数字的长度,a[i][1]是数字的最低位,a[i][ a[i][0] ]是数字的最高位
void init()
{
   
    mem(a,0);
    a[0][0]=1;
    a[0][1]=1;
    a[1][0]=1;
    a[1][1]=1;
    for(int i=2; i<=100; i++)
    {
   
        int z=4*i-2,r=0,p;
        a[i][0]=a[i-1][0];
        for(int j=1; j<=a[i][0]; j++)//乘以(4*i-2)
        {
   
            p=a[i-1][j]*z+r;
            a[i][j]=p%10;
            r=p/10;
        }
        while(r)
        {
   
            a[i][++a[i][0]]=r%10;
            r=r/10;
        }
        z=i+1,r=0;
        for(int j=a[i][0]; j>=1; j--)//除以(i+1)
        {
   
            p=(r*10+a[i][j])/z;
            r=(r*10+a[i][j])%z;
            a[i][j]=p;
        }
        while(a[i][a[i][0]]==0) a[i][0]--;//去掉最高位的0
    }
}
int main()
{
   
    init();
    int n;
    while(~scanf("%d",&n)&&n!=-1)
    {
   
        for(int j=a[n][0]; j>=1; j--)
            printf("%d",a[n][j]);
        printf("\n");
    }
}

3随机数生成方式
现在有一个随机数生成器, 1/3概率生成1, 2/3生成0, 如何基于这个生成器, 得出一个1/2概率是0, 1/2概率是1的生成器?

初看确实有点头晕,也没什么思路。但是仔细想想为什么生成0和1的概率均为1/2,我们可以看成是生成0和1的概率是均等的。这样想之后,似乎就没那么不好理解了。

原始的随机数生成器,生成0 的概率为p,生成1的概率为1-p,那么怎么构造才能使得生成0和1的概率相等呢。或者说有两个独立的事件的概率是相等呢?

这样来做一下,让该随机数生成器生成两个数,那么序列是00,01,10,11概率分别为 pp,p(1-p),(1-p)p,(1-p)(1-p)

很明显,这四种情况中存在两个独立的事件概率是相等。也就是01和10,那么我把01看成是0,10看成是1,那么他们输出的概率均为p(1-p),其他的情况舍弃。这样就得到了0和1均等生成的随机器了。

思维在扩展一下,生成1,2,…n的概率分别是1/n,也就是均等的。那么我们可以想怎么生成一个序列,里面有n个独立时间,概率是相等。而且我们能够猜测到这些概率的形式为 px*(1-p)y,如果要相等,那么x必须等于y.这样就说明了序列中0和1的个数是相等的。而且这样的情况必须有多与n个才行。

数学表示就是 C(2x,x) >=n ,我们只需要知道x就能够知道序列要多长了。而且中间必定有超过n个概率为{p(1-p)}^x不相等序列。

问题就可以解决了。

其实卡我的问题是,丢掉那些多余的,只要n个等概率的序列,是否真的是等概率的(最终输出)。
4 http的问题

影响http的最大请求数

302 303区别

6数字在排序数组中出现的次数

7MVCC

8java实现开根号

9输入url会怎么样
10 索引的底层
11 如何实现事务的呢

2.8.2 字节跳动二面(40分钟)

1 项目

2 N阶台阶,每次走一步或两步,计算共有多少种走法,并将每种走法打印出来。
加粗样式https://blog.csdn.net/weixin_41563161/article/details/105786299

2.9 斗鱼

2.9.1 斗鱼服务端一面(70分钟)

1主键索引普通索引区别
2 LRU lru-k Arc
https://blog.csdn.net/weixin_41563161/article/details/105673506
3项目
5B+树

2.9.2 斗鱼二面(50分钟)成功上岸

1 事务控制 MVCC
1 mvcc用在rr和rc的普通读 也叫快照读
就是你普通select什么都不加,就是普通读
区别是rc(最近一次被Commit) rr(事务开始之前的最后一次Commit)

2 不加锁,对应的是普通读,实现用的是mvcc 也叫一致性非锁定读

加锁了,叫一致性锁定读,(当前读)就要靠各种锁来实现了,你再去讲三种行锁

2 消息队列
计算机网络模块的缓存消息队列
3fastJson

4高性能服务器

5网络的消息队列模块,相当于操作系统的内核部分
6SYN Flood攻击
7设计模式
8网络

2.10 京东

2.10.1面(45分钟)(管培生)

1 假如有一天突然发现在月球上,你怎么办

2读过啥书,有啥感受

3 项目

4评价一下你手机上的一个app

2.10.2 京东二面(60分钟) 成功上岸

1 项目
2 Socket
3 高性能服务器开发
4 TCP
5网络五层
6数据库 事务
7类加载
8线程通信方式
https://blog.csdn.net/weixin_41563161/article/details/104616099

9 共享内存是哪张方式
共享内存
因为线程与父进程的其他线程共享该进程所拥有的全部资源。所以创建的线程本来就已经实现共享内存。但要注意的是,在操作共享资源时要注意实现同步机制,确保线程安全。
通过实现Runnable接口实现线程的共享变量:
管道流
管道流过程:生产者向管道中输出数据,消费者从管道中读取数据。当然,生产者的管道输出要与消费者的管道输入进行连接。

wait()、notify()、notifyAll()

使用Condeition控制

10 GC

2.11 360 一面(45分钟)

1 数据库

2项目

3redis作用
其实应该从数据结构的角度去答
4Nginx
5 Web容器有哪些

2.12 快手

2.12.1安卓一面(50分钟)

1流量控制拥塞控制是怎么?? 是在路由器阻塞了吗
https://blog.csdn.net/weixin_41563161/article/details/106088167

2 用户和内核态
32位系统只能寻址4G空间,64位则是128G
https://blog.csdn.net/weixin_41563161/article/details/106070705
3换页
https://blog.csdn.net/weixin_41563161/article/details/105106416
https://blog.csdn.net/weixin_41563161/article/details/106071401
4 快速排序
5 TCP UDP
6 项目
7线程创建会有一系列的 底层操作
https://blog.csdn.net/weixin_41563161/article/details/106086897
8 内存模型。比如成员变量 局部变量之间
https://blog.csdn.net/weixin_41563161/article/details/106085393
9 volatiel

10Hashmap 插入的过程
https://blog.csdn.net/weixin_41563161/article/details/104708231
11sleep wait区别

12场景题 下载,打水,分享 设计模式
1 责任链模式 + 策略模式 + 命令模式
1 每个步骤可配置,各个步骤不相耦合,实现调用端一致性——责任链模式
首先,我们看出了,它是以状态为导向的(在Handle方法的判断中)。每个步骤都有一个NextHandler属性,用来配置下一个处理器,这就可以串联他们到一个流程中。大家可以看到每个Handle方法最后都有一个"return;"语句。没错,这里我使用了不完整的责任链模式。也就是一个流程不是一次走结束的,因为它们可能不是一个时间上的连贯,也可能不是一个人走完所有的流程,比如某人负责创建任务单,某人负责分配等。
2 实现每个步骤不同的日志记录方式之——策略模式
看到在组装流程的时候我们同时组装了日志记录的策略。事实上,这里每个流程只对应了一种策略,当然可以为一个流程配置几个日志记录策略啦(修改为List,然后在处理器的Log方法中依次调用)。
3 处理数据库处理逻辑调用端的一致性——命令模式
https://blog.csdn.net/yanghua_kobe/article/details/7182888
2 状态模式
http://www.gxitsky.com/2019/12/15/springboot-app-51-workflow-state/
13分组交换和电路交换的区别

https://blog.csdn.net/weixin_41563161/article/details/106087162
14类锁和对象锁
https://blog.csdn.net/weixin_41563161/article/details/104918952
15静态方法和非静态方法
静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭。

非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。

非静态方法既可以访问静态数据成员 又可以访问非静态数据成员,而静态方法只能访问静态数据成员;
非静态方法既可以访问静态方法又可以访问非静态方法,而静态方法只能访问静态数据方法。

2.12.2 快手安卓二面

1 线程池

2 两两反转链表
https://blog.csdn.net/weixin_41563161/article/details/105982771
3 https

4 操作系统里面的软中断硬中断
https://blog.csdn.net/weixin_41563161/article/details/106066862
6DNS是单条消息吗 用的什么协议
https://blog.csdn.net/weixin_41563161/article/details/106069473
https://blog.csdn.net/weixin_41563161/article/details/104896247
7线程池以及java提供的线程 如何停止一个线程
1.线程处于阻塞状态,如使用了sleep,同步锁的wait,socket中的receiver,accept等方法时,会使线程处于阻塞状态。当调用线程的interrupt()方法时,会抛出InterruptException异常。阻塞中的那个方法抛出这个异常,通过代码捕获该异常,然后break跳出循环状态,从而让我们有机会结束这个线程的执行。
2.线程未处于阻塞状态,使用isInterrupted()判断线程的中断标志来退出循环。当使用interrupt()方法时,中断标志就会置true,和使用自定义的标志来控制循环是一样的道理。
8docker

9堆和栈
堆内存
1.什么是堆内存?
堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时候,就会在堆内存中开辟一段空间给它,用于存放。
2.堆内存的特点是什么?
第一点:堆其实可以类似的看做是管道,或者说是平时去排队买票的的情况差不多,所以堆内存的特点就是:先进先出,后进后出,也就是你先排队,好,你先买票。
第二点:堆可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,但缺点是,由于要在运行时动态分配内存,存取速度较慢。
3.new对象在堆中如何分配?
由Java虚拟机的自动垃圾回收器来管理
栈内存‘
主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。
1.什么是栈内存
栈内存是Java的另一种内存,主要是用来执行程序用的,比如:基本类型的变量和对象的引用变量
2.栈内存的特点
1栈内存就好像一个矿泉水瓶,像里面放入东西,那么先放入的沉入底部,所以它的特点是:先进后出,后进先出
2存取速度比堆要快,仅次于寄存器,栈数据可以共享,但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性
3.栈内存分配机制
栈内存可以称为一级缓存,由垃圾回收器自动回收
4.数据共享

10 垃圾回收
11 亿个数字找出前1000大的数字
Hash分为多个文件,用算出前1000大的数,然后构建小顶堆进行排序

首先建立大顶堆,堆的大小为数组的个数,即为 20,把每个数组最大的值存到堆中。
接着删除堆顶元素,保存到另一个大小为 500 的数组中,然后向大顶堆插入删除的元素所在数组的下一个元素。
重复上面的步骤,直到删除完第 500 个元素,也即找出了最大的前 500 个数。

2.13 交通银行面试(35分钟)

1 项目
2如何判断链表成环
3 事务隔离级别
4 空指针异常
https://blog.csdn.net/weixin_41563161/article/details/106055044
5形参和实参
https://blog.csdn.net/weixin_41563161/article/details/106054708
6 按位与和是否一致 && &
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&&还具有短路度的功能,即如果第一个表达式为false,则不问再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将答&&改为&,则会抛出NullPointerException异常。If(x<mark>33 & ++y>0) y会增长,If(x</mark>33 && ++y>0)不会增长
&还可内以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个容整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

7 按照年龄降序排序
8https 和http区别 http1.0 与http1.1区别
9 网络七层 以及每一层协议
10线程池
11Wait与sleep区别

2.14 华为传入接送

2.14.1 华为一面(47分钟)

1 项目
2 设计模式

2.14.2 华为二面(47分钟)

1 项目

2设计模式

3 读书

4心理咨询师

2.15 网易互联网1面(60分钟)

1中序遍历打印二叉树
​​​
​​
面试官不建议用stack 底层是vector

2 java异常
https://blog.csdn.net/weixin_41563161/article/details/105567062
3输入网址之后解析的过程
https://blog.csdn.net/weixin_41563161/article/details/105570486

2.16 微众银行1面(36分钟)

1CAS 底层

2项目

3如何避免脏读

4银行的看法

3. 语录

面试的时候说自己有心理咨询正式,大学期间了4年教育学心理学,对这些方面特别喜欢,而不单单是写出软件来,是真心的热爱,之前在抖音上看到这个消息的时候就想着我就一定要进贵公司,相当于把自己的爱好和专业结合在一起

另一个方面虽然自己的起点低,本科学历不是很好,但是我喜欢努力极致的做目前所做的事情,就比如大学期间侧重于学生工作,所以就做到了一定的层次然后锻炼了我遇到问题解决问题的能力了。 研究生期间也一样,既然选择了做研究做学问那么就一心把它做好,这也是当时为什么我本科期间基础并不是很好学历也不是很好,但是能迅速提升起来并且有幸去北京钱学森实验室参与并负责一个项目。

我们团队为什么要你?
1 自己的性格以及氛围的感染力
2 自己对人以及对事情的责任心,不会单从所做的事情考虑,也就是不会说是仅仅把自己的一份责任工作完成就行了,特别喜欢大家一起把一件事做成做好的感觉,这个也是之前大学学生干部以及研究生期间负责项目培养的。
3 遇到问题解决问题的能力,我曾看到就阿里文化“拥抱变化”,我是特别不惧怕变化,自己的适应性能力很强,很喜欢挑战。让自己很兴奋。
4 心理学
自己的缺点?
1 重拾原来读书的感觉,尤其是心理学的方面
2 可能有些不规律。就是在某一段时间内如果是自己在能力很差或者觉得不足以让自己对团队有产出的情况下不会像之前那样,去看书,去锻炼,去和朋友多谈生活,只是全部的时间去做那个事情,所以别人有时候会经常说我这个问题,就是叫我出去不会出去。吃饭那些只是应付一下,没有任何娱乐活动,可能是自己还没有成家吧,之后应该会调节起来,而且我相信我进了阿里的话在几年内技术提升起来这种会慢慢好起来。

公众号地址

博客地址https://blog.csdn.net/weixin_41563161

掘金https://juejin.cn/user/2814360172369271

知乎https://www.zhihu.com/people/hai-kuo-tian-kong-63-38-21

技术交流群

QQ

微信