转载

送你一份P6级Java面试题(二)

导读

作者: 瞿云康英文名 jacksonKang ,是一名努力成长中的 Java 爱好者

本文出处: http://mayiyk.cn/article/6

本文为 Java面试题的 第二篇,这个系列的文章主要把一些常见的java面试题目整理发给大家,希望能在大家以后的面试中提供一些帮助。

一、http协议

  • 超文本传输协议由三部分组成,分别是:请求行,消息报文,请求正文,基于请求与响应模式,无状态的、应用层的协议。与https的区别在于

    a:通信明文不加密,内容可以被窃听,

    b:不验证通信方身份,可能遭到伪装,

    c:无法验证报文的完整性,可能别篡改。

二、linux常用命令

https://www.cnblogs.com/gaojun/p/3359355.html

三、git常用命令

https://www.cnblogs.com/my--sunshine/p/7093412.html

四、为什么使用消息中间件、做了哪些事情

  • 解决分布式系统之间的消息传递。例如用户注册,发送消息给中间件,然后让邮件服务和短信服务自己去消息中间件里面去取消息,然后取到消息后再对自己做对应的业务操作。

  • a:异步处理,b:应用的解耦,c:流量的削峰,d:日志的处理(大数据的日志处理非他莫属,非常强大),e:纯粹的消息通信

五、多线程

  • https://www.cnblogs.com/Jansens520/p/8624708.html

  • https://blog.csdn.net/ll666634/article/details/78615505 (代码)

六、用过哪些安全机制

  • 加密机制:

  1. 对称密钥加密机制,发送者和接受者用相同的密钥,是典型的DES算法,长度为56bit,其加密算法是公开的,其保密性取决于对密钥的保密,优点:加密处理简单,加解密速度快,缺点:密钥管理困难。

  2. 非对称加密:又称公钥私钥系统。其特点是加密和解密使用不同密钥,RSA算法,优点:解决了密钥管理问题,用户大幅度增加时不会向外扩散,不需要在通信过程中传输密钥,安全性提高具有很高的加密强度,缺点:加密解密速度较慢。

  • 安全认证机制:

  1. 数字摘要(采用单项的hash函数,传输信息时将文件一同发送给接收方,进行运算后对比,可以验证数据的完整性)

  2. 数字签名(保证数据完整性及真实性,使用了数字摘要和非对称加密技术)

  3. 数字信封(使用对称加密来加密信息)

  4. 数字证书

七、事物及分布式事物

  • 事物是作为单个逻辑单元执行的一组操作,要么全部成功,要么全部失败。共四个特性:

  1. 原子性: 要么全部完成,要么全部不做,没有中间状态。

  2. 一致性: 必须保证系统的一致性。

  3. 隔离性: 事物和事物之间不会互相影响。

  4. 持久性: 一旦事物完成了,事物对数据所做的变更就完全保存了。

  • CAP定理

  1. 一致性: 客户端知道一系列的操作都会同时发生生效。

  2. 可用性: 每个操作都必须可预期的响应结束。

  3. 分区容错性: 即使出现单个组件无法可用,操作依然可以完成。

  • XA: oracle与DB2商业性数据实现了其接口,事物管理器作为全局的调度者,负责各个本地资源的提交和回滚。 缺点:XA无法满足高并发场景。mysql的xa实现没有记录preare日志。主备切换会导致数据库数据不一致。

  • MQ: 高并发场景下,将一个分布式事物拆分成消息事物(A系统的本地操作+发消息+B系统的本地操作),其中B系统的操作由消息驱动,只要消息事物成功,那么A操作一定成功,消息也一定发出去了。这时候B再去执行操作,如果本地操作失败,消息会重投,直到B操作成功。因此牺牲了一致性,换来性能的提升。

  • TCC编程模式(最大补偿策略): 将整个业务逻辑变成三块, try confirm cancle三个操作,try阶段去扣除库存,confirm去更新订单状态,如果订单失败则进入cancle阶段,会去恢复库存,这种模式并不能更好的复用,不同业务场景所写的代码不一样,复杂度也不一样。

八、事务介绍

  • 事务的四个属性:持久性、原子性、隔离性、一致性。其中一致性是最基本的属性,其他三个属性都是为了保证一致性而存在的。所谓一致性是指数据处于一种有意义的状态,这种状态是语义上的而不是语法上的。例如转账过程中的一致性。

  • 在数据库实现场景中,一致性可以分为数据库外部一致性和数据库内部一致性。前者由外部应用的编码来保证,即某个应用在执行转账的数据库操作时,必须在同一个事务内部调用对账户A和账户B的操作,㐊数据库本身能解决的。后者有数据库来保证,即在同一个事务内部的一组操作必须全部执行成功,这是事务处理的原子性。

  • 为了实现原子性,需要通过日志,将所有对数据库的更新操作都写入日志,如果一个事务中的一部分操作成功,但以后的操作无法继续,则通过回溯日志,将已经操作成功的操作撤销,从而达到全部操作失败的目的。典型场景是,数据库系统崩溃后重启,此时数据库处于不一致的状态,必须先执行一个crash recovery的过程,读取日志进行redo(重演将所有已经执行但未成功写入到磁盘的操作,保证持久性),再对所有到崩溃时尚未成功提交的事务进行undo(撤销所有执行了一部分但尚未提交的操作,保证原子性)。crash recovery结束后,数据库恢复到一致性状态。

  • 在多个事务并行进行的情况下,即时保证了每一个事务的原子性,仍然可能导致数据的不一致的结果。对此引入了隔离性,即保证每一个事务能够看到的数据总是一致的,好像其他并发事务并不存在一样。实现隔离性有两种典型锁:

  • 一种是悲观锁,即当前事务将所有涉及操作的对象加锁,操作完成后释放给其他对象使用。为了尽可能提高性能。发明了各种粒度,各种性质的锁,为了解决死锁问题,又发明了两阶段锁协议等一些列技术。

  • 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。数据版本,为数据增加的一个版本标识。当读取数据时,将版本标识的值一同读出,数据每更新一次,同时对版本标识进行更新。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为是过期数据。实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。

九、MQ的幂等性

  • 对于每条消息,MQ内部生成一个全局唯一、与业务无关的消息ID:inner-msg-id。当MQ-server接收到消息时,先根据inner-msg-id判断消息是否重复发送,再决定是否将消息落地到DB中,这样有了这个作为去重的依据能保证一条消息只能一次落地DB。

十、分布式锁

  • 场景:集群部署一个应用需要部署到多台机器上做到负载均衡。

  • 基于数据库实现: 在数据库创建一张表,表中包含方法名字段,并在方法名上创建索引并做唯一约束,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。缺点:a:影响可用性及性能,需要双机部署,数据同步,主备切换。b:不具备可重入性。c:没有锁失效机制。服务器宕机表中数据没有删除。增加记录有效时间字段,需要定时任务清除这些失效数据。d:不具备阻塞特性,获取不到返回失败,需要循环多次去获取。e:依赖数据库资源开销及性能。

  • 基于redis实现:

  1. 获取锁的时候,使用setnx加锁,使用expire命令为锁添加一个超时时间,锁的value值为一个随机生成的uuid。

  2. 获取锁的时候还设置一个获取超时的时间,若超过时间则放弃获取锁。

  3. 释放锁判断是否是此uuid 如果是则删除,释放锁。

  • 优点:很多缓存服务都是集群部署避免单点问题,提供了很多实现分布式锁的方法。性能好实现起来方便。

  • 缺点:通过超时时间来控制锁的失效时间不是十分靠谱。

  • Zookeeper实现: 性能上不如缓存实现的分布式锁,需要了解其原理。

十一、reids缓存和memcached的区别

  • redis支持存储数据结构多

  • redis支持数据备份。

  • redis支持数据持久化,可以将内存中数据保持在磁盘中,重启时候可以再次加载使用。

十二、工作流

  • 工作流是多个参与者,按照某种预定义的规则,传递业务信息,进行审核的一个框架,23张表

  1. RepositoryService :流程定义流程部署。

  2. RuntimeService :执行管理,包括流程实例和执行对象(正在进行)

  3. TaskService :执行任务相关的(正在进行)

  4. HistoryService :历史管理。

  5. IdentityService :Activiti表的用户角色组。

十三、乐观锁、悲观锁

  • 要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

  • 我们可以使用命令设置MySQL为非autocommit模式: set autocommit=0; 在java中synchronized的思想也是悲观锁。

  • 乐观锁相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做

  • 使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新

十四、表级锁、行级锁

  • 表级锁: 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

  • 行级锁: 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

十五、myba tis中 # 与 $ 的去区别

  • #{} 在预处理时,会把参数部分用一个占位符 ? 代替

  • ${} 则只是简单的字符串替换

  • 优先使用 #{}。因为 ${} 会导致 sql 注入的问题

十六、 IO

  • 节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

  • 字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容

  • Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1

  • inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.

  • 字节流与字符流主要的区别是他们的的处理方式

字节流:处理字节和字节数组或二进制对象;

字符流:处理字符、字符数组或字符串。

十七、运行异常和检查异常的区别

  • 运行时异常也叫非检查异常,比如常见的NullPointException,ClassCastException。这种异常可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。与其相对的,检查异常是强制需要用户处理的异常。

面试准备:

https://blog.csdn.net/u011958281/article/details/77098013

https://blog.csdn.net/sinat_35512245/article/details/60325685

https://blog.csdn.net/weixin_40096176/article/details/80605626

关联推荐:

送你一份P6级Java面试题(一)

知数堂面试宝典——《叶问》专辑: https://zhishutang.com/Z4z

送你一份P6级Java面试题(二)

送你一份P6级Java面试题(二)

送你一份P6级Java面试题(二)

扫码加入MySQL技术Q群

(群号: 650149401)

送你一份P6级Java面试题(二)

点“在看”给我一朵小黄花

送你一份P6级Java面试题(二)

原文  http://mp.weixin.qq.com/s?__biz=MjM5NzAzMTY4NQ==&mid=2653933020&idx=1&sn=dce587066231e9838e83ae1b4e8f6333
正文到此结束
Loading...