2019年丰巢科技Java面试题

1.bio与nio的区别
1、bio同步阻塞io:在此种⽅式下,⽤户进程在发起⼀个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,⽤户
进程才能运⾏。JAVA传统的IO模型属于此种⽅式!
2、nio同步⾮阻塞式I/O;java NIO采⽤了双向通道进⾏数据传输,在通道上我们可以注册我们感兴趣的事件:连接事件、读写事件;
NIO主要有三⼤核⼼部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进⾏操作,⽽NIO基于Channel和
Buffer(缓冲区)进⾏操作,数据总是从通道读取到缓冲区中,或者从缓冲区写⼊到通道中。Selector(选择区)⽤于监听多个通道的事件
(⽐如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。

  1. BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写⼊必须阻塞在⼀个线程内等待其完成。这⾥使⽤那个经典的烧开⽔例⼦,
    这⾥假设⼀个烧开⽔的场景,有⼀排⽔壶在烧开⽔,BIO的⼯作模式就是, 叫⼀个线程停留在⼀个⽔壶那,直到这个⽔壶烧开,才去
    处理下⼀个⽔壶。但是实际上线程在等待⽔壶烧开的时间段什么都没有做。
  2. NIO (New I/O):同时⽀持阻塞与⾮阻塞模式,但这⾥我们以其同步⾮阻塞I/O模式来说明,那么什么叫做同步⾮阻塞?如果还拿
    烧开⽔来说,NIO的做法是叫⼀个线程不断的轮询每个⽔壶的状态,看看是否有⽔壶的状态发⽣了改变,从⽽进⾏下⼀步的操作。
  3. AIO ( Asynchronous I/O):异步⾮阻塞I/O模型。异步⾮阻塞与同步⾮阻塞的区别在哪⾥?异步⾮阻塞⽆需⼀个线程去轮询所有
    IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开⽔中就是,为每个⽔壶上⾯装了⼀个开关,⽔
    烧开之后,⽔壶会⾃动通知我⽔烧开了。
    2.select与poll的区别
    1、io多路复⽤:
    1、概念:IO多路复⽤是指内核⼀旦发现进程指定的⼀个或者多个IO条件准备读取,它就通知该进程。
    2、优势:与多进程和多线程技术相⽐,I/O多路复⽤技术的最⼤优势是系统开销⼩,系统不必创建进程/线程,也不必维护这些进
    程/线程,从⽽⼤⼤减⼩了系统的开销。
    3、系统:⽬前⽀持I/O多路复⽤的系统调⽤有 select,pselect,poll,epoll。
    2、select:select⽬前⼏乎在所有的平台上⽀持,其良好跨平台⽀持也是它的⼀个优点。select的⼀个缺点在于单个进程能够监视的
    ⽂件描述符的数量存在最⼤限制,在Linux上⼀般为1024,可以通过修改宏定义甚⾄重新编译内核的⽅式提升这⼀限制,但是这样也
    会造成效率的降低。
    3、poll:它没有最⼤连接数的限制,原因是它是基于链表来存储的,但是同样有⼀个缺点:
    a. ⼤量的fd的数组被整体复制于⽤户态和内核地址空间之间,⽽不管这样的复制是不是有意义。
    b. poll还有⼀个特点是“⽔平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。
    epoll跟select都能提供多路I/O复⽤的解决⽅案。在现在的Linux内核⾥有都能够⽀持,其中epoll是Linux所特有,⽽select则应该是
    POSIX所规定,⼀般操作系统均有实现。
    3.zookeeper的⼯作原理
    1、定义:zookeeper是⼀种为分布式应⽤所设计的⾼可⽤、⾼性能且⼀致的开源协调服务,它提供了⼀项基本服务:分布式锁服务。
    后来摸索出了其他使⽤⽅法:配置维护、组服务、分布式消息队列、分布式通知/协调等。
    2、特点:
    1、能够⽤在⼤型分布式系统中;
    2、具有⼀致性、可⽤性、容错性,不会因为⼀个节点的错误⽽崩溃;
    3、⽤途:⽤户⼤型分布式系统,作协调服务⻆⾊;
    1、分布式锁应⽤:通过对集群进⾏master选举,来解决分布式系统中的单点故障(⼀主n从,主挂全挂)。
    2、协调服务;
    3、注册中⼼;
    4、原理:
    术语:
    数据结构Znode:zookeeper数据采⽤树形层次结构,和标准⽂件系统⾮常相似,树中每个节点被称为Znode;
    通知机制Watcher:zookeeper可以为所有的读操作(exists()、getChilden()及getData())设置watch,watch事件是⼀次
    性出发器,当watch的对象状态发⽣改变时,将会触发次对象上watch所对应的事件。watch事件将被异步的发送给客户端,并且zookeeper为
    watch机制提供了有序的⼀致性保证。
    基本流程:分布式锁应⽤场景
    1、传统的⼀主n从分布式系统,容易发⽣单点故障,传统解决⽅式是增加⼀个备⽤节点,定期给主节点发送Ping包,主节点回复
    ack,但是如果⽹络原因ack丢失,那么会出现两个主节点,造成数据混乱。
    2、zookeeper的引⼊可以管理两个主节点,其中挂了⼀个,会将另外⼀个作为新的主节点,挂的节点回来时担任备⽤节点;

4.cap理论
1、概念:⼀个分布式系统最多只能同时满⾜⼀致性(Consistency)、可⽤性(Availability)和分区容错性(Partition tolerance)这
三项中的两项。
2、⼀致性:更新操作成功并返回客户端完成后,所有节点在同⼀时间的数据完全⼀致,所以,⼀致性,说的就是数据⼀致性。
3、可⽤性:服务⼀直可⽤,⽽且是正常响应时间。
4、分区容错性:分布式系统在遇到某节点或⽹络分区故障的时候,仍然能够对外提供满⾜⼀致性和可⽤性的服务。
5.⼆段式满⾜cap理论的哪两个理论
两阶段提交协议在正常情况下能保证系统的强⼀致性,但是在出现异常情况下,当前处理的操作处于错误状态,需要管理员⼈⼯⼲预
解决,因此可⽤性不够好,这也符合CAP协议的⼀致性和可⽤性不能兼得的原理。
6.线程池的参数配置,为什么java官⽅提供⼯⼚⽅法给线程池
1、线程池简介:
2、核⼼参数:
3、⼯⼚⽅法作⽤:ThreadPoolExecutor类就是Executor的实现类,但ThreadPoolExecutor在使⽤上并不是那么⽅便,在实例化时需
要传⼊很多歌参数,还要考虑线程的并发数等与线程池运⾏效率有关的参数,所以官⽅建议使⽤Executors⼯程类来创建线程池对
象。
7.分布式框架dubbo的好处,不⽤dubbo可不可以。为什么要使⽤分布式
1、dubbo好处:
1、远程通讯: 提供对多种基于⻓连接的NIO框架抽象封装, 包括多种线程模型,序列化,以及“请求-响应”模式的信息交换⽅
式。
2、软负载均衡及容错机制: 提供基于接⼝⽅法的透明远程过程调⽤,包括多协议⽀持,以及软负载均衡,失败容错,地址路由,
动态配置等集群⽀持。
可在内⽹替代F5等硬件负载均衡器,降低成本,减少单点。
3、服务⾃动注册与发现: 基于注册中⼼⽬录服务,使服务消费⽅能动态的查找服务提供⽅,使地址透明,使服务提供⽅可以平滑
增加或减少机器 。
4、提供完善的管理控制台dubbo-admin与简单的控制中⼼dubbo-monitor
5、Dubbo提供了伸缩性很好的插件模型,很⽅便进⾏扩展(ExtensionLoader)
2、不⽤dubbo可不可以:可以,使⽤springcloud。
3、分布式作⽤:
a. 系统之间的耦合度⼤⼤降低,可以独⽴开发、独⽴部署、独⽴测试,系统与系统之间的边界⾮常明确,排错也变得相当容易,
开发效率⼤⼤提升。
b. 系统之间的耦合度降低,从⽽系统更易于扩展。我们可以针对性地扩展某些服务。假设这个商城要搞⼀次⼤促,下单量可能会
⼤⼤提升,因此我们可以针对性地提升订单系统、产品系统的节点数量,⽽对于后台管理系统、数据分析系统⽽⾔,节点数量维
持原有⽔平即可。
c. 服务的复⽤性更⾼。⽐如,当我们将⽤户系统作为单独的服务后,该公司所有的产品都可以使⽤该系统作为⽤户系统,⽆需重
复开发。
8.七个垃圾回收器之间如何搭配使⽤

  1. Serial New收集器是针对新⽣代的收集器,采⽤的是复制算法;
  2. Parallel New(并⾏)收集器,新⽣代采⽤复制算法,⽼年代采⽤标记整理;
  3. Parallel Scavenge(并⾏)收集器,针对新⽣代,采⽤复制收集算法;
  4. Serial Old(串⾏)收集器,新⽣代采⽤复制,⽼年代采⽤标记清理;
  5. Parallel Old(并⾏)收集器,针对⽼年代,标记整理;
  6. CMS收集器,基于标记清理;
  7. G1收集器(JDK):整体上是基于标记清理,局部采⽤复制;
    综上:新⽣代基本采⽤复制算法,⽼年代采⽤标记整理算法。cms采⽤标记清理;
    9.接⼝限流⽅案
  8. 限制 总并发数(⽐如 数据库连接池、线程池)
  9. 限制 瞬时并发数(如 nginx 的 limit_conn 模块,⽤来限制 瞬时并发连接数)
  10. 限制 时间窗⼝内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率)
  11. 限制 远程接⼝ 调⽤速率
  12. 限制 MQ 的消费速率
  13. 可以根据 ⽹络连接数、⽹络流量、CPU 或 内存负载 等来限流
    10.ConcurrentHashMap使⽤原理
    1、⼯作机制(分⽚思想):它引⼊了⼀个“分段锁”的概念,具体可以理解为把⼀个⼤的Map拆分成N个⼩的segment,根据key.hashCode()
    来决定把key放到哪个HashTable中。可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。
    2、应⽤:当读>写时使⽤,适合做缓存,在程序启动时初始化,之后可以被多个线程访问;
    3、hash冲突:
    1、简介:HashMap中调⽤hashCode()⽅法来计算hashCode。由于在Java中两个不同的对象可能有⼀样的hashCode,所以不同的键可
    能有⼀样hashCode,从⽽导致冲突的产⽣。
    2、hash冲突解决:使⽤平衡树来代替链表,当同⼀hash中的元素数量超过特定的值便会由链表切换到平衡树
    4、⽆锁读:ConcurrentHashMap之所以有较好的并发性是因为ConcurrentHashMap是⽆锁读和加锁写,并且利⽤了分段锁(不是在所有的
    entry上加锁,⽽是在⼀部分entry上加锁);
    读之前会先判断count(jdk1.6),其中的count是被volatile修饰的(当变量被volatile修饰后,每次更改该变量的时候会将更改结果写到
    系统主内存中,利⽤多处理器的缓存⼀致性,其他处理器会发现⾃⼰的缓存⾏对应的内存地址被修改,就会将⾃⼰处理器的缓存⾏设置为失效,并强制
    从系统主内存获取最新的数据。),故可以实现⽆锁读。
    11.解决map的并发问题⽅案
    HashMap不是线程安全的;Hashtable线程安全,但效率低,因为是Hashtable是使⽤synchronized的,所有线程竞争同⼀把锁;⽽
    ConcurrentHashMap不仅线程安全⽽且效率⾼,因为它包含⼀个segment数组,将数据分段存储,给每⼀段数据配⼀把锁,也就是所谓的锁分段技
    术。
    12.什么是协程,以及实现要点
    1、⽣产者/消费者模式不是⾼性能的实现:
    1.涉及到同步锁。
    2.涉及到线程阻塞状态和可运⾏状态之间的切换。
    3.涉及到线程上下⽂的切换。
    2、协成定义:协程,英⽂Coroutines,是⼀种⽐线程更加轻量级的存在。正如⼀个进程可以拥有多个线程⼀样,⼀个线程也可以拥
    有多个协程。最重要的是,协程不是被操作系统内核所管理,⽽完全是由程序所控制(也就是在⽤户态执⾏)。
    这样带来的好处就是性能得到了很⼤的提升,不会像线程切换那样消耗资源。
    3、协成优点:协程的暂停完全由程序控制,线程的阻塞状态是由操作系统内核来进⾏切换。因此,协程的开销远远⼩于线程的开
    销。
    4、实现:
    1、Lua语⾔
    Lua从5.0版本开始使⽤协程,通过扩展库coroutine来实现。
    2、Python语⾔
    正如刚才所写的代码示例,python
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值