美团一面
1.手写插入排序.
我当时写的
public void insortSort(ElemType[] A){
int length = A.length;
for(int i = 0; i < length; i++){
int j = 0;
for(j = 0; j < i; j++){
if(A[i] <= A[j]){
break;
}
}
ElemType temp = A[i];
for(int k = i; k >= j; k--){
A[k] = A[k-1];
}
A[j] = temp;
}
}
书本上的写法:
//数据存放在1-n中
public void insortSort(ElemType[] A,int n){
int i,j;
for(int i = 2; i <= n; i++){
if(A[i] < A[i-1]){
A[0] = A[i];
for(j = i-1; A[0].key < A[j].key; j--){
A[j+1] = A[j];
}
A[j+1] = A[0];
}
}
}
2.你觉得哪些方面是你擅长的?
回答:集合,多线程
3.开始问多线程和集合问题,你知道哪些集合?
ArrayList、HashMap、BlockingQueue;
4.BlockingQueue满了怎么办?
BlockingQueue中有两个ReentrantLock变量(takeLock和putLock),实现了读写分离。同时又有对应的两个条件Condition对象,notEmpty=takeLock.newCondition()和notFull=putLock.newCondition()。
生产者在往BlockingQueue中放入元素的时候,有四种方式:add、offer、put、offer(E,long,TimeUnit).
如果BlockingQueue满了的话,add会直接抛出异常、offer不阻塞,不抛异常,返回boolean值表示插入是否成功、put会阻塞、offer(E,long,TimeUnit)会等待一定时间。
实际上add就是掉了offer,如果返回false,再抛出异常。
put方法是如何阻塞的?
put方法在队列满的时候,会调用notFull的await方法,等待条件被满足,只有当消费者从队列中取出元素后,会调用notFull的signal方法,唤醒等待的生产者线程。
Signal的时候锁已经释放了会怎么样?
抛异常:IllegalMonitorStateException
5.ArrayList的初始容量是多少?为什么?
很自信的回答:初始容量是10。面试官反复问我你确定?见鬼。
问为什么我就不知道了。估计没有答案。
6.HashMap的hash函数是怎么设计的?
我当时的第一反应是想要问题HashCode的函数是怎么实现的吗。
现在回想起来,估计是想问HashMap中是如何计算Hash值。
HashMap中的Hash算法是使用拉链法,首先,通过对key的hashcode来计算key所对应的位置,HahsMap对求余
计算index的方式做了优化,采用按位与的操作,因为HashMap的容量始终都是2的整数幂,所以index肯定是0-2n-1,任何一个Hashcode和2n-1按位与,肯定落在0-2^n-1上。
接着又问有哪几种解决Hash冲突的方法?
1.开放定址法(线性探测、平方探测、再散列、伪随机序列法)
2.拉链法
还问了这些方法的使用场景?
6.Http头部有哪些字段?
下面列举以下常见的:
通用首部 | 作用 |
---|---|
Connection | 连接管理字段 |
Cache-Control | 缓冲控制字段 |
Transfer-Encoding | 指定报文主体的传输编码格式 |
实体首部 | 作用 |
---|---|
Content-Type | HTTP主体内容类型 |
Content-Length | HTTP主体内容长度 |
Content-Encoding | HTTP主体内容编码方式 |
如果设置了Transfer-Encoding,Content-Length就会被忽略
Transfer-Encoding指的是传输的编码方式(分块传输)
Content-Encoding指的是内容的编码方式
请求头 | 作用 |
---|---|
Accept | 设置接受的内容类型 |
Accept-Charset | 设置接受的字符编码 |
Accept-Encoding | 设置接受的编码格式 |
Authorization | 设置HTTP身份验证的凭证 |
Host | 表示请求的主机和端口,HTTP1.1中必须包含这个字段 |
Cookie | 设置服务器Set-Cookie的内容 |
Referer | 设置前一个页面的地址 |
User-Agent | 用户代理(浏览器)的字符串值 |
响应头 | 作用 |
---|---|
Server | 服务器内容信息 |
Location | 客户端重定向的URI |
7.Cookie和Session的区别
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
Session的实现方式:
1.利用Cookie
2.URL重写
3.表单隐藏
8.HTTP状态码
状态码 | 说明 |
---|---|
200 | 客户端请求成功 |
302 | 临时跳转,跳转的内容由Location字段指定 |
400 | 客户端请求有语法错误,不能被服务器识别 |
401 | 未授权 |
403 | 服务器收到请求,但是拒绝提供服务 |
404 | 请求的资源不存在 |
500 | 服务器发生不可知的错误 |
9.项目深入问的时候被怼的很厉害。需要挖掘一下项目的深度。
美团二面
1.你所知道的性能指标有哪些?
GC、数据库查询时间(qps)、请求的响应时间(RT)、CPU使用率、MEM使用率
2.手写SQL语句:
订单表Order:orderid,userid,productid,quantity.
查询购买产品id为99的且数量超过10的用户id
select userid from order
where productid = 99
group by userid
having count(quantity) > 10
SQL语句是怎么样的一个执行过程?
数据库连接池的配置
3.HTTP请求的执行过程
-
- 域名解析
-
- 发起TCP的3次握手
-
- 建立TCP连接后发起http请求
-
- 服务器端响应http请求,浏览器得到html代码
-
- 浏览器解析html代码,并请求html代码中的资源
-
- 浏览器对页面进行渲染呈现给用户
你知道HTTPS的原理吗
4.NativeHook的实现(项目)
5.LinkedHashMap的Key是否可以为空?
LinkedHashMap的继承了HashMap,并且在HashMap的实现基础上,对HashEntry增加了before和after指针,用来保存插入顺序(或访问顺序)。因此LinkedHashMap的Key是可以为空的。
6.线程池的实现。创建线程池需要哪些参数?
corePoolSize,maxPoolSize,keepAliveTime,unit,workQueue,threadFactory(忘记了),rejectedHandler
当线程数达到corePoolSize的时候,怎么做?
任务会被放入workQueue,如果workQueue满了,而且线程数没有达到maxPoolSize,会新建线程。
7.设计模式
适配器、装饰者、桥接模式、策略模式
8.手写单例模式
写了一个静态内部类,延迟加载。
public class Singleton{
private Singleton{}
public Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
private static SingletonHolder{
private static Singleton INSTANCE = new Singleton();
}
}
延迟加载有什么作用?
当创建一个对象的开销特别大的时候,而且程序中可能并不会用到这个对象。
9.考查命令:
查看日志中最后100行中出现“error”的次数
日志分析(已经被问到2次)
cat log | grep -c “error”
Java程序高CPU问题排查
top -H -p {PID} 显示高CPU的进程的所有线程号,获得线程号
printf "%x\n" {tid} 将10进制的tid转化为16进制
最后打印线程的堆栈信息:
jstack pid |grep tid -A 30
查看服务器打开的连接
netstat -nplt
10.如何控制多个线程的顺序执行?
美团三面(技术leader)
1.画一下你们的项目技术架构
2.你们的Agent的实现原理
3.Tomcat类加载器是怎么工作的,看过源码吗?