百度java工程师社招面经(接上帖)
Spring 框架中用到了哪些设计模式
> 代理模式—在 AOP 和 remoting 中被用的比较多。
> 单例模式—在 spring 配置文件中定义的 bean 默认为单例模式。
> 模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate,
JpaTemplate。
> 前端控制器—Spring 提供了 DispatcherServlet 来对请求进行分发。
> 视图帮助(View Helper )—Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码
整合在视图里。
> 依赖注入—贯穿于 BeanFactory / ApplicationContext 接口的核心理念。
> 工厂模式—BeanFactory 用来创建对象的实例。
Netty
为什么选择Netty
> 1) API 使用简单,开发门槛低;
> 2) 功能强大,预置了多种编解码功能,支持多种主流协议;
> 3) 定制能力强,可以通过 ChannelHandler 对通信框架进行灵活的扩展;
> 4) 性能高,通过与其它业界主流的 NIO 框架对比,Netty 的综合性能最优;
> 5) 成熟、稳定,Netty 修复了已经发现的所有 JDK NIO BUG,业务开发人员不需要再为
NIO 的 BUG 而烦恼;
> 6) 社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会被
加入;
> 7) 经历了大规模的商业应用考验,质量已经得到验证。在互联网、大数据、网络游戏、
企业应用、电信软件等众多行业得到成功商用,证明了它可以完全满足不同行业的商业应
用。
> 正是因为这些优点,Netty 逐渐成为 Java NIO 编程的首选框架。
说说业务中,Netty 的使用场景
> 构建高性能、低时延的各种 Java 中间件,例如 MQ、分布式服务框架、ESB 消息总线等,
Netty 主要作为基础通信框架提供高性能、低时延的通信服务;
> 公有或者私有协议栈的基础通信框架,例如可以基于 Netty 构建异步、高性能的
WebSocket 协议栈;
> 各领域应用,例如大数据、游戏等,Netty 作为高性能的通信框架用于内部各模块的数据
分发、传输和汇总等,实现模块之间高性能通信。原生的NIO 在 JDK 1.7 版本存在 epoll bug
> 它会导致 Selector 空轮询,最终导致 CPU 100%。官方声称在 JDK 1.6 版本的 update18 修
复了该问题,但是直到JDK 1.7 版本该问题仍旧存在,只不过该 BUG 发生概率降低了一些
而已,它并没有得到根本性解决。
什么是TCP 粘包/拆包
> 1、要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
> 2、待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
> 3、要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出
去,将会发生粘包。
> 4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。
TCP 粘包/拆包的解决办法
> 1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在
接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。
> 2、发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次
从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
> 3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将
不同的数据包拆分开。
Netty 线程模型
> 首先,Netty 使用 EventLoop 来处理连接上的读写事件,而一个连接上的所有请求都保证
在一个EventLoop 中被处理,一个 EventLoop 中只有一个 Thread,所以也就实现了一个连
接上的所有事件只会在一个线程中被执行。一个EventLoopGroup 包含多个 EventLoop,可
以把一个EventLoop 当做是 Reactor 线程模型中的一个线程,而一个 EventLoopGroup 类似
于一个ExecutorService
说说Netty 的零拷贝
> “零拷贝”是指计算机操作的过程中,CPU 不需要为数据在内存之间的拷贝消耗资源。而
它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User
Space)而直接在内核空间(Kernel Space)中传输到网络的方式。
Netty 内部执行流程
> 1. Netty 的接收和发送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接内存进行
Socket 读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP
BUFFERS)进行 Socket 读写,JVM 会将堆内存 Buffer 拷贝一份到直接内存中,然后才写入
Socket 中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。> 2. Netty 提供了组合 Buffer 对象,可以聚合多个 ByteBuffer 对象,用户可以像操作一
个Buffer 那样方便的对组合 Buffer 进行操作,避免了传统通过内存拷贝的方式将几个小
Buffer 合并成一个大的 Buffer。
> 3. Netty 的文件传输采用了 transferTo 方法,它可以直接将文件缓冲区的数据发送到