【实习记录】第4周 2023.07.17-2023.07.21

实习记录:

1. <insert id="insertUser" parameterType="User" keyProperty="id">

        insert时,加上keyProperty后,在插入user后,id会自动回显到user对象的id,不需要再手动set;不加keyProperty时,id不会回显,通过getId方法也无法获取,只能在一次从数据库中查数据才能获得id。 

2. 表现层调用业务层,业务层调用数据层,所以数据层的异常也会抛出来到表现层,所以统一异常处理只需要处理表现层的异常即可。

3. 统一异常处理:resources ->templates -> error -> 状态码.html (eg: 404.html 500.html),这样当出现异常时,会自动跳转到对应状态码的Html页面。

4.

        @ControllerAdvice(annotations = Controller.class)用于所有注解了@Controller的类,@ExceptionHandler({Exception.class})用在方法上,处理所有controller类的Exception异常。

5. AOP面向方面(切面)编程 Aspect-Oriented programing

        AOP是一种编程思想,是对OOP的补充

        日志记录:不能用控制器通知(ControllerAdvice),只能记录error日志;也不能用拦截器,拦截器只能对Controller记录日志,而服务层和数据访问层无法记录日志。

        业务组件中最好不要有系统需求(记录日志)。

        理解概念比较抽象,但是代码比较简单。

        目标对象Target(业务模块:帖子业务、评论业务、私信业务)上织入代码的位置叫做Joinpoint;

        Pointcut,是用来定义当前的横切逻辑准备织入到哪些连接点上

        Advice,用来定义横切逻辑,即在连接点上准备织入什么样的逻辑

        Aspect,是一个用来封装切点和通知的组件

        Spring AOP限制了连接点必须是方法执行级别

        @Aspect  @Pointcut("execution(* com.nowcoder.community.service.*.*(..))") 切点

        Service组件中每个方法都是连接点  @Before("pointcut()")

        @AfterReturning("pointcut()")  @After("pointcut()")  @AfterThrowing("pointcut()")

        @Around("pointcut()") 五种方法

        Spring AOP只能织入到方法中,而且是运行时织入,不能解决所有的AOP问题,但可解决绝大多数问题(性价比价高),对于其他高级AOP需求,可配合AspectJ(Spring也支持AspectJ的集成)实现。

        Spring AOP在运行时通过代理的方式织入代码,只支持方法类型的连接点

        AOP不需要在业务类中写任何代码,不会影响业务组件,在运行时切面内的通知会织入到连接点

6. spring中也支持redis事务,但是redis事务是把所有指令放到一个队列里,提交事务时一起执行,所以在事务中查询数据时不会立刻返回结果,所以要查数据要么在事务前要么在事务结束后,因此声明式事务在redis(@Transactional注解)中也不常用,大多使用编程式事务(把事务缩小,事务之外可以进行查询)。

7. 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

        拦截器@Interceptor和统一异常处理@ControllerAdvice也用到了AOP思想!

        (思考)Spring AOP自定义实现(不使用拦截器,不implements HandlerInterceptor)对未登录的用户进行拦截:切点PointcutController(拦截器是在请求到达Controller前进行拦截),通知advice(@Before)为验证ticket是否有效,JointPoint还是各个方法,target为需要登录的controller业务方法。

        其实现原理是使用动态代理技术,在方法运行时动态生成代理对象,然后插入切面代码。

应用场景:

        1)日志记录:记录方法的入参、出参以及方法的执行时间等信息;

        2)安全检查:在方法执行前对用户进行身份验证,判断其是否具备访问方法的权限;

        3)性能监控:记录方法的执行时间,方便分析程序性能瓶颈;

        4)事务管理:在方法执行前开启事务,在方法执行后根据方法执行结果提交或回滚事务;

        5)缓存:在方法执行前判断缓存中是否存在方法的结果在方法执行后将结果存入缓存中,方便下次调用时使用。

8. 点赞使用的Redis数据库,数据访问层的操作十分简单,所以省去写数据访问层,直接写业务层。

9. redis存验证码:解决了分布式下的session共享问题,且可以设置过期时间。

        redis存登陆凭证(LoginTicket):可以不再在mysql的表中存储;每次处理请求时,都会查询用户凭证(login_ticket表)和用户信息(user表)访问频率很高,对性能有影响。

        redis缓存用户信息:缓存(有过期时间)的同时,还要在mysql中存储

10. 优化:

        重构验证码功能:由于还未登录,所以无法获取userId,因此redisKey中只能用一个字符串来代替userId:后端generateUUID(),将结果存在cookie中,然后以此为key,value存生成的验证码text。(与session的思想类似,浏览器也是根据cookie来寻找对应的session)

        重构登录凭证功能:key的格式为:ticket:生成的ticketUUID -> 序列化后的LoginTicket的json字符串。

        redisTemplate.opsForValue().set(redisKey, loginTicket); // redis会自动将loginTicket对象序列化为json字符串存储

        LoginTicket loginTicket = (LoginTicket)redisTemplate.opsForValue().get(redisKey);

        缓存用户信息:1.优先从缓存中取值 2.取不到时初始化缓存数据 3.数据变更时清除缓存数据(修改的话可能会有并发错误,而且修改逻辑有些复杂,所以更新时直接删掉redis中的缓存数据,下次用的时候在再初始化)

        先从redis中取值,如果没有的话,再从mysql中查找并且缓存到redis库中。

11. kafka和rebbitMQ等都是对阻塞队列做了深度封装,都是基于阻塞队列(BlockingQueue接口,java自带的)来做的。

        BlockingQueue可以解决线程通信问题,类似Object的wait()和notify()函数。

        生产者消费者模式,生产者put ->| | | | |->消费者take

        实现类:ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue,         SynchronousBlockingQueue, DelayQueue

12. java启动线程的四种方法

        1)继承Thread, 重写run方法,在main函数中,调用start方法。

        2)实现Runnable接口,重写run方法,在main函数中,调用start方法。

        3)实现Callable接口,重写call()方法,在main函数中调用start()方法。

        4)线程池

13. Kafka的特点:

        对硬盘的顺序存取的效率是很高的,甚至高于堆内存的存取,但是硬盘的随机读取是较慢的。Kafka的消息持久化就是将消息存储在硬盘上,它的高效就是因为对硬盘的顺序存取。

        高可靠性:是分布式的,有冗余备份

        高扩展性:机器不够用了,进行很少的配置就能加到集群中。

14.Kafka术语:

        Broker:一个Kafka服务器 

        Zookeeper:用于管理集群的软件,Kafka中也有内置的集群管理组件

        消息队列的模式:点对点(测试代码),订阅模式(Kafka,订阅了的消费者都可以获得消息)

        Topic主题,类似于一个文件夹,用于存储消息的位置,(消息存放的地方,代表一个消息类别,比如点赞的消息/关注的消息)

        Partition分区,一个主题可以有多个分区,提高并发能力

        Offset消息在分区内存放的索引

        Replica副本,Kafka是分布式的,备份有助于提高高可靠性

        Leader Replica主副本,备份同时可以做出响应

        Follower Replica从副本,只做备份,不能作出响应

主副本挂掉后,集群会从众多的从副本中选一个当作新的主副本。

        Kafka是Apache的

15. 环境配置问题:

        下载Kafka, 更改java环境变量优先级,JAVA_HOME中有"()"删掉后即可正常运行

16. 启动Kafka的命令:

        第一个cmd: 进入F:\Kafka\kafka_2.12-2.3.0目录,运行命令启动Zookeeper : bin\windows\zookeeper-server-start.bat config\zookeeper.properties

        第二个cmd: 进入F:\Kafka\kafka_2.12-2.3.0目录,运行命令启动Kafka: bin\windows\kafka-server-start.bat config\server.properties

        第三个cmd: 进入F:\Kafka\kafka_2.12-2.3.0\bin\windows目录,运行命令创建主题topic:kafka-topics.bat --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test(服务器为localhost:9092,1个副本,1个分区,topic名叫test)

        查看现有的主题topic: kafka-topics.bat --list --bootstrap-server localhost:9092

        生产者给test主题发消息: kafka-console-producer.bat --broker-list localhost:9092 --topic test

        第四个cmd: 进入F:\Kafka\kafka_2.12-2.3.0\bin\windows目录,运行命令读取test主题的消息:kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning

        生产者可以发送消息,消费者可以接收消息

        Kafka的cmd按下Ctrl+C,输入Y,再运行命令关闭Zookeeper: bin\windows\zookeeper-server-stop.bat

日志:

2023.07.17

1. 实现私信列表和私信详情页面(没有新技术,都是业务方面的逻辑)

2. 实现发送私信,消息已读的功能

3. 微信公众号菜单是否可以跳转到外链(个人号菜单只能跳转内链,可以通过阅读原文、点击图片、自动回复、二维码来实现)

4. 统一异常处理(Spring boot项目可以直接把error文件夹放到resources->templates下,文件名为404.html...)

2023.07.18

1. 统一处理异常,借助@ControllerAdvice和@ExceptionHandler两个注解,处理异步和同步两种请求(返回json和页面)

2. Spring整合Redis,RedisTemplate(@Bean注入第三方对象),调用时用redisTemplate.opsForValue().get(redisKey); BoundValueOperations绑定redisKey; Redis编程式事务

3. 理解AOP,并编写代码。@Component @Aspect @Pointcut("execution(* com...service.*.*(..))") @Before("pointcut()) @After @AfterReturning @Aroud @afterThrowing; 不用在业务类中写任何代码,只用在Aspect中写很少代码

4. 已学习完牛客论坛第三章

2023.07.19

1. 实现对帖子和评论的点赞功能,用的Redis数据库,所以mysql中没有这个表,用set数据结构,存点赞的userId

2. 重构点赞功能,加上incr(targetUserId), decr(targetUserId),即以用户为key查询获赞数量

3. 实现关注和取消关注功能,高频操作再次利用redis存储

4. 实现关注列表和粉丝列表(未完成)

2023.07.20

1. 实现关注列表、粉丝列表所有功能,我的帖子和我的回复页面跳转

2. 重构登录模块,redis存验证码(思想类似于session),redis存登录凭证(redis可以存value为LoginTicket或User的序列化json对象),redis缓存用户信息(更改用户信息时,直接在缓存中删除;每次访问先在redis中查找,取不到再去mysql查并且缓存到redis)

3. 牛客论坛第四章完结撒花

4. 调整长图大小

5. 整理步云流海小程序的json

2023.07.21

1. 八股:三次握手、四次挥手

2. 生成小程序的json ;整理募捐活动照片、视频

3. 测试BlockingQueue类(ArrayBlockingQueue, put, take),看java启动线程的四种方式

4. 下载Kafka, 更改java环境变量优先级,JAVA_HOME中有(),删掉后即可正常运行(之后每次项目运行之前,都要保证Zookeeper和Kafaka是开启状态)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值