前言
本文包含多家公司的面试题,问题的答案纯属我的意见,并不表明标准答案,若有错误欢迎在评论区指正面试
本文涉及的面试问题不包括算法问题求解(篇幅过小且内容局限性太大)以及分布式系统架构(过于理论和公式化,说白了你们问的都是老掉牙的问题,而架构的原理涉及的太深很差展开),只挑选了部分我我的以为还有点意思或者有点深度的问题,若是有人感兴趣的话我再接着写几篇算法
函数式编程有什么特色?
- 函数和变量的地位相同,能够做为参数和返回值
- 支持闭包和高阶函数,可让对象像函数同样操做
- 支持惰性计算,能够等到须要求值的时候再进行计算
- 只使用表达式,不使用语句,全部的代码都是单纯的运算过程,全部的操做都是用于处理运算
- 没有反作用,全部的功能均返回一个新的值,不会改变外部变量的状态和值
CgLib是如何提升调用代理方法的效率的?
采用了FastClass机制,具体内容以下:spring
- 为全部的方法创建索引
- 调用前根据方法信息查找索引
- 调用时根据索引直接匹配相应的方法直接进行调用
讲一个随机选择算法(从集合A中随机选择m个元素)
算法步骤:sql
- 取m个元素放在集合B中
- 对于第i个元素(i > m,i起始为
m+1
),让这一元素在m/i
的几率下,等几率随机替换B中的任一元素
- 重复上述操做,直到遍历集合结束
- 返回B集合
证实:数据库
- 遍历到第m+1个元素时,该元素被保存在B中的几率为
m/(m+1)
,B中元素没有被替换的几率为1-(m/(m+1) * 1/m) = m/(m+1)
- 遍历到第i个元素时,前i-1个元素被保存在B中的几率为
m/(i-1)
,第i个元素被保存在B中的几率为m/i
,前i-1个元素,每一个留在B中的几率为m/i
- 当i等于n时,即遍历到第n个元素时,前n-1个元素,每一个留在B中的几率为
m/n
,第n个元素被替换到B中的几率也为m/n
,因此每一个元素被保存在B中的几率均为m/n
说一下JMM
JMM,即Java Memory Model,即Java内存模型,定义了虚拟机在内存中的工做方式编程
JMM是隶属于JVM的,从抽象角度看,JMM定义了线程和主内存之间的抽象关系:后端
- 线程的共享变量存储在主内存中
- 每一个线程拥有本身的私有的本地内存,本地内存保存了共享变量的副本
本地内存是JMM的抽象概念,并非真实存在的,它覆盖了缓存、写缓冲区、寄存器等浏览器
用最简单的话来介绍一下各类范式
- 1NF:每一列都是不可分割的数据项
- 2NF:在1NF的基础上,消除部分依赖
- 3NF:在2NF的基础上,消除非主属性对码的传递依赖
- BCNF:在1NF的基础上,保证任意依赖的决定因素必须包含码
- 4NF:在3NF的基础上,消除多值依赖
- 5NF:在4NF的基础上,保证表不能再分解
广义上的线程阻塞状态能够分为三种,讲一下是哪三种
无限期等待(Waiting):处于该状态的线程不会被cpu分配时间片,须要等待其余线程显式唤醒spring-mvc
- obj.wait()
- thread.join()
- LockSupport.park()
有限期等待(Timed Waiting):处于该状态的线程也不会被其余线程也不会被cpu分配时间片,可是除了被其余线程显式唤醒以外,在等待超时后能够自行唤醒缓存
- Thread.sleep(millis)
- obj.wait(timeout)
- thread.join(millis)
- LockSupport.parkNanos(nanos)
- LockSupport.parkUntil(deadline)
阻塞(Blocked):线程会等待获取某一个锁,在期间会被阻塞
- 进入synchronized修饰的方法或代码块中,且线程没有拥有对应的锁
线程若是发生异常,其余线程会怎么办?
当前线程方法的异常语句以后的代码无效,不影响其余线程的执行
park和wait方法有什么区别?
- wait方法经过对象的互斥锁实现线程同步,park是经过一个二元信号量实现线程同步的
- wait方法会让线程放弃当前持有的锁,park方法则不会
- 在wait方法调用前notify是无效的,但能够经过提早调用unpark方法,来让接下来调用park方法的线程提早获取许可
TCP和UDP的具体应用场景有哪些?
TCP:对通讯质量有要求
- 浏览器协议:http
- 文件传输协议:ftp
- 邮件协议:smtp、pop
- 远程登录标准协议:Telnet
UDP:对通讯速度有要求
- 简单文件传输协议:tftp
- 域名系统:dns(也使用了tcp协议,若是发送的报文超过512个字节,会使用tcp发送)
- 语音和视频
Spring的单例模式是如何实现的?
是经过单例注册表的方式实现的,在AbstractBeanFactory
的父类DefaultSigletonBeanRegistry
中,有一个ConcurrentHashMap
类型的成员变量singletonObjects
,保存了beanName => bean对象
的映射关系
当须要建立单例对象时,会检查这个对象(注册表)是否已存在映射,若是已存在则直接从表中返回
新生代对象进入老年代有哪几种状况?
- Eden区满,进行
Minor GC
,若是存活的对象仍然没法放到新生代,则提早转移到老年代
- 若是须要建立的对象太大,则直接将对象分配到老年代
- 新生代中存活超过必定代数的对象(默认为15代)
- 若是某年龄的对象超过Survivor区的一半,则超过此年龄的对象提早转移到老年代(动态年龄判断)
MVVM和MVC有什么区别?
MVVM是Model-View-ViewModel
的缩写,将MVC中View的状态和行为抽象化,同时将视图UI和业务逻辑分离开,实现了后端数据、模板页面和控制器的分离
MVC中Controller的一部分职责被拆分出由ViewModel负责,实现了Model和View的自同步,下降了业务和页面的耦合
TCP优化技术你知道的有哪些?
Nalge算法
目的是解决大量小数据传输致使效率降低的问题,实现原理是使链路上永远只有一个小于MSS(最大报文段)的待肯定包,尽量发送大块的数据
只有当如下状况时才容许发送:
- 包长度达到MSS(最大报文段长度)
- 包含有FIN
- 设置了TCP_NODELAY选项
- 未设置了TCP_CORK选项时,但全部发送的小数据包(长度小于MSS)均被确认
- 上述条件均未知足时,发生超时
虽然避免了网络拥塞,可是网络的整体利用率很低,也下降了实时性
Delay ACK(延时确认机制)
目的是减小网络中传输大量的小报文数,实现原理是经过新数据来将ACK捎带过去
具体实现以下:
- 收到数据时,不立刻ACK,而是等待一段时间后再进行ACK
- 若是连续收到两个数据包,仍然须要立刻ACK
操做系统的内碎片和外碎片的概念讲一下
- 内碎片:已经被分配出去的内存空间大于请求所需的内存空间,致使进程拥有的地址空间中有一部分没有使用到,最终白白浪费
- 外碎片:尚未被分配出去,可是因为过小没法被申请的其余进程使用,最终白白浪费
单例模式比起静态方法有什么优势?
- 单例类的方法支持覆写
- 单例类能够被延迟实例化
- 单例类能够被用于多态,不须要关注全局的状态
Mysql性能优化有哪些方案?
sql优化
- 避免全表扫描:具体的操做太多了,不一一列举了
- 避免没必要要的操做:略,理由同上
表结构优化
选择合适的数据类型
系统性能优化
- 增大
innodb_buffer_pool_size
的值,避免常常性从磁盘中读取数据
- 在数据库启动前,执行预热脚本进行数据预热,将磁盘上的数据缓存到内存中
- 使用足够大的
innodb_log_file_size
(写入缓存),建议调整为innodb_log_file_size
的0.25倍
- 增长
max_connections
,提升容许同时链接的用户数
- 增长
key_buffer_size
的值,提升用于索引块的缓冲区大小
- 增长
thread_cache_size
的值,提升可复用的线程数量
结构优化
- 分库:基于主从架构的读写分离
- 分表:水平/垂直分表 其余 启用缓存
适配器模式有哪些应用场景?
抽象场景
- 须要使用某个类,可是这个类的接口不符合系统须要
- 须要将一些彼此没有太大关联的类联系起来,使其能够一块儿工做
- 须要为一些类提供一个统一的输出接口
具体场景
- spring-aop:将不一样的通知类型适配到统一的适配器接口AdvisorAdapter中,能够经过具体的适配器类来获取对应通知的拦截器
- spring-mvc:使用
HandlerAdapter
来适配具体的Controller
,实现了DispatcherServlet
和Controller
之间的统一接口对接
跨表查询有那些优化思路?
- 能用join的不用where
- on中的条件尽量多
- 左链接保证右表字段索引,右链接保证左表字段索引,内链接保证任一表字段索引
group by
的列来自join的第一个表
- 给
group by
的列添加索引,避免产生临时表(存疑)
你会怎么实现微信里“附近的人”算法
- 将地图按照必定的经纬度距离切分红方格,每一个方格又能够进一步切分出更小的方格
- 为每个格子使用gohash算法进行编号,编号按照最左匹配,能够表示不一样精度范围的方格
- 当打开“附近的人”功能时,系统根据设备的定位信息获得用户所在的方格编号
- 按照选定的精度范围,匹配方格编号的前n位,而后从数据库中搜索方格编号前n位与其一致的用户
- 能够经过按方格分库分表加快查询速度