面试相关

一、微服务的理解
什么是微服务?
1、由一些独立的服务共同组成系统
2、单独部署,跑在自己的进程里
3、每个服务为独立的业务开发
4、分布式的管理
特点
1、组件化与多服务
2、围绕业务组建团队
3、做产品而不是做项目
4、智能端点与弱管道
5、去中心化管理数据
6、基础设施自动化
优点
1、提升开发交流,每个服务足够内聚,足够小,代码容易理解
2、服务独立测试、部署、升级、发布
3、容易扩大开发团队,可以针对每个服务组建开发团队
4、提高容错性,一个服务的内存泄露并不会让整个系统瘫痪
5、新技术的应用,系统不会被长期限制在某个技术栈上
缺点
1、提高了系统的复杂度
2、开发人员要处理分布式系统的复杂性
3、服务之间的分布式通信问题
4、服务的注册与发现问题
5、服务之间的分布式事务问题
6、数据隔离带来的报表处理问题
7、服务之间的分布式一致性问题
8、服务管理的复杂性,服务的编排
9、不同服务实例的管理

二、类加载机制
概述
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
类加载的生命周期包括以下七个阶段:
加载、验证、准备、解析、初始化、使用卸载,其中验证、准备和解析3个部分统称为连接,解析可能在初始化前也可能在初始化后开始,其它阶段顺序确定。

加载
加载过程主要完成三件事情:
1、通过类的全限定名来获取定义此类的二进制字节流
2、将这个类字节流代表的静态存储结构转为方法区的运行时数据结构
3、在堆中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口。
这个过程主要就是类加载器完成。

校验
此阶段主要确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。
1、文件格式验证:基于字节流验证。
2、元数据验证:基于方法区的存储结构验证。
3、字节码验证:基于方法区的存储结构验证。
4、符号引用验证:基于方法区的存储结构验证。

准备
为类变量分配内存,并将其初始化为默认值。(此时为默认值,在初始化的时候才会给变量赋值)即在方法区中分配这些变量所使用的内存空间。例如:
public static int value = 123;
此时在准备阶段过后的初始值为0而不是123;将value赋值为123的putstatic指令是程序被编译后,存放于类构造器方法之中.特例:
public static final int value = 123;
此时value的值在准备阶段过后就是123。

解析
把类型中的符号引用转换为直接引用。
符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。
直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在
主要有以下四种:
1、类或接口的解析
2、字段解析
3、类方法解析
4、接口方法解析

初始化
初始化阶段是执行类构造器方法的过程。方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证方法执行之前,父类的方法已经执行完毕。如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成()方法。
java中,对于初始化阶段,有且只有以下五种情况才会对要求类立刻“初始化”(加载,验证,准备,自然需要在此之前开始):
1、使用new关键字实例化对象、访问或者设置一个类的静态字段(被final修饰、编译器优化时已经放入常量池的例外)、调用类方法,都会初始化该静态字段或者静态方法所在的类。
2、初始化类的时候,如果其父类没有被初始化过,则要先触发其父类初始化。
3、使用java.lang.reflect包的方法进行反射调用的时候,如果类没有被初始化,则要先初始化。
4、虚拟机启动时,用户会先初始化要执行的主类(含有main)
5、jdk 1.7后,如果java.lang.invoke.MethodHandle的实例最后对应的解析结果是 REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄,并且这个方法所在类没有初始化,则先初始化。

双亲委派机制工作过程
如果一个类加载器收到了类加载器的请求.它首先不会自己去尝试加载这个类.而是把这个请求委派给父加载器去完成.每个层次的类加载器都是如此.因此所有的加载请求最终都会传送到Bootstrap类加载器(启动类加载器)中.只有父类加载反馈自己无法加载这个请求(它的搜索范围中没有找到所需的类)时.子加载器才会尝试自己去加载。这些类加载器之间的关系一般不是继承,而是使用组合来复用父加载器的代码。
双亲委派层次关系:启动类加载器<—扩展类加载器<—应用程序加载器<—自定义类加载器
双亲委派模型的优点:java类随着它的加载器一起具备了一种带有优先级的层次关系.
例如类java.lang.Object,它存放在rt.jart之中.无论哪一个类加载器都要加载这个类.最终都是双亲委派模型最顶端的Bootstrap类加载器去加载.因此Object类在程序的各种类加载器环境中都是同一个类.相反.如果没有使用双亲委派模型.由各个类加载器自行去加载的话.如果用户编写了一个称为“java.lang.Object”的类.并存放在程序的ClassPath中.那系统中将会出现多个不同的Object类.java类型体系中最基础的行为也就无法保证.应用程序也将会一片混乱.

三、JVM相关及垃圾回收
JVM虚拟机分为程序计数器、虚拟机栈、本地方法栈、堆、方法区。
1、程序计数器:是线程私有的,可以看作是当前线程所执行的字节码的行号指示器,是唯一一个没有规定任何OutOfMemoryError情况的区域。
2、虚拟机栈:也是线程私有的,生命周期与线程相同。每个方法执行时都会创建一个栈帧,每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。通常说的栈区指的是虚拟机栈中的局部变量表,存放了各种基本数据类型,对象的引用和returnAddress类型(指向了一条字节码指令的地址)。
3:本地方法栈为虚拟机使用到的Native方法服务
4、是被所有线程共享的一块内存区域,唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,是垃圾收集器管理的主要区域,其中新生代和老年代都在堆区,堆可以处于物理上不连续但逻辑上连续的内存空间中
5、方法区:是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。永久代在方法区。运行时常量池是方法区一部分。

一些常用JVM参数
-Xmx:JVM最大可用内存
-Xms:JVM初始内存
-Xmn:年轻代大小
-Xss:每个线程的堆栈大小

内存溢出
是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;
比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄漏
是指程序在申请内存后,无法释放已申请的内存空间,
一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
内存泄漏最后会导致内存溢出。

垃圾回收
按照基本回收策略分
引用计数(Reference Counting):
比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。

标记-清除(Mark-Sweep):
此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。

复制(Copying):
此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。

标记-整理(Mark-Compact):
此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。

年轻代:
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。年轻代使用复制算法
年老代:
在年轻代中经历了N次垃圾回收后仍然存活的对象(也可能Survivor区还没有满),就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代发生GC时使用标记-整理方法
持久代:
用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。

四、Spring相关
Spring 的优点?
1、降低了组件之间的耦合性 ,实现了软件各层之间的解耦
2、可以使用容易提供的众多服务,如事务管理,消息服务等
3、容器提供单例模式支持
4、容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
5、容器提供了众多的辅助类,能加快应用的开发
6、spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
7、spring属于低侵入式设计,代码的污染极低
8、独立于各种应用服务器
9、spring的DI机制降低了业务对象替换的复杂性
10、Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部

什么是DI机制?
依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的两种方式,设值注入和构造注入。
设值注入的优点:直观,自然
构造注入的优点:可以在构造器中决定依赖关系的顺序。

什么是AOP?
面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面
1.面向切面编程提供声明式事务管理
2.spring支持用户自定义的切面

面向切面编程(aop)是对面向对象编程(oop)的补充,
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,从而获得步骤之间的逻辑划分。

aop框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性

Spring的事务管理机制实现的原理,就是通过这样一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的 方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。Spring中的AOP实 现更为复杂和灵活,不过基本原理是一致的。

五、数据结构及复杂度
红黑树:时间复杂度是O(logn)
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

六、算法及复杂度
直接插入 O(n²)
希尔排序 O(n²)
直接选择 O(n²)
冒泡排序 O(n²)
快速排序 O(n*log2n)

七、dubbo zookeeper
Dubbo是什么?
Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架。
为什么要用Dubbo?
使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
zookeeper作为注册中心
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值