java常规问题综述(干货)

1.阐述一下你对Java平台的理解?

Java平台包括java语言,class文件结构,jvm,api类库,第三方库,各种编译、监控和诊断工具等。

Java语言是一种面向对象的高级语言;通过平台中立的class文件格式和屏蔽底层硬件差异的jvm实现‘一次编写,到处运行’;通过‘垃圾收集器’管理内存的分配和回收。

jvm通过使用class文件这种中间表示和具体语言解耦,使得任何在源码早期编译过程中以class文件为中间表示或者能够转换成class文件的具体语言,都能运行jvm之上,也就可以使用jvm的各种特性。

api类库主要包含集合、IO/NIO、网络、并发等。

第三方库包括各种商业机构和开源社区的java库,如spring、mybatis等。

各种工具如javac、jconsole、jmap、jstack等。

 

2.如何解决临界资源竞争?

在我们的日常开发中,经常会遇到不同的任务会去访问临界资源的场景,如果不采取相应措施,会导致应用程序处于不正确的状态。资源的竞争主要包括进程内的资源竞争和跨进程的资源竞争。

对于进程内的资源竞争,通常采用锁、信号量或者线程封闭技术。锁主要有jdk自带的隐式锁,juc包下的显示锁,以及jdk使用自旋+cup的cas指令实现的一种乐观锁;线程封闭主要包含栈封闭技术(主要指使用局部变量),以及线程本地存储(ThreadLocal)的方式。

对于跨进程的资源竞争,通常使用分布式锁+业务状态二次校验,按照实现方式又可以分为db实现、zk实现、通过缓存实现;db实现又包含悲观锁、乐观锁、以及创建辅助表来实现;zk实现主要通过创建、删除目录来提现分布式锁的获取和释放;缓存实现方式例如使用redis的nx+expire来实现或者说更好一点的使用nx+getset来实现。

 

3.如何解决高并发?

高并发是指系统再一段时间内遭遇流量洪峰,如果系统没有采取相应的措施可能会直接导致系统宕机。提高系统的并发性能需要从多个方面入手,包括硬件、网络、系统架构、数据库的优化、程序的优化等。硬件配置比如说内存大小、cpu核心数和处理能力、硬盘、网卡带宽等;网络拓扑的优化比如整个系统中的各个服务节点单机房部署或者单机器部署等减少网络开销;数据库层面的优化比如存储引擎的选择、索引的添加、读写分离、按业务域做垂直分库、水平分表等;系统架构上的优化又包括前端和后端,前端的优化比如动静分离、页面静态化、CDN加速等,后端优化又包括技术栈的选型(Spring Cloud vs Dubbo)、

通信协议的选择、使用缓存降低db压力、使用多线程/mq异步处理任务、网关层做负载均衡和流量控制、非核心服务的降级、水平扩展服务节点、jvm的优化(是以server模式还是以clien模式运行/各内存区域的大小/垃圾收集器的选择等);程序上的优化比如使用优化的数据结构和算法、sql的优化等。

 

4.为什么使用mq?

MQ,是一种跨进程的通信机制,用于上下游传递消息。我们平常使用mq主要是让上下游应用解耦,或者做异步提高系统并发性能和吞吐量。

缺点:系统更复杂、消息传递路径变长、会有丢消息或者消息重发等问题、上游无法知道下游的执行结果

应用场景:数据驱动的任务依赖、上游不关心多下游执行结果、异步返回执行时间长

 

5.谈谈你对ioc和aop的理解?

<1>ioc原理

IOC容器通过配置文件描述bean的配置信息以及bean之间的依赖关系,利用反射实例化bean并建立bean之间的关系,将对bean的声明周期管理以及维护bean之间依赖关系的工作由程序员侧反转给容器去处理,使得程序员只要关心业务逻辑的处理。

<2>aop原理

AOP使用“横切”技术把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

<3>aop案例:事务

spring的事务利用aop将事务功能和业务相分离,他让业务代码和事务代码使用同一个底层JDBC连接,使用这个connection进行事务的开启、提交、回滚。

Spring的事务体系主要提供了3大核心接口:

  • PlatformTransactionManager : 事务管理器
  • TransactionDefinition : 事务的一些基础信息,如超时时间、隔离级别、传播属性等
  • TransactionStatus : 事务的一些状态信息,如是否是一个新的事务、是否已被标记为回滚

 

6.谈谈你对jmm的理解?

Java虚拟机规范定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,实现平台一致性。

Java内存模型的主要目标是定义程序中对共享变量的访问规则,它规定所有的共享变量都存储在主内存中,每条线程有自己的工作内存,工作内存中保存变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成。

Java内存模型定义了八种操作来完成主内存与工作内存之间的具体交互,lock、unlock、read、load、use、assign、store、write;

jmm保证对基本数据类型的变量的读取和赋值操作是原子性操作;通过volatile关键字、synchronized和Lock来保证可见性;通过volatile关键字防止指令重排序来保证一定的“有序性”,happens-before 原则保证一定的“有序性”;

 

7.什么是幂等?怎么实现?

定义:一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。

1.查询

2.唯一索引

3.悲观锁

4.乐观锁

5.分布式锁

 

8.简述java异常处理机制?

Java异常处理机制的基类为Throwable类,只有Throwable类的实例才能被抛出和捕获。它有2大子类,Error和Exception。Error主要指不可恢复的错误,例如OutOfMemeryError,当jvm遇到Error时会不可恢复,这种错误不需要处理;Exception是指能够处理的异常,分为检查异常和非检查异常,检查异常需要捕获,否则编译不通过,非检查异常可根据需求看情况是否捕获。

注意事项:

1.捕获特定的异常

2.不能吞掉异常

3.只捕获会出现异常的代码块(异常会带来额外的开销)

4.不要用异常控制流程 (if/else效率更高)

5.java每实例化一个Exception都会对当前栈进行快照

 

9.谈谈final、finally、finalize有什么不同?

final可用来修饰类、方法、变量,被final修饰的类不可以被继承、被final修饰的方法不可被重写,被final修饰的变量不能被修改。

finally是java保证重点代码一定被执行的一种机制,我们可以用try-finally和try-catch-finally做类似jdbc连接关闭、释放锁的操作。

finalize是object类的方法,它的设计目的是对象在回收前做一些资源回收的工作(java 9以被声明为过时方法,导致垃圾回收数量级变慢;执行finalize方法出现的异常会被吞掉)备注:我们之所以要回收资源是因为资源是有限的,垃圾收集时间的不可预测,会极大加剧资源占用。对于高频资源的回收一定不能使用finalize回收,太不靠谱;应该显示释放或者使用资源池。

 

10.B+树的优势

1.单一节点存储更多的元素,使得查询的IO次数更少。

2.所有查询都要查找到叶子节点,查询性能稳定。

3.所有叶子节点形成有序链表,便于范围查询。

 

11.代理模式

代理模式主要通过代理对象来控制对目标对象的访问,为目标对象的目标方法添加横切逻辑,比如说事务功能,应用层的读写分离、分库、分表等功能。

代理模式主要分为静态代理和动态代理;静态代理编译期可知,动态代理是运行时在内存中动态生成代理类的二进制字节码流;动态代理的实现方式主要包括

jdk动态代理和cglib动态代理等,jdk动态代理生成的代理类实现目标接口并继承Proxy类,内部方法调用会委托给InvocationHandler实例对象的invoke

方法;cglib动态代理采用继承的方式生成代理类对目标类做增强。

 

12.为什么Eureka比ZK更适合做服务注册和发现?

根据CAP(一致性Consistency、可用性Availablity、分区容错性Partition Tolerance)定理,一个分布式系统只能满足其中两条,而分区容错性是分布式系统的关键,所以一般会保留。

Eureka是基于AP原则构建,而ZooKeeper是基于CP原则构建。

ZK有一个Leader,而且在Leader无法使用的时候通过Paxos(ZAB)算法选举出一个新的Leader。这个Leader的目的就是保证写信息的时候只向这个Leader写入,Leader会同步信息到Followers。这个过程就可以保证数据的一致性。

Eureka因为没有选举过程来选举Leader,因此写的信息可以独立进行。因此有可能出现数据不一致。但是当网络出现问题的时候,每台服务器也可以完成独立的服务。

相较之下,ZK因为基于CP原则,能保证很好的数据一致性,但是可用性支持力度不高。而在一个内部系统中,主要目标是服务的注册与发现,而不是配置(文件)共享,因此Eureka更适用于内部服务的建设。

 

13.为什么做服务化?

例如:有一个user表,多个业务线需要使用它,但是没有对它做服务化;会导致各个业务线里都会有访问user表的代码造成重复代码、当加入缓存时各个业务复杂性都增加、user表被各个业务线连表查询导致强耦合导致db无法做垂直拆分、各个业务线sql质量得不到保障。当我们独立出一个user模块并做服务化后,业务方获取user信息变得简单、也没有重复代码、复杂性由user服务来控制、sql由user服务统一处理、各个业务线比较容易做垂直拆分。

 

14.你们的应用系统怎么保证事务一致性的?

支付系统:首先支付平台各个子模块除交易模块外,其它模块都提供幂等接口;模块内部要有相应的commit/rollback机制;加上定时任务补偿。

以组合支付为例:(快捷+积分+红包),各个子订单串行处理,快捷子订单支付成功;积分子订单在调用资金进行外部支付时,由于网络抖动导致接口异常或者没有到达终态,组合支付流程暂时终止;如果没有收到下游系统的支付结果通知会由定时任务触发该笔子订单的补偿操作,向下游系统发起查询,如果依旧没有到达终态则等待下一次补偿,如果得到“订单不存在”则发起支付;当该笔子订单到达终态,根据支付结果进行支付现场恢复、支付步骤的恢复,如果外部支付成功,则继续向后推进该笔子订单的记账、结算预处理,如果支付失败,则找到该笔子订单对应的组合订单,查找该笔组合订单下的成功状态的子订单发起退款流程。

消费贷开户:开户成功后的一致性处理:消息队列+定时补偿+消费者幂等处理

 

转载于:https://my.oschina.net/jack19910921/blog/1822883

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值