面试经验
1 算法
(1)输出二叉树从左边看过去能看到的所有节点
源代码
public void printLevel(Node root){
Node[] queue = new Node[100];
int top=-1;
int tail=0;
top++;
tail++;
queue[top] = root;
Node fenge = new Node(-1);
queue[tail] = fenge;
tail++;
while(top< (tail-1)){
boolean flag=true;
boolean flag1=true;
while(flag) {
//出队
Node tmp = queue[top];
top++;
if(tmp.value==-1){
flag=false;
continue;
}
if(flag1) {
System.out.print(tmp.value + "\t");
flag1=false;
}
if (tmp.left != null) {
queue[tail++] = tmp.left;
}
if (tmp.right != null) {
queue[tail++] = tmp.right;
}
}
queue[tail++] = fenge;
}
}
思路:主要是二叉树的层次遍历。在输出每一次的时候,只输出第一个即可。
(2)给定一个翻转过的有序数组,找出翻转点的下标,如原数组1,2,3,5,6,7,8,翻转后的数组5,6,7,8,1,2,3
(3)给定一个整数数组,数组中元素无重复。和一个整数limit,求数组元素全排列,要求相邻两个数字和小于limit(深度优先搜索,递归实现)
(4)行列都是有序的二维数组,找出指定元素,扩展到三维数组
(5)给定一个数组,找出这个数组中每一个数右边的第一个比它大的数,比如9 6 5 7 3 2 1 5 9 10,返回的是 10 7 7 9 5 5 5 9 10 N
源代码
public void fun(int[] arr){
int[]ret = new int[arr.length];
for(int i=0;i<ret.length;i++){
ret[i] = 0;
}
int index=-1;
for(int i=arr.length-1;i>=0;i--){
//最后一个数字,右边比他大的数字规定为整型最大值
if(index==-1){
ret[++index] = Integer.MAX_VALUE;
continue;
}else{
if(arr[i]<arr[i+1]){
ret[++index] = arr[i+1];
}else{
//从已经输出的里面找出最近的一个大于arr[i]的数字
int temp = 0;
for(int j=index;j>=0;j--){
if(ret[j]>arr[i]){
ret[++index] = ret[j];
break;
}
}
}
}
}
//逆向输出数组
for(int i=index;i>=0;i--){
System.out.print(ret[i]+"\t");
}
}
(6)找出一个数组的中位数,即左边的数都比它小,右边的都比它大
(7)二叉查找树中,查找与给定数最相近的节点
(8)排序算法,各种排序算法的适用场景
(9)一个整数数组,设计方法,让所有奇数在前,所有偶数在后
源代码
public void sortByJO(int[]arr){
int i=0,j=arr.length-1;
boolean flag = true;
while(i<j && flag){
while(arr[i]%2==1){
i++;
if(i>=arr.length){
flag = false;
break;
}
}
while(arr[j]%2==0 && flag){
j--;
if(j<0){
flag = false;
break;
}
}
if(flag) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
}
思路:跟快速排序一样,分别从数组两端往中间走,奇数放在左边,偶数放在右边。
(10)给定一棵二叉树,编写代码判断这棵树是否左右对称
源代码
public boolean isDC(Node root){
return isDC1(root.left, root.right);
}
public boolean isDC1(Node root1,Node root2){
if(root1==null && root2==null){
return true;
}else if(root1!=null && root2 != null){
if(root1.value!=root2.value){
return false;
}else{
return isDC1(root1.left,root2.right) && isDC1(root1.right,root2.left);
}
}else{
return false;
}
}
(11)给定一个整数数组,找出两个下标,要求:后面下标所指的数减前面下标所指的数之差最大
源代码
public void find2Index(int[]arr){
int minIndex = 0,maxIndex = 0,max = Integer.MIN_VALUE;
int i=1;
while(i<arr.length){
for(int j=0;j<=i;j++){
if(arr[i]-arr[j] > max){
minIndex = j;
maxIndex = i;
max = arr[i]-arr[j];
}
}
i++;
}
System.out.println("min:"+minIndex+",max:"+maxIndex+
",len:arr["+maxIndex+"]-arr["+minIndex+"]="+(arr[maxIndex]-arr[minIndex]));
}
2 数据库
(1)给两条SQL语句,让根据这两条语句见索引(考虑复合索引只能匹配前缀列的特点)
(2)给定一个场景,设计一个数据库表,写sql语句,要不要对某个字段建索引,为什么(因为那个字段只有两个取值,区分度太低,不建索引)
(3)数据库中事务的概念
3 网络
(1)TCP和UDP区别
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
4 后台
(1)cookie和session的区别;
(2)session在服务器上以怎样的形式存在(session持久化)
(3)怎么设置session和cookie的有效时间
5 缓存
(1)redis有哪些数据类型,集合和有序集合有什么区别
(2)Redis的底层数据结构的实现
6 java框架
(1)springMVC和spring有什么区别
7 java基础
(1)怎么实现多线程并发修改某个值(synchronized;减小锁粒度:用java提供的原子类,比如AtomicInteger
(2)AutomicInteger怎么实现原子修改(核心方法compareAndSwap方法,俗称CAS,CAS的主要功能是什么?说到swap,实现两个数值的交换,不用额外空间))
8 linux
(1)linux高并发怎么改进
(2)fork, socket 编程,已经细到每个函数的名称了。然后linux进程通信方式,具体每一个怎么用,然后说出来一个管道的
9 架构
(1)然后设计一个系统。就说一个服务器上面有一个文件,要把这个文件传给别的服务器,别的服务器数量是成千上万个,怎么设计这个服务器,使得传输的时间最小,或者说系统吞吐量最大
10 开放题
(1)谈谈对归一化方法的了解
(2)你觉得微信中用到了哪些技术,比如朋友圈、比如春晚抢红包
(3)UDP的应用场景,UDP怎么实现可靠传输
(4)LRU Cache的实现
(5)找出排序数组中离第k个数最近的m个数,最近的意思是相减绝对值最小
(6)操作系统中有哪些你觉得有意思的东西
(7)三个房间,只有一个房间里面有车,你选一个,然后上帝打开另一个没车的,问你改不改主意。经典问题,答案是要改,证明见百度
(8)求数组中最小的10个数,用堆写
(9)画TCP三次握手、四次挥手
(10)分段分页机制
(11)C++垃圾回收,shared_ptr的引用计数出现循环引用怎么办,java是怎么解决这个问题的