Java知识整理

tech2022-09-19  64

文章目录

一、Java Serializable的作用1.什么是序列化2.什么情况需要序列化3.怎么实现序列化4.疑问 二、Equals和==的区别三、前后端分离开发,日志应该如何进行记录,在出现问题的时候,方便定位问题?四、数据库访问的时候,在一个项目中是否可以同时使用Mybatis,JPA,JDBC等多种持久化技术?如可以,事务如何处理?五、接口保证幂等性,如何做的1.什么是接口的幂等性2.如何保证幂等性 六、@transcation事务应放置在什么位置,在项目中如碰到事务什么原因不生效?1.spring实现事务的方式2.事务的传播行为 3.事务不生效的原因七、如阅读过源码,分析一下该源码给你的体会?是否参加过开源代码?八、扫码登录的原理1.Ajax短轮询2.基于HTTP长连接的服务器推技术2.1基于Ajax长轮询的方式(long-polling)方式2.2基于长连接的服务器推模型 3.WebSocket4.总结 九、Git分支应如何管理?十、实体类为未来参与排序等集合的操作操作,一般要重新哪些方法?有哪些注意点?


一、Java Serializable的作用

1.什么是序列化

序列化:把对象转换为字节序列的过程称为对象的序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

2.什么情况需要序列化

当你想把的内存中的对象状态保存到一个文件中或者数据库中时候; 当你想用套接字在网络上传送对象的时候;

3.怎么实现序列化

如果我们想把一个类实现序列化,只需要实现实现Serializable接口即可。

4.疑问

我为什么不序列化也可以把对象写入文件中? 如果一个类实现了Serializable接口,在序列化的时候静态属性是不随序列化修改的,如果有个静态属性,一开始是static int = 100,写入到一个文件属性是100,此后修改了代码改为200,再反序列化,从文件读取这个对象,此时的序列化是200. 实现序列化的时候一定要给serialVersionUID赋值,如果不赋值,在反序列化之前给这个类添加了新的属性,就会报InvalidClassException异常

二、Equals和==的区别

1、== 操作符既可以用于比较基本的数据类型,也可以用于比较对象,而equals只可以用于对象之间的比较 2、在比较String类型的对象时,== 操作符的原理只有两个变量是同一对象的引用时才会返回true,而equals方法只要两个变量的内容相同则返回true 3、其他类型的对象进行比较时,equals方法默认的原理是判断两者的内存地址是否相同,所以默认情况下与== 操作符返回的结果相同,但是这里应该发现差别,也就是equals方法可以被重写—用户可以定制自己的equals方法,而== 操作符不能被重写.

三、前后端分离开发,日志应该如何进行记录,在出现问题的时候,方便定位问题?

日志有哪些级别:等级由低到高:DEBUG < INFO < WARN < ERROR < FATAL 常用的日志框架 log4j可以配置生成日志文件到指定文件。同时可以配置日志按天为周期,或者按照日志文件大小拆分为单个文件。 前后端分离的项目需要记录好各种必要参数,尽量简单明了如编号,来源,当前ip,接口名,参数,回参等出现问题时能判断当前问题大致范围。

四、数据库访问的时候,在一个项目中是否可以同时使用Mybatis,JPA,JDBC等多种持久化技术?如可以,事务如何处理?

jpa和mybatis分别有自己的事务实现,但是再spring环境下jpa的事务会覆盖mybatis的事务,单数据源情况下,完全可以兼容两者的事务,但是如果你的项目是多数据源,并且扫包不规范的情况下,事务很有可能就失效了,比如同一个mapper被多个数据源扫描到了,这是你的事务管理器上只能标一个名字,虽然你是同一个操作,但是不在被单数据源的事务管理器处理,会导致mybatis事务不生效的问题。所以我不建议采用一个方法中既写mybatis又写jpa 除非你能保证你的项目只是单数据源的。

五、接口保证幂等性,如何做的

1.什么是接口的幂等性

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。 比如一个用户购买某件商品,点击了付款,但是因为网络原因没有获取到付款成功的通知而再次发起了付款请求,如果没有做幂等性处理,就可能发生重复扣款的操作,这就是不能保证幂等性操作。

2.如何保证幂等性

1. 通过代码逻辑判断实现,比如扣款和修改状态放在同一个事务内,正在扣款中->扣款->扣款成功,对状态加以判断。 2. 使用token机制实现, 先生成全局唯一的token,token放到redis或jvm内存,token会在页面跳转时获取.存放到pageScope中,支付请求提交先获取token;提交后后台校验token,执行提交逻辑,提交成功同时删除token,生成新的token更新redis ,这样当第一次提交后token更新了,页面再次提交携带的token是已删除的token后台验证会失败不让提交。

六、@transcation事务应放置在什么位置,在项目中如碰到事务什么原因不生效?

1.spring实现事务的方式

1.编程式事务,使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。 2.声明式事务,建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

2.事务的传播行为

TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。 TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。 TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。 TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

3.事务不生效的原因

在实际生产开发中我们一般使用声明式事务,这种方式对代码的侵入性更低。如果需要更细粒度的事务控制可以用编程式事务,可以作用在代码片段上。 事务不生效的原因: 1.要看数据库本身对应的库、表所设置的引擎是什么。MyIsam不支持事务,如果需要,则必须改为InnnoDB。 2.注解放到了私有方法上,在私有方法上,添加@Transactional注解也不会生效,私有方法外部不能访问。 3.未捕获异常,@Transactional注解默认处理运行时异常,即只有抛出运行时异常时,才会触发事务回滚,否则并不会。

七、如阅读过源码,分析一下该源码给你的体会?是否参加过开源代码?

笔者曾阅读过Spring源码和mybatis的源码,通过阅读Spring源码,学习到了Spring的各种扩展点,并且可以运用这些扩展点来扩展自己的项目。同时也学习到了Spring里面的各种设计思想和设计模式。比如基本上贯串整个spring中bean生命周期的Bean的后置处理器BeanPostProcessor,比如Bean在实例化之前会调用InstantiationAwareBeanPostProcessor来对Bean判断是否需要代理;SmartInstantiationAwareBeanPostProcessor来推断构造方法;实例化之后调用InstantiationAwareBeanPostProcessor来进行属性的注入;执行生命周期初始化回调方法和Aware;AbstractAdvisingBeanPostProcessor进行AOP操作。

八、扫码登录的原理

http协议是单向性、无状态的。必须由客户端发起一个请求连接,服务器接受请求,把数据相应给客户端,典型的一请求一响应。

1.Ajax短轮询

在登录页面执行setInterval函数,定时轮询。这样的好处是服务端基本不用改造,但是会造成服务器压力和资源的浪费,数据更新可能不及时。

2.基于HTTP长连接的服务器推技术

“服务器推”是一种很早就存在的技术,以前主要是通过客户端的套接口,或服务器的远程调用。那么我们这种纯浏览器端的应用怎么办? 这种基于HTTP长连接、无需在浏览器端安装插件的”服务器推“技术位”Comet“。 Comet的实现模型:

2.1基于Ajax长轮询的方式(long-polling)方式

1.客户端使用Ajax发出请求,服务端会阻塞请求直到有数据传递或超时才返回。 2.客户端JavaScript响应处理函数会在处理完服务器的返回信息后,再次发出请求,重新建立连接。 3.当客户端处理接收到的数据、重新建立连接时,服务器端可能有新数据到达;这些信息会被服务器端保存直到客户端重新连接,客户端会一次把当前服务器端所有的信息取回。

2.2基于长连接的服务器推模型

流方式(长连接),又叫Server-sent-events(SSE),是HTML5规范的一个组成部分,和长轮询方式很像,只有一点区别,就是流的方式在客户端请求服务端并建立连接之后,服务器始终不会关闭连接。每次有数据时,就像客户端进行输出,而不像长轮询每次向客户端输出之后,都要关闭连接。

3.WebSocket

HTML5中的协议,实现与客户端与服务器双向,基于消息的文本或二进制数据通信。适用于对数据的实时性要求很强,客户端与服务端频繁交互的场景,入直播、实时共享桌面、多人协作等。采用新的协议,后端需要单独实现,客户端并不是所有的浏览器都支持。 与SSE相比,工作方式不同,WebSocket是双向通信,SSE是单向通信。SSE使用HTTP协议,一般只用来传送文本,WebSocket是一种独立的协议,支持传送二进制数据。SSE默认支持断线重连,WebSocket需要自己的实现。

4.总结

从用户量和浏览器的支持度来说,目前主流的京东和淘宝的扫码登录、付款页面的回调,主要采用的是AJax短轮询和长轮询方式。

九、Git分支应如何管理?

(1)创建分支:git branch <分支名> (2)切换分支: git checkout <分支名> (3)删除分支:git branch -d <分支名>

十、实体类为未来参与排序等集合的操作操作,一般要重新哪些方法?有哪些注意点?

需要排序的对象需要实现comparable接口,然后重写compareTo方法,但是方法会增加耦合度,在项目中不同位置使用的时候要根据不同需求反复修改排序规则。更好的方法可以通过匿名类,new一个Comparator类,然后实现compare方法。

Git地址:https://github.com/astonMarren

最新回复(0)