【实习记录】第7周 2023.08.07-2023.08.11

实习记录:

1. spring反射机制:从.class对象得到.java中的所有信息。

        Class<?> cls = Class.forName(“com.sean.utils.User”);

        User user = (User)cls.getDeclaredConstructor().newInstance();

        user.getWord();

        降低耦合度,不必import User类(没有依赖)

        在运行期间,一个类,只有一个Class对象产生

        在运行时获得类的各种内容,进行反编译。Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

【Spring】spring的反射机制详解_spring 反射_&蚂蚁的博客-CSDN博客

【进阶】Spring中的注解与反射_spring 反射修改类上面注解的配置_倾听铃的声的博客-CSDN博客

2. 改良版雪花算法改良版雪花算法,分布式唯一ID神器!

机器号(10位)和时间戳(41位)互换;系统时间回拨时,将上一个数据的时间戳+1(超前消费)(解决时钟依赖问题)

3. 首页上的消息未读数量的显示,为了达到提示的实时性每个请求都要去获得未读消息数量,因此选择用拦截器的方式来实现。MessageInterceptor

4. Elasticsearch,性能最好、功能最强大的分布式搜索引擎。支持http协议,Restful风格

        Elasticsearch术语:索引、类型、文档(通常JSON)、字段(对应mysql的数据库、表、一行、列)(es6.0之后,类型这一概念逐渐被废弃,索引 对应 表)

        分片:一个索引(表)太大的时候,分片存储,提高了并发能力。

        副本:分片的备份,一个丢了还有其他副本

5. es命令:

        curl -X GET "localhost:9200/_cat/health?v" 查看es状态

        curl -X GET "localhost:9200/_cat/nodes?v" 查看节点

        curl -X GET "localhost:9200/_cat/indices?v" 查看索引

        curl -X PUT "localhost:9200/test" 建立索引

        curl -X DELETE "localhost:9200/test" 删除索引

6. 把帖子存到es服务器里,然后再用es搜索

        Spring整合Elasticsearch:

              1.引入spring关于elasticsearch的依赖,采用默认版本;

              2.在applicationproperties文件中配置Elasticsearch;已弃用

              ps:解决小bug,netty启动冲突问题(可作为项目难点);

              3.在Entity文件中修改DiscussPost,使用注解; 版本问题

              在Dao层中新建Elasticsearch文件,添加Elasticsearch接口,用于连接数据库(只需要继承接口即可)。

              4.相关测试代码,使用discussPostRepository和elasticsearchTemplate两 种方式,进行es的增删改查,尤其是查询比较复杂。(高亮,查title和content)

7. Elasticsearch应用:

      1)添加帖子,实现帖子搜索功能(直接在mysql搜索,模糊查找性能太差,而es效率和性能非常高)(mysql的like 简单的关键字搜索。不适合全文索引搜索。MySQL对于一些较为固定,字段较少的查询方式,可以通过简单的增加索引来完成优化。)

      MySQL表在普通查询过程中,比如select * from xxx limit 100w, 100;这种,数据量小的时候随便写sql,可能不会体会到翻页的痛。但在一个单表3000w的系统中写了limit 100w, 10。那数据库服务器就哭了。因为实际上数据库为了取出想要的那几条数据,需要把所有的数据也就是10000010条都取到内存中,复杂一点的select再加上order by则可能会同时涉及到多次磁盘读取和文件排序,慢上加慢。

      2)es存储日志,可以查找和分析日志

什么是ElasticSearch?看完这一篇你就懂了_elasticsearch是什么_BlogY的博客-CSDN博客

8.

9. 基于 SpringBoot3 仿牛客论坛项目代码及踩坑总结:基于 SpringBoot3 仿牛客论坛项目代码及踩坑总结_叁柚木的博客-CSDN博客

10. es中的netty和redis底层都应用到了netty(用于通信),先启动Redis再启动es,es会报错。可以看做项目的难点之一。(代码随想录论坛pdf中提到的,有具体思路分析)

11.

12. mysql存储引擎:

        MyISAM不支持外键,不支持事务,锁粒度是表级别,不会出现死锁,但性能较低,并发能力差。

        InnoDB支持外键约束,支持事务,锁粒度为行级,性能较好,并发能力强,但可能会出现死锁。

13. list to do: mysql四种隔离等级和五种并发异常的细节?

14. Mysql的锁:

        1)乐观锁:认为事务A在执行过程中,不会有其他事务对A操作的数据进行操作(所以是乐观的方式)。

        不会对表和行进行加锁,可以用版本号时间戳的方式来实现

        版本号方式:在事务A开始之前,或读取数据表的版本号version,然后执行事务,在提交事务执行数据操作之前,会再次读取版本号version,如果两次version相同,证明没有其他事务对表进行操作,则事务A正常执行;若两版本号不同,说明有其他事务更新了数据表,所以会返回给用户一个错误信息,用户可以自行决定如何去做(回滚或者强制执行

        时间戳方式:在每个数据记录中,添加一个时间戳字段,每次更新数据时,将时间戳更新为当前时间,当更新数据时,检查时间戳是否与当前时间戳相同,如果相同则更新数据,否则返回错误信息。

        CAS算法(compare and swap)

        2)悲观锁:认为事务A在执行过程中,会有其他事务来更新事务A所操作的表或行(悲观的态度)。

        会用数据库自带的锁(共享锁,排它锁、间隙锁(防止出现幻读)、IS、IX)对数据(表、行)进行加锁。

        乐观锁介绍:乐观锁介绍_51CTO博客_mybatisplus乐观锁

        乐观锁 悲观锁:乐观锁 悲观锁_51CTO博客_悲观锁 乐观锁

15: MySQL的B+树

16. Redis过期策略

Redis会把设置了过期时间的键值对放到一个字典中,键值对过期后不会立即删除它。Redis会通过如下两种策略来删除过期的key:

惰性删除:客户端访问key时,Redis会检查该键值对是否过期,如果过期的话则删除它。(但也有很多key在过期之后从未被访问过,这样就不会被删除,因此占用内存资源)

定期扫描:Redis默认每秒扫描十次(可以配置),扫描策略为:

      1)Redis会从过期字典里随机选择20key

      2)把这20个key中的过期的key删除

      3)如果过期的key的比例超过25%,则继续执行1)

17. Redis淘汰策略

Redis占用的内存超出最大限制时,可采用一些策略,淘汰一些数据,以腾出空间,继续提供读写服务:

18. Redis缓存穿透

场景

      1)客户端查询根本不存在的数据,请求会绕过缓存层(缓存中没有),直达存储层。导致其负载过大,甚至宕机

解决方案

      1)缓存空对象:存储层未命中数据后,仍然将空值存入缓存层,这样再次访问该数据时,会直接返回缓存层的空值。

      2)布隆过滤器:将所有存在的key提前存入布隆过滤器,客户端发送的请求在到达缓存层之前,先经过布隆过滤器,看请求的key是否在过滤器之中,如果不在,则直接返回空值,若存在,再继续访问缓存层和存储层。

19. Redis缓存击穿

场景一份热点数据,在缓存失效的瞬间,大量请求直达存储层,使得服务崩溃。

解决方案

      1)加互斥锁:对该热点数据加上互斥锁,当地一个线程访问该数据时,其他线程只能等待。待第一个线程访问热点数据结束后,会重建该键值对到缓存层;届时其他请求就可以直接从缓存中取值。

      2)永不过期:不设置过期时间(物理上永不过期)。或者待热点数据的缓存过期时,马上重建缓存。

20:Redis缓存雪崩

场景:由于某些原因,缓存层服务不可用,导致请求全都直达存储层,造成存储层宕机。

解决方案:

      1)避免同时过期:设置过期时间时,附加一个随机数,避免大量key同时过期。(导致此时的大部分请求都直达存储层)

      2)构建高可用的Redis缓存:部署多个Redis实例,个别节点宕机,依然可以保持服务的整体可用。

      3)构建多级缓存:增加本地缓存,在存储层前面多加一层屏障,降低请求直达存储层的几率。

      4)启用限流和降级措施:对存储层增加限流措施,当请求超出限制时,对其提供降级措施。

Redis 缓存击穿、穿透、雪崩的原因以及解决方案 | Laravel China 社区

21. java中的volatile关键字:

当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

java中volatile的作用是什么-Java基础-PHP中文网

22. Spring Bean的作用域(主要是singleton单例模式和prototype多个实例)

23. Spring AOP是运行时织入的,基于动态代理实现,使用了代理模式

Spring AOP的主要目的是将横切关注点(如日志、安全和事务管理等)从业务逻辑中分离出来,从而提高代码的模块性和可维护性。

代理模式就是代理对象具备真实对象的功能,并代替真实对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理。

真实对象和代理对象要实现同一个接口,以上为静态代理;随着真实对象功能的增加,代理对象的代码也会随着增加,所以考虑使用动态代理(反射机制)。(有接口的时候用jdk代理,没有接口的时候用cglib代理)

一文搞懂代理模式_deer-li的博客-CSDN博客

24. ThreadLocal是Java中的一个线程封闭技术,它可以让每个线程都拥有自己单独的变量副本,从而保证线程安全。

ThreadLocal提供了一种线程本地存储的机制,为每个线程提供一个独立的变量副本,使得每个线程中的变量互不干扰。

论坛项目中用到了ThreadLocal,在HostHolder类中使用,存储该线程的user(每个线程的user都可能是不同的,所以要做线程隔离

25. MySQL事务并发可能出现的问题

第一类丢失更新:一个事务的回滚,使得另一个事务的已更新的数据丢失了。

第二类丢失更新:一个事务的提交,导致另一个事务已更新的数据丢失了。

脏读:一个事务读取了另一个事务未提交的数据。

不可重复读:一个事务对同一个变量前后读取的结果不一致。

幻读:一个事务,对同一个表前后查询到的行数不一样。

隔离等级:读未提交、读已提交、可重复度、串行化。

读未提交,指一个事务还没提交时,它做的变更就能被其他事务看到,可能发生脏读、不可重复读和幻读现象。

读提交,指一个事务提交之后,它做的变更才能被其他事务看到,可能发生不可重复读和幻读现象,但是不可能发生脏读现象;

可重复读,指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别;可能发生幻读现象,但是不可能脏读和不可重复读现象;

串行化;会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;脏读、不可重复读和幻读现象都不可能会发生。

事务四大特性:原子性、一致性、隔离性、持久性。

四大特性是怎么实现的

原子性:undo log(回滚日志)

持久性:redo log(重做日志)

隔离性:MVCC(MultiVersion Concurrency Control) + 锁机制

一致性:通过原子性+隔离性+持久性来保证

问题严重性排序:脏读>不可重复读>幻读

间隙锁虽然存在 X 型间隙锁和 S 型间隙锁,但是并没有什么区别,间隙锁之间是兼容的,即两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系,因为间隙锁的目的是防止插入幻影记录而提出的

26. Redis是单线程的吗?

Redis 单线程指的是「接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端」这个过程是由一个线程(主线程)来完成的,这也是我们常说 Redis 是单线程的原因。

但是,Redis 程序并不是单线程的,Redis 在启动的时候,是会启动后台线程(BIO)的。

27. Java中线程的状态分为6

1. 初始(NEW)新创建了一个线程对象,但还没有调用start()方法。

2. 运行(RUNNABLE)Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。

线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。

3. 阻塞(BLOCKED)表示线程阻塞于锁。

4. 等待(WAITING)进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。

5. 超时等待(TIMED_WAITING)该状态不同于WAITING,它可以在指定的时间后自行返回。

6. 终止(TERMINATED)表示该线程已经执行完毕。

这6种状态定义在Thread类的State枚举中,可查看源码进行一一对应。

28. Spring Security

Filter和DispatcherServlet是javaEE标准,Interceptor和Controller是Spring MVC标准。Security有11个Filter,拦截到DispatcherServlet的请求。

29. 重定向:浏览器给服务器发送请求A,服务器响应给浏览器一个建议的地址(302),然后浏览器继续访问这个建议的地址B。期间,A和B没有人任何联系,A没有调用B,所以重定向可以降低服务器端的耦合度。(此时,浏览器知道是B给的响应A不能给B传数据

转发: 浏览器给服务器发送请求A,A借助B完成请求并响应给浏览器,A在服务器端是调用了B,产生耦合。(此时,浏览器不知道是B给的响应A可以给B传数据

30. CSRF攻击:x网站模仿浏览器(有浏览器的cookie和ticket),向服务器发送非法请求。

Security解决CSRF攻击的方式:服务器响应式带有一个表单内的token,这个token对于x网站来说无法获得。

日报:

2023.08.07

1. 注解是如何实现的?查看Spring的反射机制

2. 统计第二批”笃行计划“录取情况

3. 改良版雪花算法:机器号(10位)和时间戳(41位)互换;系统时间回拨时,将上一个数据的时间戳+1(超前消费)(解决时钟依赖问题)

4. 牛客论坛,显示系统通知部分功能

2023.08.08

1. 实现完显示系统通知功能

2. 将每周的实习记录整理到CSDN上

3. 学习ElasticSearch分布式搜索引擎,安装Elasticsearch、分词器Elasticsearch ik,用postman给es服务器发请求(增删改查数据,增删查索引,搜索)

2023.08.09

1. 引入es依赖并进行配置,视频中的es版本和springboot版本太低了,目前的版本中已经弃用了很多(Netty4Utils,ElasticsearchProperties、@Document(将实体的属性和es字段对应起来)),所以本部分未能实现代码编写

2. 开发社区搜索功能。Service层编写elasticsearch增删改搜索功能,DiscussPostController的add帖子中触发发帖事件,CommentController触发评论事件,消费者中新增监听publish主题的方法,方法中保存新帖子内容到es数据库

3. 大概过一遍牛客论坛项目的剩余工作,发现要看的东西还挺多的

4. 看代码随想录的仿牛客论坛的八股文pdf(热帖排行、优化网站性能和常见面试题部分未看完)

2023.08.10

1. 看完代码随想录-论坛八股pdf(MySQL、Redis)

2. 整理秋招相关信息网站

3. 整理微信浮窗(实习和招聘相关信息)

4. 补充AOP(动态代理,代理模式,jdk和cglib),ThreadLocal线程隔离

2023.08.11

1. 看阿里二面面经(mysql事务、锁,redis)

2. 看牛客社区Spring Security部分

3. 配置springsecuritydemo项目(maven仓库和jdk版本),并未写代码,springboot版本较高,WebSecurityConfigurerAdapter已弃用

4. 使用Spring Security完成权限控制功能,由于Security版本过新为6.1.1,很多类和方法已被弃用,所以实现方式与视频中不太一样

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值