- JVM说一下(JVM面试题)
(1) Jvm内存图
(2) 什么是堆和栈?
- 多线程的实现方式(4种)
(1) 继承Thread类,重写run方法
(2) 实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
(3) 通过Callable和FutureTask创建线程
(4) 通过线程池创建线程
- 有没有尝试进行多机redis 的部署?如何保证数据一致的?
主从复制,读写分离
一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。
- 线程池(java线程池面试题)
(1) 什么是线程池?
① 线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理。
② 如果每个请求都创建一个线程去处理,那么服务器的资源很快就会被耗尽,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
(2) 为什么要使用线程池?
① 创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。这样频繁的创建线程和销毁线程,再加上业务工作线程,消耗系统资源的时间,可能导致系统资源不足。(我们可以把创建和销毁的线程的过程去掉)
(3) 线程池有什么作用?
线程池作用就是限制系统中执行线程的数量。
① 提高效率 创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。
② 方便管理 可以编写线程池管理代码对池中的线程同一进行管理,比如说启动时有该程序创建100个线程,每当有请求的时候,就分配一个线程去工作,如果刚好并发有101个请求,那多出的这一个请求可以排队等候,避免因无休止的创建线程导致系统崩溃。
(4) 说说几种常见的线程池及使用场景
① newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
② newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
③ newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
④ newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
- Redis是单例还是多例?
(1) 单例模式
5.2 单例模式有以下3个特点:
① 它必须有一个构造函数,而且构造函数必须为私有
② 必须有一个保存实例的静态成员变量
③ 拥有一个访问这个实例的公共的静态方法
- 设计模式23种,说一下!你会的单独说一下
(1) 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
(2) 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
(3) 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
(4) 其实还有两类:并发型模式和线程池模式
- 高并发怎么解决?(如何解决高并发问题)
(1) HTML静态化:效率最高,消耗最小
(2) 图片服务器分离:独立的图片服务器,甚至多台图片服务器
(3) 数据库集群和库表散列
(4) 缓存
(5) 镜像
(6) 负载均衡:负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。
- 多态使用的好处?
(1) 提高了代码的维护性(继承保证)
(2) 提高了代码的扩展性
- MySQL有几种事务特性?分别描述一下!(4种)
(1) 原子性:事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
(2) 一致性:事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账户金额之和在事务前后应该是保持不变的。
(3) 隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰
(4) 持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。
- 进程和线程的关系以及区别?
(1)定义:
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
(2)关系:
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
- Spring AOP 代理是什么?
(1) 代理是使用非常广泛的设计模式。简单来说,代理是一个看其他像另一个对象的对象,但它添加了一些特殊的功能。
(2) Spring AOP是基于代理实现的。AOP 代理是一个由 AOP 框架创建的用于在运行时实现切面协议的对象。
(3) Spring AOP默认为 AOP 代理使用标准的 JDK 动态代理。这使得任何接口(或者接口的集合)可以被代理。
(4) Spring AOP 也可以使用 CGLIB 代理。这对代理类而不是接口是必须的。
14.eureka和zookeeper都可以提供服务注册与发现的功能,请说说两个的区别(优点)?
(1)zookeeper: 当主节点故障时,zk会在剩余节点重新选择主节点,耗时过长,虽然最终能够恢复,但 是选取主节点期间会导致服务不可用,这是不能容忍的。
eureka: 各个节点是平等的,一个节点挂掉,其他节点仍会正常保证服务。
(2)总结: 著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。因此,Zookeeper 保证的是CP, Eureka 则是AP。
- Ribbon 与 Nginx 的区别?
(1) nginx 是客户端所有请求统一交给 nginx,由 nginx 进行实现负载均衡请求转发,属于服务器端负载均衡。既请求由 nginx 服务器端进行转发。
Nginx 适合于服务器端实现负载均衡 比如 Tomcat
(2) Ribbon 是从 eureka 注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮询负载均衡策略。既在客户端实现负载均衡。Ribbon 适合与在微服务中 RPC 远程调用实现本地服务负载均衡,比如 Dubbo、SpringCloud 中都是采用本地负载均衡。
- Ribbon 怎么实现客户端负载均衡?
由于 Spring Cloud Ribbon 的封装, 我们在微服务架构中使用客户端负载均衡调用非常简单, 只需要如下两步:
(1)启动多个服务提供者实例并注册到一个服务注册中心或是服务注册中心集群
(2)服务消费者通过被@LoadBalanced 注解修饰过的 RestTemplate 来调用服务提供者。
这样,我们就可以实现服务提供者的高可用以及服务消费者的负载均衡调用。
14. Spring MVC 运行流程
(1) 用户发请求–>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制。
(2) DispatcherServlet–>HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器,多个HandlerInterceptor拦截器)。
(3) DispatcherServlet–>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器。
(4) HandlerAdapter–>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理,并返回一个ModelAndView对象(包含模型数据,逻辑视图名)
(5) ModelAndView的逻辑视图名–>ViewResolver,ViewResoler将把逻辑视图名解析为具体的View。
(6) View–>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构
(7) 返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户。
15. IOC底层实现原理
IoC,控制反转 ,是一种设计思想,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。 是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方。它是通过反射机制+工厂模式实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在Map中的类属性注入到类中。
DI—Dependency Injection,即“依赖注入”由容器动态的将某个依赖关系注入到组件之中。
- AOP底层实现原理
面向切面编程,利用一种称为“横切”的技术,剖解开封装的对象内部。将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来。便于减少系统的重复代码,降低模块间的耦合度。实现AOP的技术,主要分为两大类:一是采用动态代理技术,Spring默认使用Jdk动态代理,如果目标类不是接口选择cglib动态代理,二是采用静态织入的方式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。