java面试整理
IO和NIO的区别
这是一个很常见的问题,如果单纯的只回答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操作。
参考文档
Java堆和栈的区别
1)、堆和栈的共同点,
2)、堆和栈的区别,
3)、线程之间数据共享,
Java内存分两类,一类是堆内存,一类是栈内存
堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。
栈:主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。
既然回答了内存,其实可以把内存溢出的情况一并回答。
谈谈内存溢出
1)、先回答什么是内存溢出,
2)、再谈谈内存溢出的原因,
3)、最后提出几个内存溢出的解决方案,
内存溢出:程序运行实际使用的内存大于虚拟机设置的内存
溢出原因:
1)、虚拟机配置参数设置不合理
2)、代码中出现死循环或者产生大量的重复对象实体
3)、数据流如果没有闭关也容易导致
4)、内存中一次性加载的数据量过于庞大
5)、大量的垃圾不能被JVM回收
解决方案:
1)、最直接,最不负责的方案就是修改JVM启动参数
2)、正确流程是通过检查错误日志,查找OutOfMemory错误原因,然后修改bug
JVM垃圾回收机制
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
lock和synchronized区别
1)、简单介绍两者的区别
2)、工作中建议使用synchronized的原因
3)、JDK1.6之后对synchronized的优化
synchronized:关键字,在jvm层面上,线程正常执行完后会释放锁,若线程发生异常则由jvm释放锁,jdk1.5之前没有锁竞争机制,容易出现线程一直阻塞的情况,只适合少并发量使用。
Lock:类,必须在finally中释放锁,因为添加了锁竞争机制,不会出现线程一直等待的问题,适合高并发量使用。
工作中建议使用synchronized关键字,原因很简单,jdk1.6之后对synchronized做了大量的优化。为了减少获得锁和释放锁所带来的性能消耗,引入了“轻量级锁”和“偏向锁”来提高性能。
一、适应性自旋
降低了线程在等待锁的过程中的开销。因为线程从挂起到恢复是很耗时的,有些线程在挂起后很短的时间内就可以获取锁,通过漫无目的的循环让线程暂不挂起。适应性自旋表现在自选的循环次数是根据实际情况来定。
二、锁消除
删除一些没必要的加锁操作。
三、锁粗化
虽然减小锁的粒度,可以提高性能。但有些代码明明只需要加一把锁,你非要加多个??锁粗化可以把多次加锁和解锁合并成一次,用以提高效率。
四、轻量级锁
轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,就会导致轻量级锁膨胀为重量级锁。
五、偏向锁
引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次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
HashMap底层实现
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
Java单例模式实现
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模式
听到这个问题时,我是窃喜的,多么简单的问题,可是面试的时候,却不知道该怎么回答。
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
还有设计原理
偏应用的问题
因为时间和精力的情况,这里只做简单整理的问题。
一、redis事务是怎么做的?
答:redis的事务主要是通过multi(开启事务),exec(提交事务),watch(监控版本号)几个命令完成的。
二、如何实现抢购防超卖功能?
答:抢购,秒杀的场景下既要保证用户体验, 又要防超卖。其实很简单,减少数据库的调用,1000个商品限时抢购,就是1000个数字减一。通过加锁保证线程安全。使用缓存提高效率。
三、如何设计数据查询接口保证数据的安全和性能?
答:安全:服务器接口令牌验证;查询参数长度校验;查询参数格式校验(避免sql注入);
性能:索引优化;Ehcache本地缓存;redis缓存预热;
四、Nginx如何做权限拦截?
答:Nginx和lua可以实现权限拦截
五、2*16如何最快计算结果?
答:向左移动4位
六、架构如何用一个字段设置10个Boolean型权限?
答:用int型字段,分别用0,1表示false和true
七:为什么不用mysql做分布式锁?
答:我会从性能方面回答,用redis做分布式锁,是判断key值是否存在,存在则表示有锁。用Zookeeper做分布式锁,是判断临时节点是否存在,存在则表示有锁。而mysql做分布式锁在并发量高的情况下出现死锁。
八:分布式系统如何避免消息重复消费?
答:从生产者避免重复发送角度:将生产者发送的消息持久化到数据库中,如有相同的信息则不再保存;当生存者服务的事务完成后,消息服务会将数据库中的消息发送给消费者。
从消费者避免重复消费角度:消费者服务可能是集群,要考虑幂等性。查询和删除是天然的幂操作,所以我们要在更新和创建之前做判断,是否已经存在,是否已经更新。
九、你对我们公司的了解么?
答:.......
java面试整理的更多相关文章
- java面试整理(会持续更新..)
本人出道至今,经历了大大小小百余场战斗,,,下面整理的面试题有些有答案,有些没答案,那个谁说过:"要抱着怀疑的态度去编程,所以,即便有答案,也不一定正确,即便我本地正确,但是由于屏幕前的你和 ...
- JAVA 面试整理,面试汇总
1.JAVA是通过重写和重载来实现多态性的. 重写:同样的方法签名,不同的方法实现 重载:同样的方法名,不同的参数类型或参数个数 2.JAVA中如果存在不再使用的对象,但是程序又持有该对象的引用,就会 ...
- Java面试整理(精简版)
Java面向对象有哪些特征,如何应用 特征(OOP) 解释说明 通俗理解 关系联系 作用 封装 隐藏内部细节,只对外暴露访问方法 属性/方法封装,便于使用,限制不合理操作 类-类 低耦合,高内聚,增强 ...
- Java 面试/笔试题神整理 [Java web and android]
Java 面试/笔试题神整理 一.Java web 相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并 ...
- Java面试之Java基础问题答案口述整理
Java面试之基础问题答案口述整理 面向对象的理解 面向对象思想就是在计算机程序设计过程中,把具体事物的属性特性和行为特征抽象出来,描述成计算机事件的设计思想.它区别于面向过程的思想,强调的是通过调用 ...
- Java面试必备知识
JAVA面试必备知识 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可 ...
- Java面试宝典
相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消 ...
- Java 面试宝典-2017
http://www.cnblogs.com/nelson-hu/p/7190163.html Java面试宝典-2017 Java面试宝典2017版 一. Java基础部分........... ...
- Java面试宝典-2017
Java面试宝典2017版 一. Java基础部分........................................................................... ...
随机推荐
- Python入门 —— 06语音识别
Python 语音 实现语音操控的原理 语音操控分为语音识别和语音朗读两部分 我们使用speech模块实现语音模块(python 2.7) SAPI是微软Speech API , 是微软公司推出的语音 ...
- windows简易使用composer 安装国内镜像
1.下载composer.phar文件 地址: https://getcomposer.org/download/ 从下面选择一个 2.下载成功,新建项目(找到已有的项目文件夹)文件夹(D:\PHP ...
- Spring : JPA的单独使用
title: 如何单独使用spring data jpa 引用pom文件: <dependency> <groupId>org.springframework.data< ...
- hadoop生态搭建(3节点)-10.spark配置
# https://www.scala-lang.org/download/2.12.4.html# ================================================= ...
- C# IL DASM 使用-破解c#软件方法
IL DASM反编译工具 使用C#的猿人或多或少都会对微软的IL反编译工具(ildasm.exe)有所认识.我最早接触到这工具是公司同事使用他反编译exe程序,进行研读和修改.感觉他还是很强大. IL ...
- Python的scrapy之爬取链家网房价信息并保存到本地
因为有在北京租房的打算,于是上网浏览了一下链家网站的房价,想将他们爬取下来,并保存到本地. 先看链家网的源码..房价信息 都保存在 ul 下的li 里面 爬虫结构: 其中封装了一个数据库处理模 ...
- 网络文件系统nfs在ubuntu16.04的安装
1.搜索nfs-sudo apt-cache search nfs- 2.安装sudo apt-get install nfs-kernel-server 3.配置:/etc/exports /hom ...
- C指针(3)——指向指针的指针(程序讲解)
int **q可以分成两部分,即int* 和 (*q),后面的 “q” 中的* 表示q是一个指针变量,前面的int*表示指针变量q只能存放int*型变量的地址.int** q表示为指针变量q只能存放i ...
- redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect time out
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect ti ...
- Redis 常用数据结构命令
1. 字符串(string) 增加元素 set key value [EX seconds] [PX milliseconds] [NX|XX] EX seconds:为键设置秒级过期时间 PX mi ...