本人比较渣,从3月份开始找实习到现在,面了一些。把自己面试中遇到的问题拿出来跟大家分享一下,希望大家都能拿到自己满意的offer。
问题基本都是凭自己记忆,可能不太全,日后想起来的话再更新。希望能帮助到各位。
常问问题
Nginx 中 502 和 504 错误详解
- 502 Bad Gateway 错误
- 504 Gateway Time-out 错误
华为一面 2017年4月8日
线程和进程
-
操作系统的线程和java的线程区别
操作系统线程有两种状态:用户态和内核态(和心态)
图 1. Java 线程创建调用关系图
综上所述,Java 线程的创建调用过程如 图 1 所示,首先 , Java 线程的 start 方法会创建一个本地线程(通过调用 JVM_StartThread),该线程的线程函数是定义在 jvm.cpp 中的 thread_entry,由其再进一步调用 run 方法。可以看到 Java 线程的 run 方法和普通方法其实没有本质区别,直接调用 run 方法不会报错,但是却是在当前线程执行,而不会创建一个新的线程。
反射
cvte二面2017年4月12日
tcp四次挥手
设计模式
-
状态码:
- 304:post请求是否会返回这个状态码
-
-
nginx单点故障:
-
dns负载均衡:一个域名对应多个IP地址。dns服务器将解析请求多个IP。
-
cvte一面 2017年4月8日
-
内存溢出
指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,就是溢出
是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;
根本原因:内存申请的速度大于垃圾回收的速度。久而久之,内存越用越少,导致内存溢出。
Java可能出现的内存溢出:
- 程序中的死循环,或者循环过多,而产生过多重复的对象实例。
- 存在对象的引用, 使用完没有清楚,导致jvm无法回收。
- 一次操作中,申请过大的内存。
内存溢出类型:
- java.lang.OutOfMemoryError:PermGen space
是指内存的永久保存区域。这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGenspace中,它和存放类实例(Instance)的Heap区域不同,GC不会在主程序运行期对PermGenspace进行清理。
JVM由XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
JVM由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
该错误常见场合:
a) 应用中有很多Class,web服务器对JSP进行pre compile时。
b) Webapp下用了大量的第三方jar, 其大小超过了JVM默认的大小(4M)时。
- java.lang.OutOfMemoryError:Java heap space
在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;
JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
-
内存泄漏
指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态
结果你申请到的那块内存你自己也不能再访问(也许你把 它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
Java可能出现的内存泄漏:
- 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
- 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要
- 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
- 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。
-
Java会出现内存泄露吗
会。当分配的对象可达,但是已经无用(未对作废数据内存单元的引用置null),此时该对象内存泄漏,不能被垃圾回收,例如:
Vector v = new Vector(); for (int i = 0; i < 10; i++){ Object o = new Object(): v.add(o); o = null; }
或者,在用数组实现的栈中,pop一个元素后,仅把top指针移动,并未把pop的元素设置为null,则发生泄漏
-
怎么避免内存泄漏和溢出
- 尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。
- 程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。 因为每一个String对象都会独立占用内存一块区域
- 尽量少使用静态变量,静态变量是全局的,不会被gc回收。
-
项目更新怎么实现不停机更新(web工程热部署):
一个nginx,两个tomcat,部署时,关闭其中一个,让nginx全部分流到另一个tomcat上面。部署完一个之后,交替
头条 2017年4月5日
-
redis 持久化方式 实现rob的方法
- bgsave和save
-
redis save和bgsave区别
- save直接调用
rdbSave
,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。 - bgsave则
fork
出一个子进程,子进程负责调用rdbSave
,并在保存完成之后向主进程发送信号,通知保存已完成。因为rdbSave
在子进程被调用,所以 Redis 服务器在 BGSAVE 执行期间仍然可以继续处理客户端的请求。
- save直接调用
-
redis主从复制
初次同步完成:Slave向Master发出同步请求(发送sync命令),Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的写命令转发给Slave
以后的同步: Master将变量的快照直接实时依次发送给各个Slave。 但不管什么原因导致Slave和Master断开重连都会重复以上两个步骤的过程。 Redis的主从复制是建立在内存快照的持久化基础上的,只要有Slave就一定会有内存快照发生。
原理总结
1.Slave启动后,无论是第一次连接还是重连到Master,它都会主动发出一个SYNC命令 2.当Master收到SYNC命令之后,将会执行BGSAVE(后台存盘进程),即在后台保存数据到磁盘(rdb快照文件),同时收集所有新收到的写入和修改数据集的命令存入缓冲区(非查询类) 3.Master在后台把数据保存到快照文件完成后,会传送整个数据库文件到Slave 4.Slave接收到数据库文件后,会把内存清空,然后加载该文件到内存中以完成一次完全同步 5.然后Master会把之前收集到缓冲区中的命令和新的修改命令依次传送给Slave 6.Slave接受到之后在本地执行这些数据修改命令,从而达到最终的数据同步 7.之后Master与Slave之间将会不断的通过异步方式进行命令的同步,从而保证数据的时时同步 8.如果Master和Slave之间的链接出现断连,Slave可以自动重连Master。
-
redis集群搭建
-
怎么在java中调用redis保存对象类型的数据:
- 将对应的类实现Serializable接口,然后序列化为一个bytes[]数据,传入set方法
- get的时候,将返回的byte[]数组反序列化即可。
-
http状态码:
状态码 内容 200 请求成功 301 永久重定向 302 暂时重定向 304 not modify:资源没有改变,可以继续使用 400 bad request 401 未授权 Unauthorized 403 禁止访问 Forbidden 404 not found 500 内部服务器错误 Internal Server Error 502 网关错误 服务器作为网关或代理时,从上游服务器接收到无效的响应 503 服务不可用 Service Unavailable 504 网关超时 -
mysql innodb和myism区别
-
mysql 主键索引 普通索引 唯一索引 全文索引
主键索引:不能有重复 不能为null,只能有一列是主键
唯一索引:不能有重复 可以为null,但不能出现多个空值。可以有多列都是唯一索引
普通索引:既可以重复 也可以为null,也可以为空,也可以有多列
-
全文索引:只有myisam支持,只能用于char varchar text类型的列上面。适合大型数据集。文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成的较大段文字,普通索引就没什么作用了。这种检索往往以LIKE %word%的形式出现,这对MySQL来说很复杂,如果需要处理的数据量很大,响应时间就会很长。
索引原则
索引不是越多越好
不要对经常变动的数据加索引
小数据量的表建议不要加索引
索引一般应加在查找条件的字段
什么时候加索引
- 在 WHERE,ORDER BY 子句中经常使用的字段
- 字段的值是多个(例如性别字段则不适合)
- 字段内容不是经常变化的
- 经常变化的字段,添加索引反而降低性能
- 不宜过多添加索引
- 每添加一条索引都会占用磁盘空间
-
多列索引生效规则:
btree索引的常见误区 在where条件常用的列上都加上索引
比如:where cat_id=3 and price>100 #查询第3个栏目,100以上的商品
只能用上cat_id或price索引,因为独立的索引同时只能用上1个。多列索引生效规则
多列索引发挥作用,需要满足左前缀要求。以index(a,b,c)为例:
语句 | 索引是否发挥作用 - - - - - - - - - - - - - - - where a=3 | 是 where a=3 and b=5 | 是 where a=3 and b=5 and c=4 | 是 where b=3 | 否 where c=4 | 否 where a=3 and c=4 | a列能用到索引,c不能 where a=3 and b>10 and c=7 | a能,b能,c不能 where a=3 and b like 'xxx%' and c=7 | a能,b能,c不能
-
python range 和xrange
-
python yield关键字
-
Java hashmap 和 hashtable
-
hashmap和hashtable时间复杂度
-
实现一个LRU cache
-
BIO(IO) NIO AIO
同步和异步说的是消息的通知机制,阻塞非阻塞说的是线程的状态
首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,
同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO服用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
同步阻塞 IO :
在此种方式下,用户进程在发起一个 IO 操作以后,必须等待 IO 操作的完成,只有当真正完成了 IO 操作以后,用户进程才能运行。 JAVA传统的 IO 模型属于此种方式!
同步非阻塞 IO:
在此种方式下,用户进程发起一个 IO 操作以后 边可 返回做其它事情,但是用户进程需要时不时的询问 IO 操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的 CPU 资源浪费。其中目前 JAVA 的 NIO 就属于同步非阻塞 IO 。
异步阻塞 IO :
此种方式下是指应用发起一个 IO 操作以后,不等待内核 IO 操作的完成,等内核完成 IO 操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问 IO 是否完成,那么为什么说是阻塞的呢?因为此时是通过 select 系统调用来完成的,而 select 函数本身的实现方式是阻塞的,而采用 select 函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!
异步非阻塞 IO:
在此种模式下,用户进程只需要发起一个 IO 操作然后立即返回,等 IO 操作真正的完成以后,应用程序会得到 IO 操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的 IO 读写操作,因为 真正的 IO读取或者写入操作已经由 内核完成了。目前 Java 中还没有支持此种 IO 模型。
- BIO:同步阻塞,面向流,一个字节一个字节的读取
- NIO:同步非阻塞,面向通道和缓冲,
- AIO:异步非阻塞,面向通道和缓冲,
乐视 2017年4月6日
- cookie跨域:比如baidu.com的cookie可以在www.baidu.com使用吗
- 不适用session 怎么保存用户信息
- 不用session怎么实现登陆
- token的安全性问题
- session和cookie的区别
- cookie的内容
- 过期时间
- 路径
- 内容
- 主机(域)
- 名称
- http协议和请求的内容
- 请求行 get uri http/1.1
- 消息头
- Accept:客户端可以接受的文件类型
- Referer:从哪里来的
- Accept-Language:接受的语言
- Accept-Encoding:可以接受的压缩格式
- connection:keep-alive 长连接
- nginx单点故障怎么解决
- dns负载均衡 域名解析
- jvm什么情况下会溢出:当申请内存的速度超过内存回收的速度
美团一面 2017年3月16日
-
数据库连接过多是什么原因:
session用完没关闭,表示连接没释放。其他session不可以再利用这个连接。久而久之,连接池中连接数达到最大,
数据库连接和session会话是一回事儿吗?有什么不同?
-
session关闭都释放的是什么资源 怎么释放资源:
session关闭释放的是连接,把连接放回导数据库连接池中。
-
怎么让栈内存溢出
栈是jvm内存区域中的一块,存在两种内存溢出:stackOverflow和outofmemory两种错误。
递归过多会出现stackOverflow。如果在栈中申请过多内而超出栈剩余的内存会出现oom。
spring bean的生命周期
spring bean的构造中,有参构造和无参构造有什么区别
tomcat内存为什么会溢出
为什么jvm有垃圾回收还是会内存溢出
单例的实现,每种实现的原理,各有什么弊端
静态内部类实现的单例模式是否有线程安全问题(effective java推荐的那种方法)
nginx session共享实现
为什么用redis不用别的
-
手写两个算法:
一个数组和一个链表相关的。写出来之后让优化,从时空复杂度一直优化。。
最后看我论文做得是自然语言处理,然后顺便问了一些相关的算法。。
阿里二面 2017年3月16日
介绍项目。因为项目中主要负责
果然java面试官都对前端没兴趣,让我
hashmap的valueSet()是否有序
spring 事务管理,,自己管理和spring管理怎么弄,什么区别(这个不知道)
数据库索引 底层实现
jvm启动参数
垃圾回收算法
ORM框架解决的什么问题,
hibernate 和mybatis之间的区别,适应场景
阿里一面 2017年3月9号
先自我介绍
然后说项目。
项目中问到数据库连接过多,怎么解决的,mysql最大连接数
然后mysql问到mysql事务
事务的特性,持久化是什么。
mysql支持的最大连接数:默认是100,最大是16384
nginx tomcat负载均衡的有几种方式:轮询、ip_hash、weight、fair(第三方)、url_hash(第三方)
session共享:实现方法,redis。
jvm内存模型:
垃圾回收,哪种对象不会被回收
并发集合类
粉笔一面 2017年3月--日
二分查找
。。。
关于粉笔,是我实习面的第一家。可以说很失败。。。