你们好,我是ITDragon龙,今天分享一些面试中常问的题目,和一些面试感觉。我是四月二十五号离职,二十六号上午八点从深圳出发,下午三点到武汉。二十七号便开始参加面试。天天的节奏基本是:上午去公司面试,中午去小区房子装修监工,下午再去公司面试,中途还有几个电话面试,晚上再把印象深入的面试题弄清楚。回来的这几天痩了几斤肉!这几天的面试给我不少感觉。html
1、面试的几家公司大部分是北上广深在武汉创建的研发部门。缘由很简单,武汉人才性价比高。前端
2、面试的几家公司大部分面试官都会很直接告诉你加班强度很大。java
3、无关技术,从深圳回到武汉,工资大概要打七折。缘由嘛,五花八门。mysql
4、灰常的堵,特别是光谷软件园,电动车都不看红绿灯,各类瞎闯。程序员
由于房子和交通,我选择公司的范围缩小了不少。由于回来匆忙,对于面试题和公司都没有很好的了解,所以在面试中一直处于劣势。如今把本身的面试经验分享出来,帮你们把部分坑填平。预祝你们都能拿高薪。我这炮灰的做用也算是尽职了。web
找工做不能将就,不能进公司后发现不满意而选择离职,这样对本身和对公司都有损失。因此一开始就要问清楚。如下是我比较在乎的四个点,仅供参考。面试
1、加班强度:如今程序员加班已成常态,产品发布还要等到夜深人静的时候。我以为程序员就像一支蜡烛,燃烧本身照亮世界。加班必定要适量。不加,老板不会放过你!多加,医生也不会放过你!因此我但愿加班强度不能太大。redis
2、出差频率:有的人喜欢出差,有的人不喜欢出差,好比我。算法
3、额外待遇:好比每个月的绩效奖金,项目现金,一年的年终奖。年终奖必定要问清楚:未满一年的是怎么计算?发的是基本工资?除了每个月固定工资外,必定要有其余额外福利,否则动力从何而来。sql
4、接触领域:若是有机会进入贵公司,最好问清楚接触的技术领域,最好是主流的技术。不建议推倒车。
你须要清楚一点:你用一个月加班换来的钱,还不够在医院消费一次。
你须要清楚一点:回答技术问题的时候,面试官但愿听到更多的答案
这是一个很常见的问题,若是单纯的只回答IO和NIO的区别,只能算及格。我我的以为应该从如下几个方面回答:
1)、IO简介,
2)、TCP的三次握手,由于这也是二者的区别之一,
3)、NIO简介,
IO:(Block-IO)是一种阻塞同步的通讯模式。是一个比较传统的通讯方式,模式简单,使用简单。但并发处理能力低(每次链接都会建立新的线程进行链路处理),通讯耗时(TCP三次握手),依赖网速。
TCP三次握手:
第一次握手:创建链接,客户端发送syn包到服务器端,等待服务器确认
第二次握手:服务器收到客户端传来的syn包,给客户端返回ack和syn包,等待客户端确认
第三次握手:客户端收到服务器传来的ack+ayn包,向服务器发送ack包,链接创建成功
NIO:(New IO / Non-Block IO)是一种非阻塞同步的通讯模式。客户端和服务器之间经过Channel通讯(避免TCP创建链接使用三次握手带来的开销)。NIO在Channel进行读写操做。这些Channel都会被注册在Selector多路复用器上。Selector经过一个线程不停的轮询这些Channel。找出已经准备就绪的Channel执行IO操做。
参考文档
1)、堆和栈的共同点,
2)、堆和栈的区别,
3)、线程之间数据共享,
Java内存分两类,一类是堆内存,一类是栈内存
堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是能够共享数据的。
栈:主要用于存储局部变量和对象的引用变量,每一个线程都会有一个独立的栈空间,因此线程之间是不共享数据的。
既然回答了内存,其实能够把内存溢出的状况一并回答。
1)、先回答什么是内存溢出,
2)、再谈谈内存溢出的缘由,
3)、最后提出几个内存溢出的解决方案,
内存溢出:程序运行实际使用的内存大于虚拟机设置的内存
溢出缘由:
1)、虚拟机配置参数设置不合理
2)、代码中出现死循环或者产生大量的重复对象实体
3)、数据流若是没有闭关也容易致使
4)、内存中一次性加载的数据量过于庞大
5)、大量的垃圾不能被JVM回收
解决方案:
1)、最直接,最不负责的方案就是修改JVM启动参数
2)、正确流程是经过检查错误日志,查找OutOfMemory错误缘由,而后修改bug
1)、先回答什么是JVM认为的垃圾,
2)、都有那些经常使用的垃圾回收算法,
3)、都有那些经常使用的垃圾回收器,
JVM认为那些不被使用的对象就是垃圾,须要从内存中除掉。
经常使用的垃圾回收算法有:引用计算法,标记清除法,标记压缩法,复制算法,分代,分区思想
引用计算法:古老的算法,对象被引用时加一,引用断开时减一,若为零则被当成垃圾回收。频繁加减操做性能低。
标记清除法:先把垃圾"标记"(遍历全部的GC Roots,而后将全部GC Roots可达的对象标记为存活的对象),后统一"清理"。清理后的内存空间不连续,性能不高。
标记压缩法:在标记清除法的基础上作一个压缩功能。
复制算法:内存被分为两个大小相同的A,B两块,使用A内存时,将把A内存中的活对象复制到B,而后清空内存A中的全部对象。使用B内存也是同样的。缺点是内存变小了。
分代思想:新生代,老年代(新生代中的对象通过频繁的GC中存活下来的对象)。新生代由于存活率低,须要复制的对象少,建议用复制算法。老年代存活率高,须要清理的对象少,建议用标记压缩法。
分区思想:将整个内存分为多个独立空间。在每一个独立空间进行垃圾回收,提升系统性能。
串行垃圾回收器:使用单线程进行垃圾回收
并行垃圾回收器:使用多线程进行垃圾回收,对性能要求比较高
CMS收回器:并发回收器,比并行更快,当占用的资源更多,能够尽量减小系统停顿时间
G1回收器:JDK1.7以后提供的新的收集器,是基于标记压缩的算法,特色是针对整个java堆进行
参考文档:
JVM系列博客:https://blog.csdn.net/column/details/javavirtualmachine.html
1)、简单介绍二者的区别
2)、工做中建议使用synchronized的缘由
3)、JDK1.6以后对synchronized的优化
synchronized:关键字,在jvm层面上,线程正常执行完后会释放锁,若线程发生异常则由jvm释放锁,jdk1.5以前没有锁竞争机制,容易出现线程一直阻塞的状况,只适合少并发量使用。
Lock:类,必须在finally中释放锁,由于添加了锁竞争机制,不会出现线程一直等待的问题,适合高并发量使用。
工做中建议使用synchronized关键字,缘由很简单,jdk1.6以后对synchronized作了大量的优化。为了减小得到锁和释放锁所带来的性能消耗,引入了“轻量级锁”和“偏向锁”来提升性能。
1、适应性自旋
下降了线程在等待锁的过程当中的开销。由于线程从挂起到恢复是很耗时的,有些线程在挂起后很短的时间内就能够获取锁,经过漫无目的的循环让线程暂不挂起。适应性自旋表如今自选的循环次数是根据实际状况来定。
2、锁消除
删除一些不必的加锁操做。
3、锁粗化
虽然减少锁的粒度,能够提升性能。但有些代码明明只须要加一把锁,你非要加多个??锁粗化能够把屡次加锁和解锁合并成一次,用以提升效率。
4、轻量级锁
轻量级锁所适应的场景是线程交替执行同步块的状况,若是存在同一时间访问同一锁的状况,就会致使轻量级锁膨胀为重量级锁。
5、偏向锁
引入偏向锁是为了在无多线程竞争的状况下尽可能减小没必要要的轻量级锁执行路径,由于轻量级锁的获取及释放依赖屡次CAS原子指令,而偏向锁则是在只有一个线程执行同步块时进一步提升性能。
参考文档:
lock和synchronized区别:https://blog.csdn.net/wangtaomtk/article/details/52264043
lock和synchronized区别:https://blog.csdn.net/u012403290/article/details/64910926?locationNum=11&fps=1
1)、简单谈谈HashMap的底层实现
2)、HashMap和HashTable的区别
3)、工做中线程安全的HashMap使用
HashMap的底层是链表散列的数据结构,即数组和链表的结构。经过计算key的hash值肯定数组的位置,若该位置已经有值,则往该元素后面添加,造成一个链表。每一个Entity存储hash,key,value,next四个值。在检索中,经过hash找到数组的位置,而后在经过key遍历链表,直到找到为止。在jdk1.8之后,若链表长度超过阙值后,会将该链表转为红黑树,以提升检索效率。红黑树是自平衡查找二叉树,解决了二叉树屡次插入新节点致使的不平衡。当红黑树插入新节点时会经过[变色]和[选择]来知足自身规则,详情能够参考文档链接。
HashMap,HashTable,LinkedHashMap区别
1)、HashMap不是线程安全的,HashTable是线程安全的,内部经过synchronized修改加锁,其性能较差
2)、HashMap容许一个key为null,HashTable不容许
3)、HashMap的初始容量是16,而HashTable的初始容量是11
4)、工做中HashMap的使用频率较高,若但愿值有序则使用LinkedHashMap,若考虑线程安全则使用ConcurrentHashMap,ConcurrentHashMap使用分段式锁性能比HashTable好。
参考文档:
ArrayList和LinkedList的区别,Java 经常使用List集合使用场景分析
HashMap的实现原理:https://blog.csdn.net/tuke_tuke/article/details/51588156
hashMap和hashTable的区别:https://www.cnblogs.com/aspirant/p/6856487.html
什么是红黑树:http://www.sohu.com/a/201923614_466939
1)、什么是单例模式
2)、常见的单例模式有那些
3)、写出其中的一种
单例模式:某个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
常见的单例模式有:懒汉模式,饿汉模式,静态类内部加载
// 线程安全的静态类内部加载 public class SingletonDemo{ private static class SingletonHolder{ private static SingletonDemo instance = new SingletonDemo(); } public static SingletonDemo getInstance() { return SingletonHolder.instance; } }
参考文档:
https://www.cnblogs.com/cielosun/p/6582333.html
听到这个问题时,我是窃喜的,多么简单的问题,但是面试的时候,殊不知道该怎么回答。
MVC:model,view,controller。
Model:模型层,负责实现业务逻辑,操做数据库
View:视图层,负责页面展现
Controller:控制层,负责处理请求
咱们经过实际的框架来了解,
SpringMVC,它实现了mvc设计模式的web框架。用户发送的请求会经过前端控制器(DispatcherServlet),根据URL映射到对应的Handler中。而这个Handler能够是用注解@RequestMapping修饰的方法,而这个方法所在的类能够用注解Controller修饰代表该类是一个控制层。能够在方法里面调用接口完成业务逻辑的操做和数据修改,将返回的结果放在ModelAndView变量中。DispatcherServlet会经过视图解析器拼接返回页面的路径,并将数据放到做用域中,渲染给用户。实现业务逻辑的接口能够理解为Model层,处理请求的类能够理解为Controller层,页面就是View层。
谈到SpringMVC,就不会少了Struts2,
Struts2也是一个基于MVC设计模式的Web应用框架,在web.xml文件中将符合要求的请求交给Servlet处理,这个 Servlet再参考struts-config.xml文件找到对应的action方法,执行完成后关联到对应的页面。SpringMVC比Struts2简单了不少。
咱们再简单谈谈Hibernate,Mybatis,SpringData
咱们还能够再谈谈Spring
还有设计原理
由于时间和精力的状况,这里只作简单整理的问题。
1、redis事务是怎么作的?
答:redis的事务主要是经过multi(开启事务),exec(提交事务),watch(监控版本号)几个命令完成的。
2、如何实现抢购防超卖功能?
答:抢购,秒杀的场景下既要保证用户体验, 又要防超卖。其实很简单,减小数据库的调用,1000个商品限时抢购,就是1000个数字减一。经过加锁保证线程安全。使用缓存提升效率。
3、如何设计数据查询接口保证数据的安全和性能?
答:安全:服务器接口令牌验证;查询参数长度校验;查询参数格式校验(避免sql注入);
性能:索引优化;Ehcache本地缓存;redis缓存预热;
4、Nginx如何作权限拦截?
答:Nginx和lua能够实现权限拦截
5、2*16如何最快计算结果?
答:向左移动4位
6、架构如何用一个字段设置10个Boolean型权限?
答:用int型字段,分别用0,1表示false和true
七:为何不用mysql作分布式锁?
答:我会从性能方面回答,用redis作分布式锁,是判断key值是否存在,存在则表示有锁。用Zookeeper作分布式锁,是判断临时节点是否存在,存在则表示有锁。而mysql作分布式锁在并发量高的状况下出现死锁。
八:分布式系统如何避免消息重复消费?
答:从生产者避免重复发送角度:将生产者发送的消息持久化到数据库中,若有相同的信息则再也不保存;当生存者服务的事务完成后,消息服务会将数据库中的消息发送给消费者。
从消费者避免重复消费角度:消费者服务多是集群,要考虑幂等性。查询和删除是自然的幂操做,因此咱们要在更新和建立以前作判断,是否已经存在,是否已经更新。
9、你对咱们公司的了解么?
答:.......
先暂时到这里,喜欢的朋友能够关注我,以为这篇文章对你有帮助也能够点赞,若有问题,请尽快联系我,会及时修改。