Java深入学习
这篇文章用于记录Java基础知识相关的深入学习。包括了 动态代理、反射、JVM
一、动态代理篇首先先理清代理的概念,代理就是用来增强原对象功能的。通过代理,可以无侵入式的给对象增强其他功能。
代理长什么样?代理类里面就是对象要被代理的方法。
Java通过什么来保证代理的样子?通过接口保证的,被代理对象和代理都需要实现同一个接口,而这个接口里的方法就是要被代理的所有方法。
例子JDK动态代理被代理的原对象
123456789101112131415161718192021222324252627282930public class Star implements Star_Interface { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Star() { & ...
项目面试准备
一、黑马点评1.项目介绍我做的这个项目主要就是模仿大众点评,是使用springboot开发的前后端分离的项目,实现了商户的搜索、点评,好友关注、动态推送以及优惠券秒杀等功能。其中使用了redis做数据缓存,提高数据的访问效率,以及利用redis实现分布式锁解决一人一单的问题。此外,还利用了RabbitMq异步的创建优惠券订单,提高抢票的相应速度。
2.项目中遇到的难点我认为项目中主要的难点在于优惠券秒杀这个功能的实现。首先这个需要考虑到库存超卖和一人一单问题,针对库存超卖问题,我使用的是乐观锁的思想,考虑到库存如果使用版本号来判断扣减库存是否成功的话,会出现库存充足的情况下依旧会抢券失败的情况。所以我最后没有使用版本号,而是在给扣减库存的sql语句加个where条件判断库存数量是否大于0。然后针对一人一单问题,因为数据库的一人一单判断和库存扣减操作是非原子性的,所以,我的解决方案是我一开始是给用户id放到常量池中,使用synchronized这个关键字获取到用户id的锁后进行相关的抢票校验代码。但后面考虑到在多个相同服务部署的情况下,锁无法跨服务感知,所以使用了redis来创建分布式锁 ...
黑马头条项目
有意义的亮点摘要后面总结
1.垂直分表
2.ElasticSearch
3.xxl-job 分布式任务调度框架
后端知识点总结
随心记
这篇用于随时记各类八股文,后面会详细拆分各个模块
一、Spring相关1.Spring框架中的单例bean是线程安全的吗?答:不是。首先,Spring中的单例bean是全局共享的。一般情况下,spring的bean中注入的都是无状态的对象(无状态指的是不会存储数据,即没有定义可修改的成员变量),所以不会有线程安全问题。但如果假设这个bean定义了可修改的成员变量,多个线程如果同时访问并修改这个成员变量时,可能会造成数据的不一致,这种情况可用使用多例或者加锁来解决。
知识点:无状态Bean(即没有可修改的成员变量)、有状态Bean
2.什么是AOP答:AOP的话,指的就是面向切面编程,简单说就是把一些业务逻辑中相同的代码抽取到一个独立模块中,通过动态代理的方式增强原方法,让业务逻辑更加简洁。
知识点:
JDK动态代理,被代理的对象必须实现一个接口
CGLIB动态代理,适用于被代理的对象没有实现接口的场景。
Spring AOP 默认使用JDK动态代理,但如果目标类没有实现接口,则会自动切换到CGLIB动态代理。
3.项目中有没有用到过AOP答: 我之前在尚庭公寓的后台管理系统中使 ...
微服务总结
一、服务调用服务拆分之后,不可避免的会出现跨微服务的业务,此时微服务之间就需要进行远程调用。微服务之间的远程调用被称为RPC,即远程过程调用。RPC的实现方式有很多,比如:
基于Http协议
基于Dubbo协议
1.RestTemplateSpring给我们提供了一个RestTemplate的API,可以方便的实现Http请求的发送。
使用RestTemplate的基本步骤如下
注册RestTemplate到Spring容器
调用RestTemplate的API发送请求,常见方法有:
getForObject:发送Get请求并返回指定类型对象
PostForObject:发送Post请求并返回指定类型对象
put:发送PUT请求
delete:发送Delete请求
exchange:发送任意类型请求,返回ResponseEntity
利用RestTemplate发送http请求与前端ajax发送请求非常相似,包含以下信息:
1 请求路径
2 请求方式
3 请求体
4 返回值类型
5 请求参数
案例代码123456789// 2.查询商品ResponseEntity&l ...
黑马点评项目总结
一、项目介绍八股介绍:之后再补吧。。。。。词穷了
这个项目主要是基于redis相关内容进行展开的,主要实现了用户登录、抢票、点赞、评论、关注等类似社交软件的功能。
二、短信登录1.简介短信登录逻辑是用户填入手机号和短信验证码来校验用户信息。此外,该登录功能还包含了注册,即未注册过的手机号进行登录时,将会默认注册为一个新用户。
2.验证码的获取验证码缓存用户发起获取短信验证码请求时,后端会先随机生成一个6位数验证码,以login:phone:填入的手机号为key,将验证码存入redis中。随后调用短信相关的api,给对应的手机号发送验证码。
1234567891011121314151617@Overridepublic Result sendCode(String phone, HttpSession session) { //1.校验手机号 if (RegexUtils.isPhoneInvalid(phone)){ return Result.fail("非法手机号"); } //2.生成验证码 ...
Linux学习笔记
&&和||&&:从前往后执行,有一个失败则不继续执行
||:从前往后执行,有一个成功则不继续执行
例子:ping www.hdu.com -c 10 -w 10 && echo success || echo failure
-c:发送数据包的次数
-w:总体超时时间,整个ping的最大运行时长
重定向输出重定向 >:将标准输出以覆盖原文件的方式写入
>>:将标准输出追加方式写入
输入重定向<:用于将文件的内容作为输入传递给命令。
<<:用于将多行文本(自己输入的)作为输入传递给命令,适合在脚本中嵌入多行文本。
用法和<有区别,这个后面跟的是分隔符–用于多行输入时终止输入的标志。例如cat << EOF
下图所示的stop是终止输入的标志。
<<<:用于单行字符串的输入
带&的重定向前置知识点:文件描述符
0标准输入stdin按键
1标准输出stdout屏幕
2标准错误输出stderr屏幕
&>:将标准输出和错误输出重定向到文件中。
类似于部 ...
Redis最佳实践
1.键值设计优雅的key结构key的最佳实践约定
1.遵循基本格式:**[业务名称]:[数据名]:[id]**
2.长度不超过44字节
3.不包含特殊字符
优点
可读性强
避免key冲突
方便管理
更节省内存:key是string类型,底层编码包含int,embstr和raw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小。raw模式下,内存空间不是连续的,而是会采用指针形式指向其他空间。
拒绝BigKey什么是BigKey
key本身的数据量过大,比如一个key的值就占了5MB。
key中的成员数过多,比如一个ZSET类型的key,它的成员数量为10000个。
key中成员的数据量过大,比如一个Hash类型的key,它的成员数量虽然只有1000个,但这些value的总大小为100MB。
推荐值:
单个key的value小于10kb
对于集合类型的key,建议元素数量小于1000
选择合理的数据结构
2.批处理优化单个命令的执行流程一次命令响应时间=一次往返的网络传输所耗的时间 + 1次redis执行命令耗时
问题:一次命令响应时间耗费时 ...
黑马点评笔记
1.缓存机制数据一致性:先修改数据库再删除redis缓存。先删缓再删数据发生线程安全的问题更大,因为数据库修改数据耗时长,可能删了缓存后在数据库信息修改还没好之前,又读取了该信息并缓存了。
2.缓存穿透客户端访问数据库中不存在的数据,缓存永远不生效,可能会被恶意攻击数据库导致瘫痪。方法1.缓存空对象 2.布隆过滤
3.缓存雪崩指的是同一时间段内,redis中大量的缓存的key同时失效或者redis服务器宕机了,导致有大量请求到达数据库,带来巨大压力解决方法:1.给TTL添加随机值 2.利用redis集群 3.给缓存业务添加降级限流策略(微服务内容)4.添加多级缓存
4.缓存击穿指的是某一个被高并发访问并且该缓存重建业务较复杂的key突然失效了,导致大量请求到达数据库,带来巨大冲击。解决方法:1.添加互斥锁到redis中 2.逻辑过期
实战通用的redis缓存工具12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 ...
RabbitMq
RabbitMq消息队列总结参考黑马教程day06-MQ基础 - 飞书云文档
1.概述RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:
https://www.rabbitmq.com/
使用背景:同步调用在微服务项目中,我们使用的OpenFeign都是同步调用,可以理解为阻塞,只有当前任务执行完毕才能往下执行,同步调用存在以下问题:
第一,拓展性差
在大多数电商业务中,用户支付成功后都会以短信或者其它方式通知用户,告知支付成功。假如后期产品经理提出这样新的需求,你怎么办?是不是要在上述业务中再加入通知用户的业务?
某些电商项目中,还会有积分或金币的概念。假如产品经理提出需求,用户支付成功后,给用户以积分奖励或者返还金币,你怎么办?是不是要在上述业务中再加入积分业务、返还金币业务?
由此可见,服务会越来越臃肿。
第二,性能下降
由于我们采用了同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和。
第三,级联失败
由于我们是基于OpenFeig ...