当前位置: 首页 > news >正文

Redis项目_黑马点评

部署:

1. 导入sql

开发:

Session登录:

session的原理是cookie,每个session都有个唯一的sessionId,  在每次访问tomcat的时候sessionId就会自动的写在cookie当中, 携带着sessionId就能找到session, 所以不需要返回用户凭证

每一个进入tomcat的请求都是有一个独立的线程来处理的

ThreadLocal:

每个线程都拥有一个ThreadLocalMap, 健是ThreadLocal对象, 值是所存储的变量副本

ThreadLocal为每个线程独立的提供了变量副本, 使得每个线程可以独立的操作自己的变量

对于那些只需要在单个线程中保持状态, 而不需要在多个线程之间共享的变量,使用ThreadLocal化非常合适, 可以避免使用锁带来的性能损耗. 因为每个线程上都有自己的变量副本 ,不需要进行同步操作.

注意: 如果线程结束后没有手动的删除ThreadLocal变量, 存储在线程本地变量表中的ThreadLocal对象不会自动删除, 可能导致他们不会被垃圾回收机制回收, 这样可能造成内存泄漏.

所以在使用之后应该及时的调用remove删除变量副本

配置拦截器步骤:

1. 编写实现了HandlerInterceptor接口的类, 有三个方法:

preHandler: 对应Controller方法执行之前, 返回为true则放行, 若返回false则中断执行

postHandler: 对应Controller方法执行之后, DispatcherServlet进行视图的渲染之前

afterHandler: 对应的是DispatcherServlet进行视图的渲染之后, 多用于统一的资源清理, 日志和异常的处理.

集群的session共享问题:

当服务需求比较大的时候, 一台tomcat服务器是不能满足需求的, 可能需要多条tomcat共同服务, 这时同一个用户的不同请求可能会分配到不同的tomcat上, 这时就需要tomcat之间共享session数据 来保证用户不需要重复地登录验证

前端在登陆成功后会接收token, 使用浏览器存储或者使用pinia存储, 在axios配置请求头,每次氢气都携带返回的token.

为什么使用随机生成的token作为存储用户信息的key:

1. 确保唯一性

2. 如果和存储code(验证码)一样使用手机号作为key, 那么在做登录验证的时候,就需要将手机号在登陆成功时返回前端, 这样前端在请求头中携带手机号来做登录验证, 就有比较大的数据泄露的风险,使用随机数既能确保唯一性,又能避免数据泄露.

在存储用户信息时,采用的存储结构是Hash结构,相比于使用String有两点好处: 

1. 能够修改里面的某个元素

2.内存利用率比较高

登录拦截器的优化:

在使用原来的拦截器刷新用户信息存储时间时,并不是所有的路径都被拦截, 这样就可能会使得用户在浏览一些不需要做登录验证的页面时时间过长导致需要重新登录, 为了解决这个问题, 采用如下结构

拦截器的执行顺序默认是添加顺序, 但是有一个order属性可以控制的更加严谨, order的值越小(最小为0)执行优先级越高

商户查询缓存:

redis缓存工作图:

这是将主页面的常用的商店列表的数据写入Redis

缓存更新策略:

先删缓存后更新数据库的出现缓存和数据库不一致的概率高于先更新数据库后删除缓存的概率

注意: 缓存的操作速度高于数据库的操作

数据的查和读操作速度高于写操作

先删除缓存后更新数据库情况下造成缓存和数据库不一致的发生情况为: 线程1删除缓存->线程2查询缓存未命中,查询数据库->线程2将数据写入缓存->线程1更新数据库

先更新数据库后删除缓存情况下缓存和数据库不一致的发生情况为: 缓存失效->线程1查询缓存未命中,查询数据库->线程2更新数据库->线程2删除缓存->线程1将数据写入缓存

因为对数据库的写操作相较于对数据库的查和读操作以及对缓存的操作来说速度是比较慢的, 所以先啥删除缓存后更新数据库的情况下造成缓存和数据库中的数据不一致的概率是比较大的

缓存穿透:

缓存雪崩:

缓存击穿:

基于互斥锁解决缓存击穿的问题:

redis中有一个setnx指令, 当key不存在的时候才会执行, 存在则返回为null.

利用这个特性来做为锁

整个流程:

先从redis中查询, 如果未查到, 则尝试获取锁, 如果获得锁则查询数据库并写入缓存; 如果没有获得锁, 则等待一段时间后迭代, 即先去缓存中获取,如果缓存中没有则去数据库中查找, 所以这个锁的释放一定要在写入缓存之后

基于逻辑过期的思想来解决缓存击穿的问题:

这是应对已经存储在缓存中可能会更新的数据, 首先去缓存中查找数据(不会为null, 因为前提就要把用对的数据写入缓存中), 查到数据后进行逻辑判断, 如果没有过期,则直接返回数据, 如果过期, 则返回旧数据, 并尝试获取针对该数据的锁, 如果获取锁是失败, 则直接返回数据, 如果获取锁成功, 则返回旧数据的同时另起一个线程用于去数据库查询数据, 并将其写入缓存来更新旧数据.

秒杀模块:

全局ID生成器:

                            

线程池和CountDownLatch:

private ExecutorService executor = Executors.newFixedThreadPool(300);

这是声明了一个管理300个线程的线程池, 使用它的submit方法来提交实现了Runnable接口的类,或者在类使用lambda表达式.

CountDownLatch countDownLatch = new CountDownLatch(60);

初始化值为60, 它有两个常用的方法, countDown和await方法

countDown方法会将值减一, await会阻塞当前线程

当值减到0时, 当前线程(调用await方法的线程)会继续执行

注意, 比如说, 这个函数会启动100个线程, 但是初始值设为60, 那么主线程(调用这个方法的线程,也可以是测试方法)只会等待60个线程执行完毕, 对于剩余的40个线程不会等待(但是也会启动)

同样的如果初始值设为200(比线程数大), 那么值永远都不会减为0 ,那么主线程将会一直等待

这个初始值的设定要考虑多方面因素.一般和连接池的初始化数量保持一致.

超卖问题的解决:

版本号法: 每次库存量减一的时候版本号加一

这两种方法的解决思路是一样的, 只不过CAS是用数据(库存)来替代version(版本号)

库存比较特殊, 在使用乐观锁时不一定是库存量有没有变化, 也可以是只判断库存量是否大于0

如果是判断库存量有没有变化的话, 失败率是比较高的, 因为100->99也是变化, 而99也是可以继续减少的, 所以当一个线程对库存量减一时, 其他的线程发现库存量被修改时就放弃修改, 这样就会加大请求的失败. 而将判断更改为库存量是否大于0则能够有效的避免这个问题.

一人一单问题的解决:

这个问题的解决使用到的编程技巧太带劲了.包括悲观锁的使用, 代理对象的使用, String.toString()的方法会生成一个新的对象, 所以使用 intern()方法, 这个方法的作用是确保所有具有相同字符序列的字符串字面量都被存储在一个唯一的字符串池中。当调用 intern() 方法时,如果字符串池(字符串常量池)中已经存在等于此 String 对象的字符串,则返回代表池中这个字符串的 String 对象的引用;否则,将此 String 对象添加到池中,并返回此 String 对象的引用。

对方法添加事务注解时, 如果在该类的某个方法中调用了这个方法,即this.method()

这时事务的注解是不生效的, 因为事务的实现是Spring获取类的代理对象, 由代理对象做的事务处理

所以应该使用

AopContext.currentProxy();

来生成所在类的代理对象,由该代理对象调用方法

synchronized (userId.toString().intern()){IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);}

使用该方法需要添加aspectjweaver依赖, 并且在启动类中添加@EnableAspectJAutoProxy(exposeProxy = true)的注解,来暴露代理对象

在集群模式下的一人一单的并发问题:

启动了两个进程, 就存在两个JVM,即两个锁监视器, 所以锁在另一个启动的项目中无效

分布式锁:

要做的就是让多个进程都从一个锁监视器中获取锁

判断和释放是两步, 如果判断完成后发生了阻塞, 这时可能锁已经释放了, 然后其他的线程获取了锁,并存储了自己的值, 这是阻塞结束,就会删除现存的锁,发生并发安全问题, 为了解决这个问题, 就需要将这两步合成为一步, 方法就是利用Lua脚本

Lua脚本:

java调用Lua脚本:

Redisson:

@Bean修饰方法spring会在启动时自动调用这个方法, 将返回值注册为spring管理的Bean

Redisson可重入锁的实现原理:

分布式锁的总结:

优化秒杀:

对于数据库的修改操作是比较耗时的, 所以将库存和一人一单的校验利用redis优化, 然后对于数据库的写操作另起线程做, 因为此时对于写的时效性没有要求, 这样就能提高整体的效率.

基于jvm的阻塞队列存在内存限制问题

每当重启或出现宕机时阻塞队列中的数据就会消失, 或者当从阻塞队列中拿到数据, 但是在做处理时出现异常也会造成数据安全问题

Redis提供的消息队列:

基于list的消息队列:

基于PubSub的消息队列:

基于Stream的消息队列:

消费者组:

达人探店:

点赞:

每个人只能对一个blog点一个赞, 所以考虑使用set(具有唯一性)

点赞排行榜:

按照时间顺序, 显示前五名, 这就要求存储的数据结构具有顺序, 综合下来, SortedSet满足要求.

set有ismember来判断给定元素是否存在, 而SortedSet没有这个方法, 但是可以通过score来查分数, 如果给定元素不存在则返回null, 可以根据此来判断是否已经点赞. SortedSet是根据score(分数)来自动排序的, 所以可以在里面存时间戳, 然后获取0-4的元素即为前五个.

select返回的数据默认是按照id大小的, 但是这个给定的id顺序不一致, 而给定的id顺序是点赞顺序, 所以后面要加上order by filed (id, 5, 1), 这样才会按照给定的id顺序返回

这段代码是处理获取SortedSet中前五个数据, 重点是看将从数据库中返回的List<User>转换为List<UserDTO>的过程, 先将其转换为stream<User>, 然后用其提供的map()方法转换为Stream<UserDTO>, 最后用其提供了collect()方法将其转化为List<UserDTO>

还有一个就是将List<Long>转换为用","间隔的字符串的方法:

StrUtil.join(",", ids)

关注:

在求共同关注时, 可以借助set集合的求交集的功能:SINTER, 将每个用户的的关注对象都存储在set集合中, 当前端发送求共同关注的请求时要携带访问主页的id号, 然后去到redis中求这两个id对应的set的交集.

关注推送:

拉模式: 只有在粉丝打开收件箱的时候才会去读取关注人发布的信息,然后根据发布时间去排序, 并且不做保存, 优点就是减少内存, 缺点是每次读取都要去发送请求重新获取, 并且对获取到的数据进行处理, 比较耗时.

推模式: 没有发件箱, 博主发布后直接发送到粉丝的收件箱, 能够极大程度的减少延迟, 缺点就是对内存的占用比较高.

推拉结合: 针对普通博主(粉丝比较少的)将发布的内容直接推送到粉丝; 针对大V, 将粉丝群体分为活跃粉丝和普通粉丝, 对于活跃粉丝直接将发布的内容发到其收件箱, 而对于普通粉丝则采用拉模式.

Feed流中的分页问题:

所谓滚动分页就是按照上一次查询的最后一条数据查找, 不在按照角标查询, 而List只能按照角标查询, 所以只能使用SortedSet, 因为SortedSet不仅能按照角标查询,即ZRANGE, 也能按照socre查询.

注意offset的设置

这是获取收件箱中内容的函数, 注意: 1. List<Long>用于存储收件箱中用户的id, 可以在初始化的时候大小设定为返回的个数, 这样就避免了扩容时带来的消耗. 2. os(最小时间戳的相同个数)的计算方法.

附近商户:

GEO:

地理坐标, 太牛逼了

这是将店铺的id和坐标按照店铺的类型导入到不同的geo中的测试方法

注意: 1. 将店铺List<Shop>分组成Map<Long, List<Shop>>的方式, 使用了stream流提供的按照指定内容分组的函数, 如果不知道这个方法,可能就需要来迭代一遍数组进行分组了.

用户签到:

BitMap:

用BitMap中的01来映射是否签到, 比如某个用户一个月的签到情况就可以使用一个31bit位的BitMap来表示, 第一位代表第一天,以此类推, 这样就能大大减少存储的数据量

用于签到的函数:

注意: 日期的格式化使用的函数, 获取日期的当前所在月的天数

签到统计:

UV统计:

第三个命令是合并, 可以合并多个HL

相关文章:

Redis项目_黑马点评

部署: 1. 导入sql 开发: Session登录: session的原理是cookie,每个session都有个唯一的sessionId, 在每次访问tomcat的时候sessionId就会自动的写在cookie当中, 携带着sessionId就能找到session, 所以不需要返回用户凭证 每一个进入tomcat的请求都是有一个独立的线程来处理…...

Golang Channel 使用详解、注意事项与死锁分析

#作者&#xff1a;西门吹雪 文章目录 一、引言&#xff1a;Channel 在 Go 并发编程中的关键地位二、Channel 基础概念深度剖析2.1 独特特性2.2 类型与分类细解 三、Channel 基本使用实操指南3.1 声明与初始化3.3 单向 Channel 的运用 四、Channel 典型使用场景实战案例4.1 协程…...

CSS 入门指南(一):基本概念 选择器 常用元素属性

一、初识 CSS 1, CSS 定义 层叠样式表(Cascading Style Sheets&#xff0c;缩写为 CSS)&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09; CSS 能够对网页中元素位置的排版进行 像素级 精确控制&#xff0c;实现美化页面…...

c_cpp_properties.json等三个文件解释

不建议太小白的人看啊 在 Visual Studio Code 中使用 C 语言进行编程时&#xff0c;通常会看到一些特定的配置文件。这些文件是用来帮助你配置开发环境、调试程序等 就是这三个文件 首先是c_cpp_properties.json&#xff1a; 这是 Visual Studio Code 配置 C/C 开发环境的文件。…...

G-Star 公益行起航,挥动开源技术点亮公益!

公益组织&#xff0c;一直是社会温暖的传递者&#xff0c;但在数字化浪潮中&#xff0c;也面临着诸多比大众想象中复杂的挑战&#xff1a;项目管理如何更高效&#xff1f;志愿者管理又该如何创新&#xff1f;宣传推广怎么才能更有影响力&#xff1f;内部管理和技术支持又该如何…...

Jetson Xavier NX安装CUDA加速的OpenCV

我们使用SDKManager刷机完成后&#xff0c;使用jtop查看&#xff0c;发现OpenCV 是不带CUDA加速的&#xff0c;因此&#xff0c;我们需要安装CUDA加速的OpenCV&#xff0c;这样后续在使用的时候速度会快很多。 首先我们先卸载默认OpenCV sudo apt purge libopencv* -y sudo …...

用android studio模拟器,模拟安卓手机访问网页,使用Chrome 开发者工具查看控制台信息

web 网页项目在安卓手机打开时出现问题&#xff0c;想要查看控制台调试信息。记录一下使用android studio 模拟器访问的方式。 步骤如下&#xff1a; 1.安装android studio&#xff0c;新增虚拟设备&#xff08;VDM- virtual device manager) 点击Virtual Device Manager后会…...

基于Transformer的医学文本分类:从BERT到BioBERT

随着自然语言处理(NLP)技术的快速发展,Transformer模型在文本分类、情感分析、机器翻译等任务中取得了显著成果。在医学领域,文本数据(如电子病历、医学文献、临床报告)具有高度的专业性和复杂性,传统的NLP方法往往难以处理。Transformer模型,尤其是BERT及其变体,通过…...

【Python】Django 中的算法应用与实现

Django 中的算法应用与实现 在 Django 开发中&#xff0c;算法的应用可以极大地扩展 Web 应用的功能和性能。从简单的数据处理到复杂的机器学习模型&#xff0c;Django 都可以作为一个强大的后端框架来支持这些算法的实现。本文将介绍几种常见的算法及其在 Django 中的使用方法…...

vs code配置 c/C++

1、下载VSCode Visual Studio Code - Code Editing. Redefined 安装目录可改 勾选创建桌面快捷方式 安装即可 2、汉化VSCode 点击确定 下载MinGW 由于vsCode 只是一个编辑器&#xff0c;他没有自带编译器&#xff0c;所以需要下载一个编译器"MinGW". https://…...

YOLO11 环境安装

1.安装Anaconda/Miniconda 在Ubuntu中安装Miniconda Anaconda/Miniconda pip 配置清华镜像源 Anaconda/Miniconda 基本操作命令 2.创建python虚拟环境 # 创建 conda create -n yolo11_env python3.12# 激活 conda activate yolo11_env 3.安装pytorch # Pytorch https://…...

BLEU评估指标

一、介绍 用于评估模型生成的句子和实际句子差异的指标&#xff0c;取值在[0,1]&#xff0c;匹配度高就距离1近&#xff0c;反之距离0近。这个指标计算代价小&#xff0c;容易理解&#xff0c;与语言无关&#xff0c;与人类评价结果高度相关。 BLEU主要基于n-gram匹配&#x…...

学习路之TP6 --重写vendor目录下的文件(新建命令)

[TOC](学习路之TP6 --重写vendor目录下的文件(新建命令)) 一、新建命令文件 php think make:command CustomWorker二、修改 复制vendor\topthink\think-worker\src\command\Server.php 内容到app\command\CustomWorker.php 修改继承类&#xff1a;class CustomWorker exten…...

[Linux] 3588开发准备工作

背景需求 在3588上开发软件系统&#xff0c;用于视频流读取&#xff0c;处理&#xff0c;推流等操作。一般来说&#xff0c;会先买对应型号的开发板进行开发测试。同步制作硬件&#xff0c;等到硬件回来之后&#xff0c;可将代码进行烧录到嵌入式板端&#xff0c;能够执行相应…...

小程序网络大文件缓存方案

分享一个小程序网络大图加载慢的解决方案 用到的相关api getSavedFileList 获取已保存的文件列表&#xff1b;getStorageSync 获取本地缓存&#xff1b;downloadFile 下载网络图片&#xff1b;saveFile 保存文件到本地&#xff1b;setStorage 将数据储存到小程序本地缓存&…...

在 Windows 上快速部署 OpenManus:从安装到运行

在当今快速发展的 AI 领域&#xff0c;OpenManus 作为一个强大的开源工具&#xff0c;为开发者提供了便捷的 AI 应用开发体验。本文将详细介绍如何在 Windows 系统上安装并运行 OpenManus&#xff0c;帮助你快速搭建一个本地的 AI 开发环境。 一、安装 Anaconda Anaconda 是一…...

Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决

前言 在将 Spring Boot 项目升级至 3.3.4 版本后&#xff0c;遇到 Logback 配置的兼容性问题。本文将详细描述该问题的错误信息、原因分析&#xff0c;并提供调整日志回滚策略的解决方案。 错误描述 这是SpringBoot 3.3.3版本之前的回滚策略的配置 <!-- 日志记录器的滚动…...

快速集成1688商品API:10分钟实现跨境选品数据自动化

要快速集成 1688 商品 API 以实现跨境选品数据自动化&#xff0c;可参考以下步骤&#xff1a; 注册并申请 API 权限&#xff1a;注册账号创建应用并申请所需的 API 权限&#xff0c;如商品搜索、筛选、获取详情等相关权限。获取 API Key 和 Secret&#xff1a;在应用管理页面获…...

21天 - 说说 TCP 的四次挥手?TCP 的粘包和拆包能说说吗?说说 TCP 拥塞控制的步骤?

说说 TCP 的四次挥手&#xff1f; TCP 协议是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;它通过著名的 “三次握手” 来建立连接。相对地&#xff0c;TCP 协议通过四次挥手来断开连接。以下是四次挥手的详细过程&#xff1a; 第一次挥手&#xff08;Clien…...

LeetCode:93. 复原 IP 地址(DFS Java)

目录 93. 复原 IP 地址 题目描述&#xff1a; 实现代码与解析&#xff1a; DFS 原理思路&#xff1a; 93. 复原 IP 地址 题目描述&#xff1a; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xf…...

Flutter_学习记录_device_info_plus 插件获取设备信息

引入三方库device_info_plus导入头文件 import package:device_info_plus/device_info_plus.dart;获取设备信息的主要代码 DeviceInfoPlugin deviceInfoPlugin DeviceInfoPlugin(); BaseDeviceInfo deviceInfo await deviceInfoPlugin.deviceInfo;完整案例 import package…...

详解CISC与RISC及其区别

CISC&#xff08;Complex Instruction Set Computing&#xff0c;复杂指令集计算机&#xff09;和RISC&#xff08;Reduced Instruction Set Computing&#xff0c;精简指令集计算机&#xff09;是两种不同的计算机架构理念&#xff0c;主要区别在于指令集的设计和处理方式&…...

偶然发现了 setTimeout 的隐藏彩蛋

最近在看《JavaScript高级程序设计&#xff08;第4版&#xff09;》&#xff0c;运行书中的一个代码示例时&#xff0c;偶然发现了 setTimeout 的一些之前没注意到的特性&#xff0c;觉得挺有意思的&#xff0c;就来记录一下。 书中代码如下&#xff1a; for (var i 0; i &l…...

zerotier搭建免费moon服务器

&#x1f31f; 前言 ZeroTier是一种基于P2P的虚拟组网工具&#xff0c;通过搭建‌Moon服务器‌可大幅提升跨运营商/跨国节点的连接质量。本文使用云服务演示部署流程。 &#x1f4cb; 准备工作 ‌注册三丰云账号‌ ‌创建CentOS 8.5实例‌ &#xff08;这里选择centos8以上&a…...

Unity Timeline 扩展

这里认为大家已经会timeline的基本使用了&#xff0c;只介绍怎么自定义扩展。 第一步.自定义Track 首先要自定义一条轨道。剪辑是要在轨道里跑的&#xff0c;系统自带的轨道我们加不了自定义剪辑&#xff0c;得新建自己用的。这个很简单。 [TrackClipType(typeof(TransformTw…...

HarmonyOS第21天:解锁分布式技术,开启跨设备协同新体验

一、HarmonyOS 分布式技术&#xff1a;开启万物互联新时代 在物联网蓬勃发展的今天&#xff0c;设备之间的互联互通不再是遥不可及的梦想&#xff0c;而是真切融入日常生活的现实。从智能家居设备的联动控制&#xff0c;到智能办公场景中的高效协作&#xff0c;再到智能出行中的…...

BUUCTF Pwn [ZJCTF 2019]EasyHeap unlink+freehook做法

checksec exeinfo &#xff1a; IDA64打开&#xff1a; delete_heap函数已经将指针清零 无UAF edit_heap允许自己输入读取字节 存在堆溢出 同时 存储的指针位于bss段 那接下来就想到unlink方法&#xff1a; 图示&#xff1a; 后续修改0x6020E0的位置为freehook 再修改一次 让其…...

【解决方案】RAGFlow部分问题清单及解决方案备忘1

一、长时间显示&#xff1a;Task is queued 多半是因为模型确实在队列中排队的原因&#xff0c;要么是内存一直在被占用中&#xff0c;要么是CPU或GPU一直在被占用中&#xff0c;可以首先检查硬件利用率&#xff1a; 如果是内存导致的队列缓慢&#xff0c;可以将.env文件中的M…...

Linux笔记---文件系统硬件部分

1. 文件系统 文件系统是操作系统用于明确存储设备&#xff08;常见的是磁盘&#xff0c;也有基于NAND Flash的固态硬盘&#xff09;或分区上的文件的方法和数据结构&#xff0c;即在存储设备上组织文件的方法。 1.1 基本组成 索引节点&#xff08;inode&#xff09;&#xff…...

低成本抗衡DeepSeek-R1!QwQ-32B本地部署教程:消费级硬件可部署

QwQ-32B是阿里通义千问团队在3月6日发布的开源大模型&#xff0c;这款仅有320亿参数的模型&#xff0c;在数学、代码、通用能力等核心场景里&#xff0c;几乎跟满血版DeepSeek-R1&#xff08;6710亿参数&#xff09;不相上下。可以说实现了开源领域的降维打击。 参数规模与性能…...

二叉树中堆的实现

1 堆的声明和定义 typedef int HPDateType; typedef struct Heap {HPDateType* arr;int size;int capcity; }HP; 与顺序表相似&#xff0c;我们需要一个数组&#xff0c;有效空间大小&#xff0c;有效元素个数 2 堆的初始化 void HPInit(HP*php) {assert(php);php->arr …...

概率论的基本知识

逆概率还不懂&#xff0c;改天再想想。 联合概率 联合概率&#xff08;Joint Probability&#xff09; 是概率论中的一个重要概念&#xff0c;用于描述多个随机变量同时取某些值的概率。联合概率可以帮助我们理解多个变量之间的关系。...

LVDS(Low Voltage Differential Signaling)电平详解

一、LVDS的定义与核心特性 LVDS&#xff08;低压差分信号&#xff09;是一种 低功耗、高速、抗干扰 的差分信号传输技术&#xff0c;通过一对互补的电压信号&#xff08;正负端差值&#xff09;传递数据。其核心特性包括&#xff1a; 电气特性 电压摆幅&#xff1a;差分电压约…...

2024年第十五届蓝桥杯软件C/C++大学A组——五子棋对弈

蓝桥杯原题&#xff1a; 题目描述&#xff1a; “在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f; ” 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着 “ 友谊第一&#xff0c;比赛第二…...

OpenRewrite配方之import语句的顺序——org.openrewrite.java.OrderImports

org.openrewrite.java.OrderImports 是 OpenRewrite 工具库中的一个重要规则(Recipe),专为 Java 项目设计,用于自动化调整 import 语句的顺序,使其符合预定义的代码规范。从而提高代码的一致性和可读性。 核心功能 排序规则: 静态导入优先:默认将静态导入(import stati…...

数字电子技术基础(二十八)——TTL门电路的静态功耗和动态功耗

1 静态功耗 门电路的工作需要直流电压源的支持&#xff0c;无论在模拟电路还是在数字电路中&#xff0c;只有在外加直流电源的作用下&#xff0c;半导体二极管具有单向导电性&#xff0c;晶体管的放大能力以及开关特性才能体现出来芯片的电源端正负级。芯片的电源端正负极如果…...

RISC-V汇编学习(四)—— RISCV QEMU平台搭建(基于芯来平台)

RISCV汇编学习系列&#xff1a; RISC-V汇编学习&#xff08;一&#xff09;—— 基础认识 RISC-V汇编学习&#xff08;二&#xff09;—— 汇编语法 RISC-V汇编学习&#xff08;三&#xff09;—— RV指令集 RISC-V汇编学习&#xff08;四&#xff09;—— RISCV QEMU平台搭建…...

链表的定义、节点结构、基本操作(C++)

1. 链表的基本概念 链表是一种动态数据结构&#xff0c;它的元素&#xff08;节点&#xff09;在内存中不一定是连续存储的。每个节点通过指针连接到下一个节点&#xff0c;形成一个链式结构。链表分为单向链表、双向链表和循环链表等&#xff0c;这里主要介绍单向链表。 2. …...

deepseek使用记录21——脑图记录

我们有比前人更先进的工具&#xff0c;为何不利用起来呢&#xff1f; 工作的时候&#xff0c;问问自己&#xff0c;这个问题是理论问题&#xff1f;还是实践问题&#xff1f;如何在系统中劈开一条可实践路径&#xff1f;系统中的缝&#xff0c;系统中的力量&#xff08;人先进…...

[多线程]基于阻塞队列(Blocking Queue)的生产消费者模型的实现

标题&#xff1a;[多线程]基于阻塞队列(Blocking Queue)的生产消费者模型的实现 水墨不写bug 文章目录 一、生产者消费者模型特点&#xff1a;二、实现2.1详细解释1. 成员变量2. 构造函数3. Isfull 和 Isempty4. Push 函数5. Pop 函数6. 析构函数7. GetSize 函数 三、总结与多线…...

【时时三省】(C语言基础)输入输出的概念

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 有关数据输入输出的概念 从前面的程序中可以看到&#xff1a;几乎每一个C程序都包含输入输出。因为要进行运算&#xff0c;就必须给出数据&#xff0c;而运算的结果当然需要输出&#xff0c…...

基于ragflow中deepdoc对pdf文档的rag系统

基于ragflow中deepdoc对pdf文档的rag系统 一、安装 conda环境安装到指定的路径 conda create 包名/环境的名字 rag就是包的名字&#xff0c;ragflow就是环境名&#xff1b; 怎样激活环境&#xff1f;–我是在百度飞桨上面跑的 conda activate /home/aistudio/rag/ragflow …...

基于WebRTC技术的EasyRTC嵌入式音视频SDK:多平台兼容与性能优化

在当今数字化、智能化的时代背景下&#xff0c;实时音视频通信技术已成为众多领域不可或缺的关键技术。基于WebRTC技术的EasyRTC嵌入式音视频SDK&#xff0c;凭借其在ARM、Linux、Windows、安卓、iOS等多平台上的兼容性&#xff0c;为开发者提供了强大的工具&#xff0c;推动了…...

Linux驱动开发实战(四):设备树点RGB灯

Linux驱动开发实战&#xff08;四&#xff09;&#xff1a;设备树点RGB灯 文章目录 Linux驱动开发实战&#xff08;四&#xff09;&#xff1a;设备树点RGB灯前言一、驱动实现1.1 驱动设计思路1.2 关键数据结构1.3 字符设备操作函数1.4 平台驱动探测函数1.5 匹配表和平台驱动结…...

大模型架构记录5-向量数据库

一 倒排索引、KNN、PQ 1.1 基础版本 query -> requery 对问题做处理&#xff0c;处理上下文 对query 做 refined query 1.2 向量数据库 二 搜索逻辑 2.1 knn 2.2 近似KNN 先和N个空间的均值比较再和空间内部的所有点比较&#xff0c;计算最近值。 优化一&#xff1a; …...

【 Fail2ban 使用教程】

Fail2ban 使用教程 1. 安装 Fail2ban2. 配置 Fail2ban2.1 创建 jail.local 文件2.2 基本配置参数说明2.3 配置具体服务的监控规则2.3.1 SSH 服务2.3.2 Apache 服务 3. 启动和管理 Fail2ban3.1 启动 Fail2ban 服务3.2 设置 Fail2ban 开机自启3.3 检查 Fail2ban 服务状态3.4 重新…...

Django系列教程(8)——函数视图及通用类视图

目录 什么是视图(View)及其工作原理 接近现实的函数视图 更复杂的案例: 视图处理用户提交的数据 基于函数的视图和基于类的视图 Django通用类视图 a. ListView b. DetailView c. CreateView d. UpdateView e. FormView f. DeleteView 小结 Django的视图(view)是处理…...

【C#学习笔记04】C语言格式化输出

引言 ​​printf()​​函数不仅可以将数据输出到控制台&#xff0c;还可以通过格式化字符串灵活地控制输出的格式。​​printf()​​​函数的使用规则&#xff0c;包括标志说明、字段宽度、转换精度、长度修饰、转换说明、转义字符。 1. ​​printf()​​函数概述 ​​printf…...

九点标定和十二点标定的区别

九点标定和十二点标定是机器视觉中常用的两种手眼标定方法&#xff0c;用于建立图像坐标系与机械坐标系之间的映射关系。它们的核心区别在于标定点的数量、变换模型和适用场景。以下是详细对比&#xff1a; 1. 九点标定 特点 标定点数量&#xff1a;9 个点&#xff0c;通常排…...

qt+opengl 播放yuv视频

一、实现效果 二、pro文件 Qt widgets opengl 三、主要代码 #include "glwidget.h"GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent) {connect(&m_timer, &QTimer::timeout, this,[&](){this->update();});m_timer.start(1000/33); }v…...