如何让QPS提升20倍
一、什么是QPS
QPS,全称Queries Per Second,即每秒查询率,是用于衡量信息检索系统(例如搜索引擎或数据库)或请求-响应系统(如Web服务器)每秒能够处理的请求数或查询次数的一个性能指标。以下是对QPS的详细解释:
一、定义与意义
- 定义:QPS表示系统在单位时间(通常为一秒)内能够成功处理的请求数量。在高并发场景下,这个指标尤为重要,因为它直接关系到系统的稳定性和用户体验。
- 意义:QPS是衡量服务器性能的关键指标之一,它直接反映了系统处理请求的能力。通过监控和优化QPS,可以确保系统在高负载下依然保持高效稳定运行。
二、计算方法
QPS的计算公式为:QPS = 总请求数 / 时间段(秒)。具体计算步骤如下:
确定时间窗口:根据实际需求和服务器负载情况来确定时间窗口,可以是1秒、1分钟、5分钟等。
收集查询日志:收集服务器在该时间窗口内的查询日志,并统计成功处理的请求总数。
计算QPS:将总请求数除以时间窗口的总秒数,即可得到平均每秒的查询率。
例如,如果在1分钟内系统处理了3000个请求,则QPS = 3000 / 60 = 50 QPS,意味着系统平均每秒处理了50个请求。
三、与并发数和响应时间的关系
QPS与系统的并发数和响应时间紧密相关。具体来说:
并发数:并发数是指系统在同一时间内处理的请求数量。并发数越高,系统在单位时间内能够处理的请求数量也就越多,从而可能提高QPS。
响应时间:响应时间是指系统从接收到请求到返回响应结果所需的时间。响应时间越短,系统在单位时间内能够处理的请求数量也就越多,同样可能提高QPS。
因此,在优化系统性能时,可以通过增加并发数和缩短响应时间来提升QPS。
二、同步代码
所谓的同步代码,也就是从我们接受到请求直到请求返回都是由一个线程处理的,如果处理代码中有阻塞那么这个时候此线程就会阻塞,在请求量比较大的情况下,也就是并发场景,这个时候会有很多的请求发过来,那么tomcat只有两百的线程,如果线程阻塞时间较长,那么tomcat的线程会被全部阻塞,导致无法处理外部请求,进而系统的吞吐量就会很低
2.1、示意图
在这张图片中可以清晰的看到,前端(移动端+pc端)发过来一个请求,这时tomcat会开启一个线程处理,这个线程从接受请求是开启直到请求返回都是一个线程在处理,那么就会存在上面所说的同步阻塞问题
到这里先思考三秒钟,该情况如何优化
这是同步代码的第一个问题。
(大家别慌,我们先提出同步代码的所有问题,然后我们一一解决)
接下来继续探索下一个问题
以上我们聊了从接受请求到处理请求都是由一个线程处理,当并发量大并且代码有阻塞的情况下,会将tomcat的线程耗尽,从而达到tomcat的瓶颈。那造成这个问题的原因是什么呢?
- 第一个:由于tomcat的线程是有限的(200)
- 第二个:由于处理代码耗时,导致线程阻塞,进而导致tomcat线程耗尽
2.2、同步处理代码图解
在这张图中,大家可以清晰的看到当需要完成这一个任务时,需要先完成任务1,再完成任务2,然后完成任务3。那么所消耗的时间就是 :time > 任务1 + 任务2 + 任务3,在这里我举个实际生活中的场景,如果你要下单,那么需要调用 用户服务(查询用户信息)—>商品服务(查询商品信息)—>积分服务(修改积分)—>订单服务(生成订单)—>库存服务(减库存)
2.3、代码示例:伪代码模拟
JSONPObject createOrder(Integer userId,Integer goodsId){// 1、调用用户服务,获取用户信息User user = getUserById(userId); // 2s// 2、调用商品服务,获取商品详情Goods goods = getGoodsById(goodsId); // 2s// 3、调用积分服务,修改积分updatePoints(userId); // 2s// 4、调用订单服务,生成订单createOrderByUserAndGoods(user,goods); // 2s// 5、调用库存服务,修改库存updateInventoryByGoodsId(goodsId); //2sreturn null;}
这里只给出了个示例,实际中链路会很长,那这个时候是不是需要花费很长的时间,那这里也将是我们需要优化的点
三、异步代码优化
首先我们使用异步代码优化第二个问题,也就是刚刚提到的代码串行所造成的耗时,进而导致的线程阻塞。
3.1、图解异步代码
先来张图
在这幅图中可以清晰看到只要到我们的处理代码,我们开启了四个线程处理,在这里我将订单服务放到了用户服务和商品服务完成之后处理,这里和你的系统设计有关系,也可以和其他服务同时并发处理,那么经过这次优化后,处理时间 time > 前四个服务中最长的 + 订单服务,这样既完成了代码串行问题的优化。
很多小伙伴在这个时候是不是想着光理论没用,要能代码实现。放心,肯定会有代码实现的。
3.2、代码示例:
JSONPObject createOrder2(Integer userId, Integer goodsId) {// 1、调用用户服务,获取用户信息CompletableFuture<User> future1 = CompletableFuture.supplyAsync(() -> {// 2sreturn getUserById(userId);});// 2、调用商品服务,获取商品详情CompletableFuture<Goods> future2 = CompletableFuture.supplyAsync(() -> {return getGoodsById(goodsId); // 2s});// 3、调用积分服务,修改积分CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {updatePoints(userId); // 2s});// 4、调用订单服务,生成订单(在用户服务和商品服务调用结束后执行)CompletableFuture<Void> completableFuture = future1.thenCombineAsync(future2, (user, goods) -> {createOrderByUserAndGoods(user, goods); // 2sreturn null;});// 5、调用库存服务,修改库存CompletableFuture.runAsync(() -> {updateInventoryByGoodsId(goodsId); //2s});return null;}
在这里大家你要纠结为什么用户服务和商品服务完成后调用订单服务,这个和你的业务逻辑有关系,怎么写都无所谓,在这里大量使用了CompletableFuture,接下来我详细介绍一下CompletableFuture
3.3、CompletableFuture 详讲
CompletableFuture是Java 8中引入的一个类,它实现了Future和CompletionStage接口,为异步编程提供了强大的支持。以下是对CompletableFuture的详细介绍:
3.3.1、基本概念与特性
- 异步执行:CompletableFuture允许任务在后台线程中异步执行,不会阻塞主线程,从而提高了应用程序的响应性和性能。
- 可组合性:CompletableFuture的操作可以组合成一个或多个CompletableFuture对象,构成复杂的异步计算链。这包括结果的转换、组合以及异常处理等。
- 异常处理:通过exceptionally()等方法,CompletableFuture可以捕获计算中的异常并返回默认值,或者通过handle()等方法同时处理正常结果和异常。
- 取消与超时:支持取消异步任务和设置超时时间,避免任务的无限等待。
- 非阻塞式等待:提供了非阻塞式的等待方法,如join()和getNow(),可以在不阻塞当前线程的情况下获取任务的结果。
- 并行处理:在处理多个耗时操作时,如I/O操作、数据库访问或网络请求,CompletableFuture可以并行执行这些任务,提高系统吞吐量和响应能力。
3.3.2、创建CompletableFuture实例
1、supplyAsync():用于创建返回结果的异步任务。例如:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 执行异步任务并返回结果return "Hello, CompletableFuture!";
});
2、runAsync():用于创建不返回结果的异步任务。例如:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 执行异步任务System.out.println("Task running asynchronously");
});
3.3.3、任务编排方法
3.3.3.1、转换类方法
- thenApply() / thenApplyAsync():将上一个任务的结果转换为新的结果。thenApply()在同一个线程中执行,而 thenApplyAsync()可能在新的线程中执行。
- thenAccept() / thenAcceptAsync():处理上一个任务的结果,但不返回新的值。thenAccept()在同一个线程中执行,而thenAcceptAsync()可能在新的线程中执行。
- thenRun() / thenRunAsync():在上一个任务完成后执行一个操作,不使用上一个任务的结果。
3.3.3.2、组合类方法
- thenCompose() / thenComposeAsync():将两个CompletableFuture组合成一个。当一个任务依赖另一个任务的结果时,可以使用此方法。
- thenCombine() / thenCombineAsync():组合两个独立任务的结果。需要两个独立任务的结果进行计算时,可以使用此方法。
3.3.3.3、多任务协调方法
- allOf():等待所有任务完成。适用于需要等待多个任务都完成的场景。
- anyOf():等待任意一个任务完成。适用于多个任务中只需要最快的结果的场景。
3.3.3.4、异常处理机制
- exceptionally():处理异常并提供默认值。当CompletableFuture中的任务抛出异常时,可以捕获该异常并返回一个默认值。
- handle() / handleAsync():处理正常结果和异常。无论任务是否成功完成,都可以使用此方法处理结果或异常。
- whenComplete() / whenCompleteAsync():任务完成时的回调(正常或异常)。可以在任务完成后执行一些清理工作或记录日志等。
3.3.3.5、使用示例
以下是一个简单的使用示例,展示了如何创建CompletableFuture对象、进行任务编排以及处理异常:
public class CompletableFutureExample {public static void main(String[] args) {// 创建两个异步任务CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000); // 模拟耗时操作return "Result from future1";} catch (InterruptedException e) {Thread.currentThread().interrupt();return "Task interrupted";}});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(500); // 模拟耗时操作return "Result from future2";} catch (InterruptedException e) {Thread.currentThread().interrupt();return "Task interrupted";}});// 组合两个异步任务的结果CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {return result1 + " and " + result2;});// 处理异常并提供默认值CompletableFuture<String> safeFuture = combinedFuture.exceptionally(ex -> {return "Default value due to error: " + ex.getMessage();});// 获取结果并打印try {String result = safeFuture.get(); // 阻塞等待结果返回System.out.println(result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}
}
在这个示例中,我们创建了两个异步任务future1和future2,它们分别在不同的线程中执行并返回结果。然后,我们使用thenCombine()方法将这两个任务的结果组合成一个新的CompletableFuture对象combinedFuture。接着,我们使用exceptionally()方法处理可能发生的异常,并提供一个默认值。最后,我们使用get()方法阻塞等待结果返回并打印出来。
综上所述,CompletableFuture是Java异步编程的强大工具,它提供了一种简洁且强大的方式来处理异步任务。通过丰富的API和灵活的任务编排能力,CompletableFuture可以轻松地创建、组合和链式调用异步操作,从而提高了程序的响应速度和资源利用率。
大家看完这里CompletableFuture的介绍后,再回过头去看看我们写的伪代码就知道怎么回事儿了(为什么是异步的,为什么会提高系统执行时间)
3.4、接口异步
在这里我们已经优化了同步代码所造成的线程阻塞问题,那我们如何优化tomcat因线程有限(200)而造成的吞吐量下降问题呢?
首先我们分析一下问题在哪里:1、tomcat线程池有限(200);2、占用tomcat线程时间过长
占用时间过长我们已经做了优化,针对第一个问题,最简单的方法时配置tomcat的线程数量,但是这种方法并不是我们研究的重点。这里我们依然采用异步的方式去解决问题
解决的核心思路:tomcat主线程接受请求------> 交给子线程处理 ----->找tomcat线程返回
3.4.1、图解
在这里这样写大家可能看不懂,上图:
针对这张图,我i在这里做详细介绍:
前端发起请求,tomcat接受到请求后,通过Spring MVC的DispatcherServlet将请求交给响应的 controller 处理,但这个controller返回的是一个CompletableFuture对象,那么这个时候任务就会交给子线程处理,tomcat 线程将被释放,并且spring boot会开启一个监听器,监听你返回的 CompletableFuture 对象的状态,一旦CompletableFuture对象状态被修改为完成,那么这个时候就会找到tomcat线程返回相应的结果
3.4.2代码示例
controller
@GetMapping("name")public CompletableFuture<String> getUserName(){return userService.getUserName();}@GetMapping("setName")public void setName(){userService.setUserName();}
service
CompletableFuture<String> completableFuture = new CompletableFuture<>();@Overridepublic CompletableFuture<String> getUserName() {return completableFuture;}@Overridepublic void setUserName() {completableFuture.complete("siyu");}
在这里你就会看到你请求name接口时并拿不到数据,当你在请求一下setName接口时name接口就拿到了值,这里就实现了异步操作,当然实际代码中你肯定不会这么用,这只是个示例,实际代码中设置name这一步你可能会用定时任务什么的去实现,我就不过多赘述了。
在这里优化思路已经讲完了。那来个实际优化案例,本例使用(异步+合并)的方式提升系统并发量
四、实际场景优化案例
controller 代码示例
@RestController
@RequestMapping("user")
public class UserController {@Autowiredprivate UserService userService;@GetMappingpublic CompletableFuture<User> getUserById(@RequestParam("userId") Integer userId) throws ExecutionException, InterruptedException {return userService.getUser(userId);}
}
service 代码示例
public interface UserService {CompletableFuture<User> getUser(Integer userId) throws ExecutionException, InterruptedException;
}
serviceImpl 代码示例
@Slf4j
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;private final LinkedBlockingDeque<Request> blockingDeque = new LinkedBlockingDeque<>();private final ExecutorService executorService = Executors.newFixedThreadPool(16);private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(16);@Datastatic class Request {Integer userId;CompletableFuture<User> completableFuture;}@Overridepublic CompletableFuture<User> getUser(Integer userId) {CompletableFuture<User> future = new CompletableFuture<>();Request request = new Request();request.userId = userId;request.completableFuture = future;blockingDeque.add(request);return future;}@PostConstructpublic void init() {AtomicInteger count = new AtomicInteger(0);scheduler.scheduleAtFixedRate(() -> {if (blockingDeque.isEmpty()) return;List<Request> requests = new ArrayList<>();blockingDeque.drainTo(requests);Set<Integer> userIds = requests.stream().map(Request::getUserId).collect(Collectors.toSet());List<User> usersFromDb = userMapper.selectByIds(userIds);log.info("查询数据库{}次,处理{}个请求", count.incrementAndGet(), requests.size());Map<Integer, User> userMap = usersFromDb.stream().collect(Collectors.toMap(User::getUserId, user -> user));for (Request request : requests) {CompletableFuture.runAsync(() ->{User user = userMap.getOrDefault(request.userId, null);request.completableFuture.complete(user);}).exceptionally(ex ->{log.error(ex.getMessage());return null;});}}, 200, 200, TimeUnit.MILLISECONDS);}@PreDestroypublic void destroy() {scheduler.shutdown();try {if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {scheduler.shutdownNow();if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {System.err.println("Scheduler did not terminate!");}}} catch (InterruptedException ex) {scheduler.shutdownNow();Thread.currentThread().interrupt();}executorService.shutdown();try {if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {executorService.shutdownNow();if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {System.err.println("ExecutorService did not terminate!");}}} catch (InterruptedException ex) {executorService.shutdownNow();Thread.currentThread().interrupt();}}
}
首先说明一下,本例中使用的userId,那这个场景肯能不是很多,比如说多人查询同一个热门商品,那就很好用了。
代码设计思想解读:
大量请求发过来后,构建 Request 对象,Request 对象包含请求的userId和一个Completablefuture对象,然后将 Request 放入阻塞队列,等待定时任务处理,接口直接返回Completablefuture对象。
定时任务从阻塞队列中定时弹出所有请求进行处理。拿到请求后,根据 userId 去重,然后调用批量查询接口查询数据,拿到数据后,比对 Request 中的userId和获取到数据的userId,如果相等,将获取后的数据设置到对应Request 的Completablefuture对象。完结散花。
五、祝愿
路漫漫其修远兮,吾将上下而求索。
愿明天的您遇见更好的自己
相关文章:
如何让QPS提升20倍
一、什么是QPS QPS,全称Queries Per Second,即每秒查询率,是用于衡量信息检索系统(例如搜索引擎或数据库)或请求-响应系统(如Web服务器)每秒能够处理的请求数或查询次数的一个性能指标。以下是…...
时间复杂度简介
定义 时间复杂度是用来衡量算法运行时间随着输入规模增长而增长的量级。简单来说,它描述了算法执行时间与数据规模之间的关系。我们通常用大O符号( O O O)来表示时间复杂度。例如,对于一个简单的加法运算,它的执行时间…...
记一次sealos部署k8s集群之delete了第一台master如何恢复
记一次sealos部署k8s集群之delete了第一台master如何恢复 一、背景描述 使用sealos部署了一套K8S集群 master信息:172.27.100.1、172.27.100.2、172.27.100.3 node信息:172.27.100.4、172.27.100.5 sealos安装在172.27.100.1节点,根目录下/root/.sealos/文件还在! [root…...
【json】
JSON JSON是一种轻量级的,按照指定的格式去组织和封装数据的数据交互格式。 本质上是一个带有特定格式的字符串(py打印json时认定为str类型) 在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互,类似于计算机普通话 python与json关系及相互转换…...
TypeScript语言的并发编程
TypeScript语言的并发编程 引言 随着现代应用程序的复杂性不断增加,性能和用户体验的重要性显得尤为突出。在这种背景下,并发编程应运而生,成为提升应用程序效率的重要手段。在JavaScript及其超集TypeScript中,尽管语言本身是单…...
左值引用(Lvalue Reference)和右值引用(Rvalue Reference)详解
左值引用(Lvalue Reference)和右值引用(Rvalue Reference)详解 文章目录 左值引用(Lvalue Reference)和右值引用(Rvalue Reference)详解1. 什么是左值和右值?左值&#x…...
音视频入门基础:RTP专题(1)——RTP官方文档下载
一、引言 实时传输协议(Real-time Transport Protocol,简写RTP)是一个网络传输协议,由IETF的多媒体传输工作小组1996年在《RFC 1889》中公布的。 RTP作为因特网标准在《RFC 3550》有详细说明。而《RFC 3551》详细描述了使用最小…...
【Flutter】使用ScrollController配合EasyRefresh实现列表预加载:在还未滑动到底部时加载下一页数据
需求/背景 在我们的业务场景中,列表的加载使用easy_refresh组件: https://pub.dev/packages/easy_refresh 大概效果是往上滑动到一定的offset会触发一个上滑加载,可以触发一些网络请求拉取列表后面的数据来展示。 这种模式一般在一页翻完…...
js实现md5加密
要在JavaScript中实现MD5加密并截取特定位置的字符,你可以使用像crypto-js这样的库。首先,你需要确保你的项目中包含了crypto-js库。如果你是在浏览器环境中,可以通过CDN引入;如果是在Node.js环境中,可以通过npm安装。…...
[java基础-集合篇]LinkedList源码粗析
LinkedList 的数据结构 实现List、Deque 接口,基于 双向链表实现的列表。与基于数组的 ArrayList 不同,基于链表的LinkedList 允许在列表的任何位置快速地插入和删除元素。 Java中LinkedList实现了Deque,它提供了 add, offer, remove, poll, …...
【Rust自学】11.1. 编写和运行测试
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 11.1.1. 什么是测试 在Rust里一个测试就是一个函数,它被用于验证非测试代码的功能是否和预期一致。 在一个测试的函数体里通…...
移动端屏幕分辨率rem,less
谷歌模拟器:能直接看到移动端效果 屏幕分辨率 右键电脑桌面 ,点击显示设置 PC端是逻辑分辨率,移动端代码也是参考逻辑分辨率 网页端宽度和逻辑分辨率尺寸相同 手机屏幕尺寸不同,网页宽度均为 100% 所以就需要添加视口标签&#x…...
rk3568 , buildroot , qt ,使用sqlite, 动态库, 静态库
问题说明: 客户反馈 ,buildroot 系统 ,使用qt 使用sqlite ,有报错,无法使用sqlite. 测试情况说明: 我自己测试,发现, buildroot 自己默认就是 使能了 sqlite 的。 是否解决说明&…...
web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理
web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理 1.uni.getSystemInfoSync().screenWidth; 获取屏幕宽度 2.uni.onWindowResize() 实时监测屏幕宽度变化 3.根据宽度的大小拿到每行要展示的数量itemsPerRow 4.为了确保样式能够根据 items…...
Airflow:TimeSensor感知时间条件
在数据管道工作流中,任务可能需要在特定的时间执行,或者在继续之前等待一定的时间。为了满足这些需求,Apache Airflow提供了TimeSensor,这是一种内置Sensor,可以监控当前时间,并在达到指定时间时触发后续任…...
使用Python和Neo4j驱动程序来实现小规模数据的CSV导入
要将CSV数据导入到Neo4j数据库中,你可以使用Neo4j提供的工具,比如neo4j-admin import命令(适用于大规模数据导入),或者使用Python的Neo4j驱动程序通过Cypher查询逐行插入数据(适用于小规模数据导入…...
网络安全测评技术与标准
网络安全测评概况 网络安全测评是网络信息系统和IT技术产品的安全质量保障。本节主要阐述网络安全测评的概念,给出网络安全测评的发展状况。 18.1.1 网络安全测评概念 网络安全测评是指参照一定的标准规范要求,通过一系列的技术和管理方法,获…...
某漫画网站JS逆向反混淆流程分析
文章目录 1. 写在前面1. 接口分析2. 反混淆分析 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Pyth…...
如何获取文件的MIME类型
文章目录 1. 概念介绍2. 方法与类型2.1 使用方法2.2 常见类型3. 示例代码4. 内容总结我们在上一章回中介绍了"如何加载本地图片"相关的内容,本章回中将介绍如何获取文件类型.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中提到的文件类型是指MI…...
Three.js 基础概念:构建3D世界的核心要素
文章目录 前言一、场景(Scene)二、相机(Camera)三、渲染器(Renderer)四、物体(Object)五、材质(Material)六、几何体(Geometry)七、光…...
Linux web服务器
Linux 作为 Web 服务器操作系统 安装 Web 服务器软件(以 Apache 为例) 步骤一:更新系统软件包列表 在 CentOS 系统中,使用命令 yum update -y 这个命令会连接到 CentOS 的软件包仓库,检查所有已安装软件包是否有更…...
Linux 下信号的保存和处理
信号的几个状态 信号抵达: 当接收到的信号被处理时, 此时就成为信号的抵达信号的未决: 从信号的产生到信号抵达这个时间段之间, 称为信号未决信号阻塞: 当进程设置了某个信号为阻塞后, 这个进程就不会在接收到这个信号信号忽略: 将信号设置为忽略后, 接收到这个信号, 对这个信…...
宝塔安装教程,bt怎么安装 linux
Centos安装脚本 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 37a09b35 Ubuntu/Deepin安装脚本 wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo b…...
java通过ocr实现识别pdf中的文字
需求:识别pdf文件中的中文 根据github项目mymonstercat 改造,先将pdf文件转为png文件存于临时文件夹,然后通过RapidOcr转为文字,最后删除临时文件夹 1、引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId&g…...
基于SpringBoot的养老院管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
阿里云发现后门webshell,怎么处理,怎么解决?
当收到如下阿里云通知邮件时,大部分管理员都会心里一惊吧!出现Webshell,大概是网站被入侵了。 尊敬的 xxxaliyun.com: 云盾云安全中心检测到您的服务器:47.108.x.xx(xx机)出现了紧急安全事件…...
韩顺平老师Linux学习笔记【持续更新...】
1、课程内容 1.1、课程大纲 1.2、Linux使用在哪些地方 Linux运维工程师Linux嵌入式工程师Linux下开发项目:JavaEE、大数据、Python、PHP、C/C、Go 1.3、Linux的应用领域 个人桌面领域服务器领域(最强领域)嵌入式领域 2、Linux入门 2.1、…...
Cognitive architecture 又是个什么东东?
自Langchain: https://blog.langchain.dev/what-is-a-cognitive-architecture/ https://en.wikipedia.org/wiki/Cognitive_architecture 定义 A cognitive architecture refers to both a theory about the structure of the human mind and to a computational…...
【css】浏览器强制设置元素状态(hover|focus……)
直接上步骤: 打开浏览器控制台 → 找到样式选项 → 找到:hov选项 → 点击:hov选项,会展开【设置元素状态】。 只要选中就会展示出自己写在css里面的该种状态下的样式了。...
leetcode热题100——NO.160相交链表——JAVA
一、题目描述 题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后,链表必…...
基于Media+Unity的手部位姿三维位姿估计
使用mediapipe Unity 手部位姿三维位姿估计 参考文章 基于Mediapipe的姿势识别并同步到Unity人体模型中 MediapipeUnity3d实现虚拟手_unity mediapipe-CSDN博客 需求 我的需求就是快速、准确的跟踪手部位姿并实现一个三维显示。 主要思路 搭建mdeiapipe系统,…...
cJson——序列化格式json和protobuf对比
cJson——序列化格式json和protobuf对比 1. 更小的消息体积2. 更快的序列化与反序列化速度3. 类型安全4. 向后和向前兼容性5. 更低的带宽消耗6. 高效的编码方式7. 易于跨语言支持8. 支持复杂的数据结构9. 更好的支持大型数据交换总结 Protocol Buffers (Protobuf) 和 JSON 都是…...
STM32F1学习——ADC模数转换器
一、ADC模数转换器 ADC的全称 Analog-Digital Converter 模拟-数字转换器,他可以用来将引脚上连续变换的模拟电压转换为内存中存储的数字变量。 ADC有两个重要指标,分辨率和频率。 STM32的ADC是 12位 逐次逼近型,1us转换时间,也就…...
2025-1-10-sklearn学习(36、37) 数据集转换-无监督降维+随机投影 沙上并禽池上暝。云破月来花弄影。
文章目录 sklearn学习(36、37) 数据集转换-无监督降维随机投影sklearn学习(36) 数据集转换-无监督降维36.1 PCA: 主成份分析36.2 随机投影36.3 特征聚集 sklearn学习(37) 数据集转换-随机投影37.1 Johnson-Lindenstrauss 辅助定理37.2 高斯随机投影37.3 稀疏随机矩阵 sklearn学…...
Linux之线程池与单例模式
目录 线程池 线程池代码 单例模式 饿汉模式单例模式 懒汉模式单例模式 在前几期,我们已经学习了多线程的创建和控制,学习了多线程中的同步和互斥,学习了多线程中的条件变量和信号量,基于此我们实现了基于阻塞队列和基于环形队…...
LabVIEW调用不定长数组 DLL数组
在使用 LabVIEW 调用 DLL 库函数时,如果函数中的结构体包含不定长数组,直接通过 调用库函数节点(Call Library Function Node) 调用通常会遇到问题。这是因为 LabVIEW 需要与 DLL 中的数据结构完全匹配,而包含不定长数…...
计算机的错误计算(二百零七)
摘要 利用两个数学大模型计算 arccot(0.125664e2)的值,结果保留16位有效数字。 实验表明,它们的输出中分别仅含有3位和1位正确数字。 例1. 计算 arccot(0.125664e2)的值,结果保留16位有效数字。 下面是与一个数学解题器的对话。 以上为与…...
基于 GEE 利用 RF 回归模型实现空间降尺度
目录 1 前言 2 完整代码 3 运行结果 1 前言 本篇讲述在GEE上基于回归模型降尺度,也就是要复现以下论文,该论文发表在J-Star期刊上。 “Ebrahimy H, Aghighi H, Azadbakht M, et al. Downscaling MODIS land surface temperature product using an a…...
Linux 系统下磁盘相关指令:df、du、fdisk、lsblk
文章目录 I df、du、fdisk、lsblk指令df命令用于显示文件系统的磁盘空间使用情况du命令用于估算目录或文件的磁盘空间使用情况fdisk命令用于对磁盘进行分区操作lsblk指令查看设备信息II 应用du估算目录或文件的磁盘空间使用情况lsblk查看服务器上查看硬盘个数III 知识扩展磁盘阵…...
在线或离线llama.cpp安装和模型启动
该版本安装时间是2025-01-10,因为不同版本可能安装上会有所不同,下面也会讲到。 先说下问题——按照官方文档找不到执行命令llama-cli或./llama-cli 先附上llama.cpp的github地址:https://github.com/ggerganov/llama.cpp,build…...
(Arxiv-2023)LORA-FA:针对大型语言模型微调的内存高效低秩自适应
LORA-FA:针对大型语言模型微调的内存高效低秩自适应 paper是香港浸会大学发表在Arxiv 2023的工作 paper title:LORA-FA: MEMORY-EFFICIENT LOW-RANK ADAPTATION FOR LARGE LANGUAGE MODELS FINE-TUNING ABSTRACT 低秩自适应 (LoRA) 方法可以大大减少微调…...
Ubuntu | 系统软件安装系列指导说明
文章目录 Ubuntu 系统软件安装系列指导说明工具系列1. Docker 与 Docker-Compose部署与安装 环境系列1. Golang部署与安装 数据库系列1. PostgreSQL17.2源码部署与安装 Ubuntu 系统软件安装系列指导说明 工具系列 1. Docker 与 Docker-Compose部署与安装 链接 环境系列 1…...
攻防靶场(32):两个爆破技巧 Funbox 7 EasyEnum
目录 攻击路径一 1. 侦查 1.1 收集目标网络信息:IP地址 1.2 主动扫描:扫描IP地址段 1.3 主动扫描:字典扫描 2. 初始访问 2.1 有效帐号:本地账户 3. 权限提升 3.1 滥用特权控制机制:Sudo和Sudo缓存 4. 凭据访问 4.1 凭据…...
Vue3初学之插槽(slot)使用
在 Vue 3 中,插槽(Slots)是一种强大的内容分发机制,允许你在组件中定义可替换的内容区域,从而使组件更加通用和灵活。以下是 Vue 3 中插槽的几种常见用法: 默认插槽 默认插槽是最基本的插槽类型࿰…...
从 0 开始上手 Solana 智能合约
Solana CLI 基础知识 Solana CLI 是一个命令行界面工具,提供了一系列用于与 Solana Cluster 交互的命令。 我们将介绍一些最常见的命令,但你始终可以通过运行 solana --help 查看所有可能的 Solana CLI 命令列表。 Solana CLI 配置 Solana CLI 存储了…...
USB基础 -- USB 控制传输(Control Transfer)的重传机制
USB 控制传输(Control Transfer)的重传机制 1. 控制传输的事务结构 控制传输分为三个阶段,每个阶段都有自己的事务,并可能触发重传机制: 设置阶段(Setup Stage):主机发送 8 字节的…...
创建基本的 Electron 应用项目的详细步骤
创建一个基本的 Electron 应用项目的详细步骤。我们将从安装 Node.js 开始,然后创建项目文件夹并初始化 Electron 项目。 1. 安装 Node.js 首先,确保你已经安装了 Node.js 和 npm。你可以在终端中运行以下命令来检查是否已经安装: node -v…...
《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》
哈喽,大家好!在平常开发过程中会遇到许多意想不到的坑,本篇文章就记录在开发过程中遇到一些常见的问题,看了许多博主的异步编程,我只能说一言难尽。本文详细的讲解了异步编程之美,是不可多得的好文…...
Android 修改SVG属性并显示图片(AndroidSvg)
引入依赖: dependencies {implementation com.caverock:androidsvg-aar:1.4 }核心代码: import com.caverock.androidsvg.SVG import org.w3c.dom.Document import java.io.StringWriter import javax.xml.transform.OutputKeys import javax.xml.tran…...
Ubuntu 磁盘修复
Ubuntu 磁盘修复 在 ubuntu 文件系统变成只读模式,该处理呢? 文件系统内部的错误,如索引错误、元数据损坏等,也可能导致系统进入只读状态。磁盘坏道或硬件故障也可能引发文件系统只读的问题。/etc/fstab配置错误,可能…...