分布式微服务系统架构第125集:AI大模型
加群联系作者vx:xiaoda0423
仓库地址:https://webvueblog.github.io/JavaPlusDoc/
https://1024bat.cn/
一、user
表(用户表)
sql
复制编辑
create table if not exists user
(id bigint auto_increment comment 'id' primary key,userAccount varchar(256) not null comment '账号',userPassword varchar(512) not null comment '密码',userName varchar(256) null comment '用户昵称',userAvatar varchar(1024) null comment '用户头像',userProfile varchar(512) null comment '用户简介',userRole varchar(256) default 'user' not null comment '用户角色:user/admin/ban',createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',isDelete tinyint default 0 not null comment '是否删除',index idx_userAccount (userAccount)
) comment '用户' collate = utf8mb4_unicode_ci;
列名 | 类型 | 约束 / 默认值 | 说明 |
---|---|---|---|
id | bigint | auto_increment ,主键 | 自增唯一 ID |
userAccount | varchar(256) | NOT NULL | 登录账号(如手机号、邮箱或自定义账号) |
userPassword | varchar(512) | NOT NULL | 存储密码(建议储存 bcrypt 等加密后的结果) |
userName | varchar(256) | NULL | 用户昵称 |
userAvatar | varchar(1024) | NULL | 用户头像 URL |
userProfile | varchar(512) | NULL | 个人简介 |
userRole | varchar(256) | NOT NULL DEFAULT 'user' | 角色: |
createTime | datetime | NOT NULL DEFAULT CURRENT_TIMESTAMP | 记录创建时间 |
updateTime | datetime | NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 最后更新时间 |
isDelete | tinyint | NOT NULL DEFAULT 0 | 软删除标志: |
索引 | idx_userAccount (userAccount) | 登录查询或唯一校验可加唯一索引 | |
表注释 | collate = utf8mb4_unicode_ci | 支持 4 字节 UTF-8(表情等) |
二、chat
表(图表/会话信息表)
sql
复制编辑
create table if not exists chat
(id bigint auto_increment comment 'id' primary key,goal text null comment '分析目标',`name` varchar(128) null comment '图表名称',chartData text null comment '图表数据',chartType varchar(128) null comment '图表类型',userId bigint null comment '用户id',genChart text null comment '生成的图表',genResult text null comment '生成的数据',status varchar(128) not null default 'wait' comment 'wait,running,succeed,failed',execMessage text null comment '执行信息',createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',isDelete tinyint default 0 not null comment '是否删除'
) comment '图表信息表' collate = utf8mb4_unicode_ci;
列名 | 类型 | 约束 / 默认值 | 说明 |
---|---|---|---|
id | bigint | auto_increment ,主键 | 自增唯一 ID |
goal | text | NULL | 分析目标,通常是用户输入的需求文本 |
name | varchar(128) | NULL | 图表/会话名称 |
chartData | text | NULL | 输入的原始图表数据(JSON 等) |
chartType | varchar(128) | NULL | 图表类型,如 |
userId | bigint | NULL | 关联 |
genChart | text | NULL | AI 或后端生成的图表(如图表配置 JSON) |
genResult | text | NULL | AI 或后端生成的结果数据 |
status | varchar(128) | NOT NULL DEFAULT 'wait' | 任务状态: |
execMessage | text | NULL | 执行日志或错误信息 |
createTime | datetime | NOT NULL DEFAULT CURRENT_TIMESTAMP | 记录创建时间 |
updateTime | datetime | NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 最后更新时间 |
isDelete | tinyint | NOT NULL DEFAULT 0 | 软删除标志: |
表注释 | collate = utf8mb4_unicode_ci | 支持 4 字节 UTF-8 |
三、建议 & 说明
外键约束
建议在
chat.userId
上增加外键:alter table chatadd constraint fk_chat_userforeign key(userId) references user(id);
唯一索引
如果
userAccount
需要唯一,改成unique key
。
状态字段
status
建议改为enum('wait','running','succeed','failed')
,以节省存储并保证值域。
分表 / 分库
若
chat
表数据量巨大,可考虑按时间或用户分表。
软删除
isDelete
字段已支持软删除,查询时请加where isDelete=0
。
字符集
utf8mb4_unicode_ci
可存储 Emoji 等 4 字节字符,适合昵称、头像 URL 等。
mongo,cassandra,elasticsearch,redis,clickhouse,mysql,postgresql集群,扩展,多节点分布
1. MongoDB
复制集(Replica Set)
一主多从(Primary/Secondary),自动故障切换。
从节点可做读分担读流量。
分片集群(Sharded Cluster)
数据依据 shard key 切分到多个分片(Shard);每个分片内部为复制集。
Config Servers 存储元数据;Mongos 负责路由查询。
扩展
增加分片实现水平扩展;增添 Secondary 提升读可用。
Online Resharding(4.4+)支持在线调整分片键。
部署建议:至少 3 个 Config Server,偶数分片时用仲裁节点避免 split-brain。
2. Cassandra
对等节点(Peer-to-Peer)
每个节点都相同,无主从。
基于 Gossip 协议 交换拓扑,一致性哈希环 分配数据。
复制因子(RF) & 一致性级别
RF 控制每条数据复制到多少节点;读写可配置 ONE/QUORUM/ALL 等。
扩展
横向自动扩容:加入新节点,数据自动重分布(Rebalancing)。
部署建议:跨机房多机架部署,保证 RF 的多可用区冗余。
3. Elasticsearch
节点类型:Master、Data、Ingest、Coordinating(Client)
索引与分片
每个索引可设置 N 个 Primary Shard + M 个 Replica Shard。
Primary/Replica 分布在不同 Data 节点。
集群协调
Master 负责元数据管理;Coordinating 节点负责聚合请求。
扩展
增加 Data 节点后,可通过
cluster.routing.allocation
平衡分片。增加 Master 候选节点增强稳定性(奇数个,>=3)。
部署建议:Master 节点隔离,Client 节点对外负载均衡。
4. Redis
主从复制 + 哨兵(Sentinel)
一主多从,Sentinel 监控故障并自动 failover。
集群模式(Cluster)
数据分为 16384 个槽(hash slots),分布到不同主节点;每个主节点可有从节点。
客户端自动感知重定向(MOVED、ASK)。
扩展
增加主节点提升写吞吐;增加从节点提升读吞吐。
部署建议:至少 3 个 Sentinel,保证 Quorum;Cluster 模式至少 3 主 3 从。
5. ClickHouse
Shard + Replica
每个表在多个分片(Shard)上水平分区;每个分片可有多个副本(Replica)。
Table Engines
ReplicatedMergeTree
系列支持复制和副本间自动同步。
扩展
增加分片:编辑集群配置文件,重新部署新分片节点并重平衡。
部署建议:使用 ZooKeeper 管理分布式元数据、跨机房部署副本。
6. MySQL
主从复制(Replication)
一主多从,基于 binlog。读写分离提升读性能。
组复制 / InnoDB Cluster
Group Replication 实现多主(Multi-Primary)或单主模式,自动仲裁。
分库分表
Sharding Proxy(如 ShardingSphere)、Vitess、ProxySQL 等中间件支持水平拆分。
扩展
增加只读从实例;使用 Proxy 做负载均衡;使用分片中间件做写扩展。
部署建议:异地多机房部署 GTID 复制,结合 ProxySQL 做读写分离。
主从复制(Streaming Replication)
物理或逻辑复制;热备从库用于故障切换或读扩展。
Patroni / Pgpool-II / PgBouncer
Patroni + Etcd/ZooKeeper 管理高可用;Pgpool-II 做负载均衡和故障切换;PgBouncer 做连接池。
分布式扩展
Citus 扩展:将表分布到 worker 节点,实现分片和并行查询。
扩展
增加从节点做读扩展;使用 Citus 或 Citus Cloud 做写扩展。
部署建议:至少 3 个 Etcd/Consul 实例+3 个 Patroni 主体节点,保证高可用。
通用最佳实践
奇数节点:无论是仲裁节点还是选主节点,保持奇数个以达成多数派。
跨机架/机房部署:避免单点故障,保证副本分布在不同物理位置。
监控与告警:部署 Prometheus + Grafana 或 ELK、Graylog 等监控各节点健康与性能。
备份与恢复:定期全量备份(快照)+增量备份,确保可快速恢复。
自动化运维:使用 Ansible、Terraform、Kubernetes Operators(如 MongoDB Operator、Etcd Operator)等工具管理集群生命周期。
http://localhost:8108/api/doc.html#/home
1️⃣
@Target(ElementType.METHOD)
意思:这个注解只能加在“方法”上。
举例:
@AuthCheck(mustRole = "admin") public void deleteUser() { ... }
✅ 可以用在方法上
❌ 不可以用在类、字段、构造器等位置
2️⃣
@Retention(RetentionPolicy.RUNTIME)
意思:这个注解在程序运行的时候依然“存在”,并可以通过反射读取它的内容。
说明:你可以在运行时动态读取
mustRole
的值,来做权限校验。
3️⃣
public @interface AuthCheck { ... }
定义一个叫
AuthCheck
的注解。你就可以像使用@Override
那样使用它。
4️⃣
String mustRole() default ""
这是一个 注解的参数,叫
mustRole
,类型是String
,表示“必须的角色”。default ""
表示默认值是空字符串。举例:
@AuthCheck(mustRole = "admin") // 必须是 admin 角色 @AuthCheck() // 不传参数,相当于默认空字符串
📌 使用场景示例(配合 AOP 做权限控制)
比如你定义了以下方法:
@AuthCheck(mustRole = "admin") public void deleteUserAccount() {// 删除账号逻辑 }
你可以在后台通过 AOP 切面读取这个注解的值,判断当前登录用户是否是
admin
,否则拒绝执行这个方法。🔹
@Aspect
+@Component
@Aspect @Component
@Aspect
:标识这是一个 切面类,Spring AOP 会识别它。@Component
:让这个类变成 Spring 管理的 Bean,才能自动注入和工作。
🔹 拦截逻辑的主函数
@Around("@annotation(authCheck)")
@Around
:表示“环绕通知”,就是在目标方法执行 之前和之后都能插手干预。@annotation(authCheck)
:只拦截打了@AuthCheck
注解的方法。authCheck
就是注解的实例。
🔹 获取注解中的角色要求
String mustRole = authCheck.mustRole();
如果你写的是:
@AuthCheck(mustRole = "admin")
那
mustRole
就是"admin"
。🔹 获取当前请求与用户
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); User loginUser = userService.getLoginUser(request);
拿到当前请求对象,然后调用
userService
拿出登录用户。@Component
:把这个类交给 Spring 管理,后续可以自动注入使用。BiMessageProducer
:就是“发送消息的人”。
假设你在一个点餐系统中:
用户点单后,你需要把这个订单数据发到“厨房系统”;
那么你可以:
biMessageProducer.sendMessage("订单:奶茶1杯");
然后 RabbitMQ 就会“帮你传话”,把这条消息送给对应的消费者。
注入两个服务类:
AiManager
:调用 AI 分析图表。ChartService
:查和更新图表信息。
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = BiMqConstant.BI_QUEUE_NAME),exchange = @Exchange(name = BiMqConstant.BI_EXCHANGE_NAME, type = ExchangeTypes.DIRECT),key = BiMqConstant.BI_ROUTING_KEY),ackMode = "MANUAL" )
监听器的配置,告诉 RabbitMQ:
哪个队列(
BI_QUEUE_NAME
);哪个交换机(
BI_EXCHANGE_NAME
);用什么路由键(
BI_ROUTING_KEY
);
ackMode = "MANUAL"
表示:消息手动确认,不确认就不会从队列移除。
📨 方法参数说明(很关键)
private void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag)
message
:收到的消息内容(这里是图表 ID 的字符串)。channel
:RabbitMQ 通信通道,用于确认/拒绝消息。deliveryTag
:消息唯一编号,确认时要用。
/*** 分析目标*/ private String goal;
/*** 图表类型*/ private String chartType;
/*** 图表数据*/ private String chartData;
🧠 拼接 AI
StringBuffer userInput = new StringBuffer(); userInput.append("你是一个数据分析师...").append("分析目标:").append(chart.getGoal())...
把 chart 里的信息拼成 AI 要求的输入格式:
分析目标
图表类型(如柱状图)
原始数据(CSV 格式)
🧠 调用 AI,生成结果
String result = aiManager.doChat(userInput.toString()); String[] splits = result.split("【【【【【");
✅ 确认消息处理成功
channel.basicAck(deliveryTag, false);
RabbitMQ 要求你手动告诉它“这条消息处理完了”,否则它会反复发。
一个流水线机器人:
等待 RabbitMQ 叫它干活;
拿到图表 ID;
去数据库拿详细信息;
拼成 AI 能看懂的输入;
让 AI 输出图表代码和结论;
写回数据库;
告诉 RabbitMQ:我干完了!
public enum ErrorCode {// ========== 成功 ==========SUCCESS(0, "成功", "操作成功"),// ========== 参数错误 ==========PARAMS_ERROR(40000, "请求参数错误", "请求参数不符合预期"),VALIDATION_ERROR(40001, "参数校验失败", "字段格式或约束错误"),// ========== 认证 & 授权 ==========NOT_LOGIN_ERROR(40100, "未登录", "用户未登录,请先登录"),NO_AUTH_ERROR(40101, "无权限", "当前用户无访问权限"),// ========== 资源访问错误 ==========FORBIDDEN_ERROR(40300, "禁止访问", "服务器理解请求但拒绝执行"),NOT_FOUND_ERROR(40400, "资源不存在", "请求的数据或页面不存在"),// ========== 系统错误 ==========SYSTEM_ERROR(50000, "系统错误", "服务器内部发生错误,请联系管理员"),OPERATION_ERROR(50001, "操作失败", "请求的操作未成功执行"),SERVICE_UNAVAILABLE(50300, "服务不可用", "系统维护中,请稍后再试"),// ========== 频率限制 ==========TOO_MANY_REQUEST(42900, "请求频繁", "请求过于频繁,请稍后重试"),// ========== 业务逻辑错误 ==========DUPLICATE_OPERATION(60001, "重复操作", "请勿重复提交"),DATA_CONFLICT(60002, "数据冲突", "存在重复或冲突的数据"),DATA_NOT_READY(60003, "数据未就绪", "请稍后重试,数据正在处理中");private final int code;private final String message;private final String description;ErrorCode(int code, String message, String description) {this.code = code;this.message = message;this.description = description;}public int getCode() {return code;}public String getMessage() {return message;}public String getDescription() {return description;} }
CORS 跨域配置类,用于让前端页面可以访问后端接口,即使它们的域名或端口不同。
✅ 什么是 CORS?
CORS 全称是 Cross-Origin Resource Sharing(跨域资源共享) 。
默认情况下,浏览器不允许前端去请求一个不同域名/端口/协议的接口,需要配置后端允许“跨域访问”。比如:
前端在
http://localhost:3000
后端在
http://localhost:8080
👉 这就叫“跨域”@Configuration
:告诉 Spring 这是一个配置类(类似全局设置)。WebMvcConfigurer
:这是 Spring Web 的一个接口,你可以用它来自定义 Web 行为(比如 CORS、静态资源、拦截器等)。
.allowCredentials(true) 允许前端携带 Cookie、token 等凭证。
⚠️ 注意:如果允许携带 Cookie,就不能用 allowedOrigins(""),要用 allowedOriginPatterns("")。
@Configuration
:这个类是一个 配置类,会被 Spring 自动加载。@MapperScan("com.sss.bibackend.mapper")
:告诉 MyBatis 去扫描你指定的包下的
Mapper
接口(也叫 DAO 层)。例如你有一个接口
UserMapper
放在com.sss.bibackend.mapper
里,这里就会自动注册它。
📌 Bonus:分页查询怎么用?
你写完这个配置后,可以这样分页查询:
Page<User> page = new Page<>(1, 5); // 第1页,每页5条 Page<User> resultPage = userMapper.selectPage(page, null); List<User> records = resultPage.getRecords(); // 查到的数据 long total = resultPage.getTotal(); // 总条数
我们有一个
User
表,字段如下:id
:主键username
:用户名email
:邮箱age
:年龄
1️⃣ 数据库建表语句(MySQL)
CREATE TABLE user (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50),email VARCHAR(100),age INT );
2️⃣ 实体类
User.java
@Data @TableName("user") public class User {private Long id;private String username;private String email;private Integer age; }
3️⃣ Mapper 接口
UserMapper.java
public interface UserMapper extends BaseMapper<User> {// 无需添加任何代码,MyBatis-Plus 会自动实现分页功能 }
4️⃣ Service 示例
UserService.java
public interface UserService extends IService<User> {Page<User> searchUsers(String username, Integer minAge, int current, int size); }
实现类
UserServiceImpl.java
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Overridepublic Page<User> searchUsers(String username, Integer minAge, int current, int size) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();// 如果用户名不为空,模糊查询if (StringUtils.isNotBlank(username)) {queryWrapper.like("username", username);}// 如果设置了最小年龄,做大于等于筛选if (minAge != null) {queryWrapper.ge("age", minAge);}Page<User> page = new Page<>(current, size);return this.page(page, queryWrapper); // 调用 MyBatis-Plus 分页查询} }
5️⃣ Controller 示例
UserController.java
@RestController @RequestMapping("/user") public class UserController {@Resourceprivate UserService userService;@GetMapping("/search")public Page<User> searchUsers(@RequestParam(required = false) String username,@RequestParam(required = false) Integer minAge,@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size) {return userService.searchUsers(username, minAge, page, size);} }
@Configuration
:告诉 Spring Boot 这是一个配置类,要自动加载。@ConfigurationProperties(prefix = "threadpool")
:表示你可以在配置文件(如
application.yml
)里写threadpool.xxx
的配置,自动绑定到这个类的字段上。
@Data
:Lombok 提供的注解,自动生成 getter/setter、toString 等。@Bean
:把这个线程池交给 Spring 管理,以后可以通过注入@Autowired
来使用它。Runnable r:每个要执行的任务(也可以看成一个函数)。
newThread(r) :线程池内部需要新线程时就会调用这个方法。
设置线程名字为:
线程1
、线程2
……,方便日志调试。
🚀 创建线程池本体
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, // 核心线程数maximumPoolSize, // 最大线程数keepAliveTime, // 非核心线程的存活时间TimeUnit.MILLISECONDS, // 时间单位new ArrayBlockingQueue<>(4), // 队列容量 4 的阻塞队列threadFactory // 上面自定义的线程工厂 );
线程池怎么工作的?
核心线程数(比如 2):一直保留,即使空闲;
最大线程数(比如 4):超过核心线程后再用,任务多了就扩容;
队列(大小为 4):任务先进入队列排队;
自定义线程工厂:创建线程时用你定义的名字;
超出容量(线程 + 队列都满)时会报错(默认策略是
AbortPolicy
)。
使用线程池的方法(举个例子)
@Autowired private ThreadPoolExecutor threadPoolExecutor;public void doSomethingAsync() {threadPoolExecutor.execute(() -> {// 异步任务代码System.out.println("当前线程:" + Thread.currentThread().getName());}); }
public class BusinessException extends RuntimeException
这个类继承了 RuntimeException,说明它是一个运行时异常。
使用起来很方便,可以不写 try...catch 也能抛出。
同一个用户每秒最多请求 2 次
🧩 注入 Redisson 客户端
@Resource private RedissonClient redissonClient;
RedissonClient
是操作 Redis 的 Java 客户端,功能强大,支持分布式锁、限流器等;这里我们用的是它的限流器(RateLimiter)功能。
🧱 创建限流器
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key); rateLimiter.trySetRate(RateType.OVERALL, 2, 1, RateIntervalUnit.SECONDS);
getRateLimiter(key)
:从 Redis 中拿一个名为key
的限流器,如果不存在就创建;trySetRate(...)
:RateType.OVERALL
:总的限流(所有客户端共享这个限制);2
:允许每个周期(1 秒)最多执行 2 次;RateIntervalUnit.SECONDS
:单位是秒。
✔️ 翻译成人话就是:
“我允许这个 key(比如 user:123)每秒最多只能干 2 次,再多就不行。”
你在 Controller 或 Service 中这样使用:
redisLimiterManager.doRateLimit("user:" + userId); // 如果没抛异常,就可以执行后续逻辑
Redisson 限流 + 接口注解限流
🧱 最终实现效果:
@RateLimit(key = "user:limit", permitsPerSecond = 2, time = 1, unit = TimeUnit.SECONDS) @GetMapping("/test") public String test() {return "请求成功!"; }
请求超过每秒 2 次 → 自动抛出限流异常!
星火大模型(Spark)发送用户消息
sparkRequest
:后面会构建这个对象,封装用户要发给 AI 的内容;sparkClient
:客户端对象,用来发起请求给大模型。
构建对话内容
List<SparkMessage> messages = new ArrayList<>(); messages.add(SparkMessage.systemContent("你是一个数据分析师...")); messages.add(SparkMessage.userContent(message));
创建对话消息列表:
第一条是系统设定(告诉 AI 它扮演谁);
第二条是用户真正输入的分析目标+数据。
数据万象文本审核
调用腾讯云 COS(对象存储)进行文档内容合规检测
把用户上传的文件上传到腾讯云 COS,然后调用内容审核接口判断该文件是否包含违规内容(如暴力、涉黄等),如果违规就抛出异常。
📁 获取文件流并上传到 COS
inputStream = multipartFile.getInputStream(); ObjectMetadata objectMetadata = new ObjectMetadata(); String bucketName = "bi-1324629091"; String key = "folder/" + multipartFile.getOriginalFilename(); PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, objectMetadata); PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
将
MultipartFile
转成InputStream
;构造上传请求
PutObjectRequest
;key
是文件路径 + 名称;上传文件到 COS(腾讯云对象存储)。
用户上传文件 → 上传到腾讯 COS → 发起内容审核 → 等待审核结果 → 如果不合格就抛异常,阻止后续逻辑执行。
相关文章:
分布式微服务系统架构第125集:AI大模型
加群联系作者vx:xiaoda0423 仓库地址:https://webvueblog.github.io/JavaPlusDoc/ https://1024bat.cn/ 一、user 表(用户表) sql 复制编辑 create table if not exists user (id bigint auto_increment comment id pri…...

MySQL 8.0 OCP 英文题库解析(三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题16~25 试题16:…...
MapReduce 模型
引言 MapReduce 是分布式计算领域的里程碑式模型,由 Google 在 2004 年论文中首次提出,旨在简化海量数据处理的复杂性。其核心思想是通过函数式编程的 Map (映射)和 Reduce (归约)阶段&#x…...

Docker容器启动失败?无法启动?
Docker容器无法启动的疑难杂症解析与解决方案 一、问题现象 Docker容器无法启动是开发者在容器化部署中最常见的故障之一。尽管Docker提供了丰富的调试工具,但问题的根源往往隐藏在复杂的配置、环境依赖或资源限制中。本文将从环境变量配置错误这一细节问题入手&am…...
mysql dump 导入导出用法
导出 指定库中指定的表 mysqldump -uroot -pmysql databasename table1 table2 > ./bak.sql 导入 mysql -uroot -p123456 databasename< ./bak.sql 导出指定数据库 mysqldump -uroot -p123456 databasename > ./databasename.sql 导入: mysql -uroot…...

MySQL 数据类型全面指南:从理论到实践
在数据库设计和开发中,数据类型的选择是构建高效、可靠系统的基石。MySQL作为最流行的关系型数据库之一,提供了丰富的数据类型以满足各种数据存储需求。本文将全面介绍MySQL的数据类型体系,通过理论讲解和实际示例,帮助开发者做出…...
第二课:ESP32 使用 PWM 渐变控制——实现模拟呼吸灯或音调变化
第二课:ESP32 使用 PWM 渐变控制——实现模拟呼吸灯或音调变化 🧠 一、PWM 占空比与亮度/音量控制原理 PWM(Pulse Width Modulation,脉宽调制)是一种常用的数字信号控制方式,广泛应用于 LED 灯光亮度、电…...
Quartus与Modelsim-Altera使用手册
目录 文章内容: 视频内容: Quartus: ModelSim: 顶层设计与子模块: 只是对所查阅的相关文章的总结与视频总结 文章内容: 这篇对基础操作很详细: 一、Quartus II软件的使用_quartus2软件上…...

uniapp(微信小程序)>关于父子组件的样式传递问题(自定义组件样式穿透)
在父组件中给子组件添加类名,子组件的样式由父组件决定 由于"微信小程序"存在【样式隔离机制】,且默认设置为isolated(启用样式隔离),因此这里给出以下两种解决方案: // 小程序编译机制 1. 当 <style scoped> 存在时&#…...

【HCIA】BFD
前言 前面我们介绍了浮动路由以及出口路由器的默认路由配置,可如此配置会存在隐患,就是出口路由器直连的网络设备并不是运营商的路由器,而是交换机。此时我们就需要感知路由器的存活状态,这就需要用到 BFD(Bidirectio…...

计算机视觉最不卷的方向:三维重建学习路线梳理
提到计算机视觉(CV),大多数人脑海中会立马浮现出一个字:“卷”。卷到什么程度呢?2022年秋招CV工程师岗位数下降了16%,但求职人数增加了23%,求职人数与招聘岗位的比例达到了恐怖的15:1࿰…...

android抓包踩坑记录
由于需要公司业务需求,需要抓取APP中摄像机插件的网络包,踩了两天坑,这里做个总结吧。 事先准备 android-studio emulatesdk 需要android模拟器和adb调试工具。如果已经有其他模拟器的话,可以只安装adb调试工具即可 mitmproxy…...

Webpack其他插件
安装html打包插件 const path require(path); const HtmlWebpackPlugin require(html-webpack-plugin) module.exports {entry: path.resolve(__dirname,src/login/index.js),output: {path: path.resolve(__dirname, dist),filename: ./login/index.js,clean:true},Plugin:…...
如何正确地写出单例模式
如何正确地写出单例模式 | Jarks Blog 枚举方式: public class SingletonObject {private SingletonObject() {}/*** 枚举类型是线程安全的,并且只会装载一次*/private enum Singleton {INSTANCE;private final SingletonObject instance;Singleton() {…...
常见相机焦段的分类及其应用
相机焦段是指镜头的焦距范围,决定了拍摄时的视角、画面范围和透视效果。不同焦段适合不同的拍摄场景和主题,以下是常见焦段的分类及其应用: 一、焦段的核心概念 焦距:镜头光学中心到成像传感器的距离(单位:…...

Python Matplotlib 库【绘图基础库】全面解析
让AI成为我们的得力助手:《用Cursor玩转AI辅助编程——不写代码也能做软件开发》 一、发展历程 Matplotlib 由 John D. Hunter 于 2003 年创建,灵感来源于 MATLAB 的绘图系统。作为 Python 生态中最早的可视化工具之一,它逐渐成为科学计算领…...

C++ string数据查找、string数据替换、string子串获取
string查找示例见下,代码见下,以及对应运行结果见下: #include<iostream>using namespace std;int main() {// 1string s1 "hellooooworld";cout << s1.find("oooo") << endl;// 2cout << (in…...
入侵检测SNORT系统部署过程记录
原理背景知识: 一、入侵检测系统介绍 1、入侵检测系统 入侵检测(Intrusion Detection) 指通过对计算机网络或计算机系统中的若干关键点收集信息并对其进行分析,从中发现网络或系统中是否有违反安全策略的行为和被攻击的迹象。 入侵检测系统(IDS) 是从网络和系统中收集…...
使用 Java 反射动态加载和操作类
Java 的反射机制(Reflection)是 Java 语言的一大特色,它允许程序在运行时检查、加载和操作类、方法、字段等元信息。通过 java.lang.Class 和 java.lang.reflect 包,开发者可以动态加载类、创建实例、调用方法,甚至在运行时构造新类。反射是 Java 灵活性的核心,广泛应用于…...

关于甲骨文(oracle cloud)丢失MFA的解决方案
前两年,申请了一个招商的多币种信用卡,然后就从网上撸了一个oracle的免费1h1g的服务器。 用了一段时间,人家要启用MFA验证。 啥叫MFA验证,类似与短信验证吧,就是绑定一个手机,然后下载一个app,每…...
vue3项目中使用CodeMirror组件的详细教程,中文帮助文档,使用手册
简介 这是基于 Vue 3 开发的 CodeMirror 组件。该组件基于 CodeMirror 5 开发,仅支持 Vue 3。 除了支持官方提供的各种语法模式外,还额外添加了日志输出展示模式,开箱即用,但不一定适用于所有场景。 如需完整文档和更多使用案例…...
C++ stl中的list的相关函数用法
文章目录 list的介绍list的使用定义方式 插入和删除迭代器的使用获取元素容器中元素个数和容量的控制其它操作函数 list的使用,首先要包含头文件 #include <list>list的介绍 1.list是一种可以在常数范围内在链表中的任意位置进行插入和删除的序列式容器&…...

【网络编程】七、详解HTTP 搭建HTTP服务器
文章目录 Ⅰ. HTTP协议的由来 -- 万维网Ⅱ. 认识URL1、URL的格式协议方案名登录信息 -- 忽略服务器地址服务器端口号文件路径查询字符串片段标识符 2、URL的编码和解码 Ⅲ. HTTP的报文结构1、请求协议格式2、响应协议格式🎏 写代码的时候,怎么保证请求和…...

[Java实战]Spring Boot 快速配置 HTTPS 并实现 HTTP 自动跳转(八)
[Java实战]Spring Boot 快速配置 HTTPS 并实现 HTTP 自动跳转(八) 引言 在当今网络安全威胁日益严峻的背景下,为 Web 应用启用 HTTPS 已成为基本要求。Spring Boot 提供了简单高效的方式集成 HTTPS 支持,无论是开发环境测试还是生产环境部署࿰…...
Spring Boot 中的重试机制
Retryable 注解简介 Retryable 注解是 Spring Retry 模块提供的,用于自动重试可能会失败的方法。在微服务架构和分布式系统中,服务之间的调用可能会因为网络问题、服务繁忙等原因失败。使用 Retryable 可以提高应用的稳定性和容错能力 1。 使用步骤 &…...
【React中useRef钩子详解】
一、useRef的核心特性 useRef是React提供的Hook,用于在函数组件中创建可变的持久化引用,具有以下核心特性: 持久化存储 返回的ref对象在组件整个生命周期内保持不变,即使组件重新渲染,current属性的值也不会丢失。无触发渲染 修改ref.current的值不会导致组件重新渲染,适…...
golang-ErrGroup用法以及源码解读笔记
介绍 ErrGroup可以并发执行多个goroutine,并可以很方便的处理错误 与sync.WaitGroup相比 错误处理 sync.WaitGroup只负责等待goroutine执行完成,而不处理返回值或者错误errgroup.Group目前虽然不能直接处理函数的返回值或错误。但是当goroutine返回错…...
17.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--loki
在微服务中,日志是非常重要的组成部分。它不仅可以帮助我们排查问题,还可以帮助我们分析系统的性能和使用情况。 一、loki简介 loki是一个开源的日志聚合系统,它可以帮助我们高效地收集、存储和分析日志数据。loki的设计理念是“简单、快速…...

CVPR计算机视觉顶会论文解读:IPC-Dehaze 如何解决真实场景去雾难题
【CVPR 2025】迭代预测-评判编解码网络:突破真实场景去雾的极限 摘要 本文提出了一种名为IPC-Dehaze的创新去雾方法,通过迭代预测-评判框架和码本解码机制,有效解决了现有去雾算法在复杂场景下的性能瓶颈。该方法在多个基准测试中取得了SOT…...

ppy/osu构建 ipad作为osu按键xz笔记2 deepwiki websokect
ipad当x和z键玩osu #无声打osu#没磁轴怎么打osu 下载 .NET (Linux、macOS 和 Windows) | .NET dotnet还行 构建:f5 运行:dotnet run --project osu.Desktop -c Debug deepwiki就是nb uinput是ubuntu的我现在没法调试,放着 import asyn…...