LeetCode 146 LRU实现
LeetCode刷题笔记 —— 146 LRU的实现题目解析:设计一个LRU缓存,规定好最大容量,设计get/put接口,当即将超出容量的时候,要把最久未使用的缓存删除
最久未使用:最久没有进行 get/put操作
要求get/put均为o(1)复杂度
o(1)的key value,必然是哈希表,可是应该怎么获取 最久未使用 这一个信息?
第一思路:把 最久未获取 当成一个属性来维护
最久未使用 这一信息的获取过程,是伴随着 put 操作发生的,因此,put想要是O(1),获取最久未使用也必须是O(1)
换句话说,我们想要这个信息的获取既能和key的获取一样便捷,又能把他和key联系起来
然而,哈希表也仅有key能在O(1)时间内获取,getvalue则是通过遍历哈希key获得的,时间复杂度是O(n)
同样的道理,使用 栈 Stack 来维护这个信息,在移除头节点的时候,remove(0)操作也是需要O(n)的时间
**第二思路:1. 利用某种数据结构的特性,把时间信息隐含到数据结构里 **
**2.必须满足通过key查找到它的过程不是O(n)遍 ...
Spring事务失效的情况,场景和解决办法 以及引出的Spring底层注入原理彻底分析
Spring 事务失效的3大情况概览
方法内自调用
解决办法:
把调用方法拆分到另外一个bean中
自己注入自己(Spring的缓存机制能够避免循环依赖,不放心可以加@Lazy注解)
AopContext.currentProxy()方法获取当前的代理对象,用这个方法启动类要加注解@EnableAspectJAutoProxy(exposeProxt = true),同时也要引一下依赖
方法是private 或 final 的,代理对象就不能重写这个方法了,因此调用它的时候,实际调用的是extends的父类的普通方法
单独的线程调用方法:
当MyBatis执行sql的时候,会从ThreadLocal中获取数据库连接对象,如果开启事务的线程和执行SQL的线程是同一个,就能拿到数据库连接对象,如果不是同一个线程,就拿不到,这时会新建一个数据库连接,这个数据库链接默认直接提交
解决方法:不能在事务方法内开启多线程操作数据库,可以开启多线程给每个线程添加事务
Spring底层注入和事务注解的剖析Spring的注入过程:由表入里,层层递进,直至底层
从底层开始注入,底层注入 ...
网关路由、统一鉴权与动态配置管理
Spring Cloud微服务 —— 网关路由、统一鉴权与动态配置管理
一、问题引入:微服务拆分后的痛点
模块
服务名称
用户服务
user-service
商品服务
item-service
购物车服务
cart-service
交易服务
trade-service
支付服务
pay-service
拆分后出现了几个常见问题
问题一:前端访问困难
每个微服务的端口不同,前端要维护多个地址;
前端无法通过 Nacos 获取实时服务列表。
问题二:身份认证割裂单体架构下只需登录一次即可共享用户信息; 而微服务拆分后,每个服务都需要单独做登录校验与用户信息传递。
解决方案:使用微服务网关 Gateway!
二、网关路由(Gateway Routing)2.1 网关是什么?网关(Gateway)是微服务系统的统一入口,承担以下功能:
请求转发与路由;
登录校验与权限控制;
日志记录与限流。
类比现实:
网关就像园区传达室的大爷,所有人(请求)都得先经过他:
不合法的请求会被拦截;
合法请求会被带到对应的服务。
2.2 Spring Clo ...
SpringCloud 微服务——Nacos 与 OpenFeign 详解
SpringCloud 微服务——Nacos 与 OpenFeign 详解一、微服务通信的基础:服务注册与发现在微服务架构中,系统被拆分为多个独立的服务(如用户服务、商品服务、订单服务等)。 为了让这些服务能够相互调用,就需要一个注册中心(Registry)来管理服务实例的注册和发现。
注册中心原理注册中心的核心流程包括三部分:
服务注册(Service Registration) 各个微服务在启动时,将自己的 IP、端口、服务名等信息注册到注册中心。
服务发现(Service Discovery) 其他服务在调用时,先向注册中心查询要调用的服务地址。
健康检测与剔除(Health Check) 注册中心定期检测服务是否存活,失效的实例会被剔除。
二、Nacos 注册中心详解1. Nacos 简介Nacos 是阿里巴巴开源的动态服务发现与配置管理平台,兼容 Spring Cloud Alibaba 生态。
功能包括:
服务注册与发现
配置管理
动态负载均衡
健康检测
2. 项目中引入 Nacos① 添加依赖在微服务的 pom.xml 中引入:
1234<depende ...
JDK新特性
Lambda表达式首先明确一点:Lambda表达式是由匿名内部类传参简化而来
使用lambda表达式的场景:
函数式接口做方法参数传递
(只要是想new一个函数式接口,就能用lambda,只是用的时候大多出现在传递参数的时候)
什么是函数式接口 ——> 一个接口有且仅有一个重写方法 可以用过在接口上加上@FunctionalInterface注解来判断
举个例子:
12345678910111213141516171819202122public class Test { public static void main(String [] args){ new Thread( new Runnable(){ @Override public void run { System.out.println("a new thread"); } ...
Docker
Docker命令树:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475Docker 命令树│├── 镜像管理 (Images)│ ├── docker search [镜像名] # 从仓库搜索镜像│ ├── docker pull [镜像名]:[标签] # 拉取镜像│ ├── docker images # 列出本地镜像│ ├── docker rmi [镜像ID/名] # 删除镜像│ ├── docker build -t [镜像名] [路径] # 构建镜像│ ├── docker tag [旧名] [新名] # 给镜像打新标签│ └── docker save -o [文件.tar] [镜像] # 导出镜像│├── 容器生命周 ...
MyBatisPlus
MybatisPlusMP引入Mp的使用:
1.mapper层:继承BasMapper接口
2.service层:service接口实现IService接口,service实现类继承IServiceImpl实现类
Mp将实体类和数据库表明对应的约定:
MybatisPlus会把PO实体的类名驼峰转下划线作为表名
MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型
MybatisPlus会把名为id的字段作为主键
常见注解:
@TableName 当实体类名称和数据库名称不一致时,使用该注解可以指定实体类对应的数据库表名
@TableId 一个作用是指定id,另一个作用是规定id的增长逻辑,没有指定默认是雪花算法:
值
描述
AUTO
数据库 ID 自增
NONE
无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT
insert 前自行 set 主键值
ASSIGN_ID
分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since ...
GORM
GORM快速使用导包
1234import ( "gorm.io/driver/mysql" "gorm.io/gorm")
模型相关一言以蔽之,GORM中,使用模型所实现的效果,就相当于 Java Mybatis 中,自动把对象中的属性变成 数据库字段 /把数据库字段变成属性
名称相关
属性名 / 字段名
GORM中也实现了 结构体字段驼峰命名 <——> 数据库字段 小写+下划线 命名的相互转化
如果结构体中的命名和数据库字段命名不只是这种差异,则默认无法映射
在Java中,对于这样的字段我们使用@Param注解,而在go中,我们为结构体参数配置Tag:
1CreateTime int64 `gorm:"column:createtime"` //必须把column加上
而go的Tag还不止这一个作用,因为gorm还可以创建表,所以后面还可以跟建表属性
1gorm:"column:id; PRIMARY_KEY"
此外,有的时候结构体和数据库并不是完全一样的,这 ...
苍穹day2-3
苍穹Day2-3swagger在controller接口方法上加上注解:
1@ApiOperation("接口名")
公共字段自动填充 ——AOP 反射 注解 枚举1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980package com.sky.aspect;import com.sky.annotation.AutoFill;import com.sky.context.BaseContext;import com.sky.enums.UpdateOrInsert;import com.sky.interceptor.JwtTokenAdminInterceptor;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.JoinPoint;import o ...
AOP
AOP基础SpringAOP实现步骤
导入依赖:在 pom.xml 文件中导入 AOP 的依赖
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>
在类名上加@Aspect注解
在方法名上加具体AOP方法注解
123456789101112131415161718192021@Component@Aspect //当前类为切面类@Slf4jpublic class RecordTimeAspect { @Around("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))") public Object recordTime(ProceedingJoinPoint pjp) throws Throwabl ...
