面试稿·Java
- 一、Java基础
- 二、Spring·前后端分离架构
一、Java基础
1、Java数据结构
2、Java网络编程
2.1 TCP&UDP
2.2 Netty
2.2.1 Netty项目
2.2.1.1 Push(推) & Pull(拉)
Pull 模式的另外一个好处是 consumer 可以自主决定是否批量的从 broker 拉取数据。Push 模式必须在不知道下游 consumer 消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免 consumer 崩溃而采用较低的推送速率, 将可能导致一次只推送较少的消息而造成浪费。Pull 模式下, consumer 就可以根据自己的消费能力去决定这些策略。
Pull 有个缺点是,如果 broker 没有可供消费的消息,将导致 consumer 不断在循环中轮询,直到新消息到 t 达。为了避免这点,Kafka 有个参数可以让 consumer 阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发送)。
3、Java多线程
3.1 Java并发基础(锁)
3.1.1 多线程活跃性问题
- 死锁(一个山上的景区,只有一天路,一辆车要上山去景区、一辆车逛完了要下山离开景区,两车互不相让)
- 活锁(互相谦让)
- 饥饿锁(低优先级线程一直拿不到资源,无法正常工作)
3.1.2 并发级别
- 阻塞(synchronized和可重入锁)
- 无饥饿(公平锁)
- 无障碍(乐观锁)
- 无锁(原子类、Disruptor)
- 无等待()
3.1.3 同步控制
3.1.3.1 可重入锁
lock、unlock、tryLock(限时等待)
3.1.4 锁优化
3.1.4.1 偏向锁
-XX:+UseBiasedLocking
3.1.4.2 自旋锁
3.1.4.3 锁消除
-XX:+DoEscapeAnalysis
-XX:+EliminateLocks
3.2 JDK并发包(J.U.C)
3.2.1 线程复用:线程池
- FixedThreadPool(固定数量线程池)
- CachedThreadPool
- ScheduledThreadPool
- SingleThreadExecutor(只有一个线程的线程池)
- SingleThreadScheduledExecutor(只有一个线程且周期性定时执行某任务的线程池)
3.2.2 自定义线程池
public ThreadPoolExecutor(
int corePoolSize, //线程数量
int maximumPoolSize, //最大线程数量
long keepAliveTime, //空闲线程存活时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //任务队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler //拒绝策略)
3.2.2.1 合理的线程池大小
- 合理的线程池大小:
- I/O密集型:CPU核数 *(1+I/O耗时/CPU耗时)amp工具
- CPU密集型:CPU核数 + 1
Runtime.getRuntime().availableProcessors()
3.2.3 并发容器
3.2.3.1 BlockingQueue
ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue
3.3 并行模式&算法
3.4 Java8并发(CompletableFuture)
3.5 使用建议
4、Java虚拟机
4.1 内存管理
- 虚拟机的分代回收,又分为新生代(Eden、S0、S1)和老年代。对新生代的回收为Minor GC,对老年代的回收为Major GC。
- Stop The World:清理时暂停其他工作线程。
4.2 引用
- 强引用:大部分场景都是强引用
- 软引用:缓存(内存不足即回收)
- 弱引用:缓存(发现即回收)
- 虚引用:对象的回收跟踪
4.3 GC详解
4.4 性能调优
- CPU(线程上下文切换、频繁GC,解决方案:使用线程池、减少线程数量及线程间的切换)
- 内存(合理设置各个代的大小、选择合适的GC策略)
- I/O(异步代替同步、尽量批量写入、减少IO次数)
5、Java8新特性
5.1 Java8接口新特性
在Java8中,可以为接口添加 静态方法 和 默认方法
- 实现类不能调用接口中的 静态方法、只能通过接口调用
- 实现类可以 调用和重写 接口中的 默认方法
- 实现类同时继承了一个有与接口同名同参的 默认方法 的父类、根据类优先原则、在子类没有重写该方法时、默认调用父类的方法
5.2 Java8注解新特性
在Java8中,注解方面新增了 可重复注解 和 类型注解
5.3 HashMap源码 JDK1.7 vs JDK1.8
底层结构有变化、JDK1.8中HashMap的底层结构是:数组+链表+红黑树
5.4 Java8其他新特性:函数式接口、方法引用
Lambda表达式、Stream API
二、Spring·前后端分离架构
1、Spring
1.1 Spring 编程模型
Spring FrameWork 一共涉及到5种编程模型、面向对象的编程模型(接口、对象、设计模式)、面向切面的编程模型(动态代理、字节码提升)、注解驱动的编程模型、事件驱动的编程模型、模块驱动的编程模型
1.2 Spring FrameWork 有哪些核心模块?
spring-core(资源管理、泛型处理)、spring-beans(依赖注入)、spring-context(注解驱动、事件驱动、模块驱动)、spring-webmvc(Servlet)、spring-aop(动态代理、字节码提升)
1.3 Spring IOC
1.3.1 什么是IOC
Spring管理Bean的容器
1.3.2 BeanFactory 和 FactoryBean 有什么区别
BeanFactory是一种Spring IOC的容器
FactoryBean是创建Bean的一个工厂方法
1.3.3 BeanFactory 和 ApplicationContext有什么区别
ApplicationContext是BeanFactory的一个子接口,在BeanFactory上进行了很多扩展、比如扩展了消息国际化(MessageSource)、环境可配置(EnvironmentCapable)、应用事件发布(ApplicationEventPublisher)和资源模式解析(ResourcePatternResolver)等
1.3.4 @Autowired 与 @Resource有什么区别
IOC容器中允许按照名字或类型获取Bean
@Autowired根据类型进行注入、@Resource根据名字注入
@Primary 和 @Quelifier 消除歧义 配合@Autowired使用
@Primary(优先)、@Quelifier(限定)有参数的构造方法装配
1.3.5 延迟加载的好处
没有在SpringIoC容器初始化时就执行了Bean的实例化和依赖注入。
1.3.6 Spring IOC 生命周期
读取和解析配置元信息(通过BeanDefinition可以注册)、启动Spring上下文、实例化Bean、依赖注入(初始化Bean)、(Bean生存期)关闭Spring上下文(销毁Bean)
BeanNameAware , BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean
1.4 Spring MVC
- ApplicationContext初始化时用Map保存所有URL和Controller类的对应关系。
- 根据请求URL找到对应的Controller,并从Controller中找到处理请求的方法。
- 将Request参数绑定到方法的形参上,执行方法处理请求,并返回结果视图。
- 主要有DispatcherServlet、视图解析器(ViewResolver)和处理适配器(HandlerAdapter)
- DispatcherServlet是前端控制器,主要负责接收Request并将Request转发给对应的处理组件。
- HandlerMapping主要完成URL到Controller映射的组件。
- Controller主要处理Request,并返回ModelAndView对象。
- ④、⑤、⑥是视图解析器解析ModelAndView对象并返回对应的视图给客户端的过程。
1.4.1 Controller
mv.setViewName("")