文件服务器FastDFS 消息队列中间件RabbitMQ
新标签页 (chinaunix.net)
FastDFS - Browse Files at SourceForge.net
一、FastDFS
Tracker和Storage:
tracker用来管理所有的storage,只是管理服务器,负责负载均衡。
storage是存储服务器,每一个storage服务器都是一个单独的个体,storage服务器之间没有交互关系。
在storage中根目录包含256个一级目录、每个一级目录中包含256个二级子目录,在二级子目录中存储图片。存储图片时服务器会返回相应的group和remote,访问文件时通过这两个键值对获取图片。
①、在虚拟机中使用docker安装FastDFS
docker load -i fastdfs.tar //在docker中加载镜像源文件mkdir -p /opt/fdfs/tracker docker run -d --network=host --name tracker -v /opt/fdfs/tracker:/var/fdfs delron/fastdfs tracker mkdir -p /opt/fdfs/storagedocker run -d --network=host --name storage -e TRACKER_SERVER=192.168.222.128:22122 -v /opt/fdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage//重启服务器需要删除文件。
rm -rf /opt/fdfs/tracker/data/*.pid
rm -rf /opt/fdfs/storage/data/*.pid//更改服务器的磁盘限制
docker exec -it tracker bash
cd /etc/fdfs
vi /etc/fdfs/tracker.conf
reserved_storage_space = 10K //磁盘剩余多少空间时关闭上传文件功能
②、java代码使用FastDFS
1)首先编写FastDFS配置信息fdfs.properties
fastdfs.connect_timeout_in_seconds=10 fastdfs.network_timeout_in_seconds=30 fastdfs.charset=UTF-8 # tracker???????????????? fastdfs.tracker_servers=192.168.222.128:22122 # tracker????????tracker.conf??http?????????? fastdfs.http_tracker_http_port=8080
2)FastDFS 操作工具类
封装了加载配置文件fdfs.properties的静态代码块,还有上传和下载的方法。
package com.xja.util;import org.csource.common.NameValuePair; import org.csource.fastdfs.*;import java.io.InputStream; import java.util.Properties;/*** FastDFS Java客户端工具*/ public final class FastDFSUtils {/*** 定义静态属性,Properties和StorageClient*/private final static Properties PROPERTIES;private final static StorageClient STORAGE_CLIENT;/*** 静态初始化代码块,初始化静态属性* 静态初始化代码块有异常如何处理?* 处理的时候,try。。catch。。 抛出一个Error,终止虚拟机。*/static{try {PROPERTIES = new Properties();// 读取配置文件PROPERTIES.load(FastDFSUtils.class.getClassLoader().getResourceAsStream("fdfs.properties"));// 使用ClientGlobal初始化FastDFS客户端配置ClientGlobal.initByProperties(PROPERTIES);// 创建Tracker客户端对象TrackerClient trackerClient = new TrackerClient();// 基于Tracker客户端对象,获取Tracker服务器对象TrackerServer trackerServer = trackerClient.getConnection();// 基于Tracker服务器和客户端对象,获取Storage服务器对象StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);// 创建Storage客户端对象STORAGE_CLIENT = new StorageClient(trackerServer, storageServer);}catch (Exception e){throw new ExceptionInInitializerError(e);}}/*** 删除文件* int delete_file(String 卷名, String 路径及文件名);* 返回值: 0代表成功,其他数字代表错误编码*/public static int remote(String group, String remote){try {return STORAGE_CLIENT.delete_file(group, remote);}catch (Exception e){e.printStackTrace();return -1;}}/*** 查询某文件的元数据* @param group 卷名* @param remote 路径及文件名* @return 返回文件的元数据数组。发生错误返回null*/public static NameValuePair[] getMetaData(String group, String remote){try{return STORAGE_CLIENT.get_metadata(group, remote);}catch (Exception e){e.printStackTrace();return null;}}/*** 下载文件工具方法* 下载方法* byte[] download_file(String 卷名, String 路径及文件名)* 返回要下载的文件内容* @param group 卷名* @param remote 路径及文件名* @return 返回下载的文件内容,发生错误返回null*/public static byte[] download(String group, String remote){try {return STORAGE_CLIENT.download_file(group, remote);}catch (Exception e){e.printStackTrace();return null;}}/*** 上传文件的工具方法* 一定保存文件到FastDFS,一定保存至少一个元数据(文件原始名称)* @param inputStream 要上传的文件的输入流* @param fileName 上传文件的原始名称* @param metaProperties 上传文件的元数据,成对提供,如: 名,值,名,值* @return*/public static String[] uploadFile(InputStream inputStream, String fileName, String... metaProperties){try {int length = inputStream.available();byte[] datas = new byte[length];inputStream.read(datas, 0, length);// 处理元数据NameValuePair[] nameValuePairs = null;if (metaProperties.length % 2 == 0) {// 参数数量满足要求,开始处理nameValuePairs = new NameValuePair[metaProperties.length / 2 + 1];for (int i = 0; i < nameValuePairs.length; i = i + 2) {nameValuePairs[i / 2] = new NameValuePair(metaProperties[i], metaProperties[i + 1]);}} else {nameValuePairs = new NameValuePair[1];}nameValuePairs[nameValuePairs.length - 1] = new NameValuePair("fileName", fileName);// 获取文件后缀String extName = getExtName(fileName);// 上传文件到FastDFSString[] result = STORAGE_CLIENT.upload_file(datas, extName, nameValuePairs);for (String s : result) {System.out.println("s = " + s);//s = group1//s = M00/00/00/wKjegGbqfoKACfLIAAAnJ2OoZs8411.txt}System.out.println("============= " + nameValuePairs[0]+ "/n"+ nameValuePairs[1]);//============= org.csource.common.NameValuePair@4ae28001/norg.csource.common.NameValuePair@3e472f5dreturn result;}catch (Exception e){// 发生任何异常,上传文件失败。返回nulle.printStackTrace();return null;}}/*** 截取文件后缀* @param fileName* @return*/private static String getExtName(String fileName){if(fileName.lastIndexOf(".") > -1){// 文件名称中包含字符 .return fileName.substring(fileName.lastIndexOf(".") + 1);}else{// 文件名称中不包含字符 .return "";}}/*** 提供获取Storage客户端对象的工具方法*/public static StorageClient getStorageClient(){return STORAGE_CLIENT;}private FastDFSUtils(){} }
3)编写上传和下载路由
下载路由中需要加上内容类型和响应头,否则可能出现访问下载却出现在线预览图片
@Controller public class LoginController {@RequestMapping("/index")public String uploadPage(){return "index";}@RequestMapping("/upload")public String upload(MultipartFile file, HttpSession session) throws IOException {InputStream inputStream = file.getInputStream();String originalFilename = file.getOriginalFilename();String[] strings = FastDFSUtils.uploadFile(inputStream, originalFilename, "s", "");System.out.println(strings);return "a";}@RequestMapping("/download")public void download(String group,String remote,HttpServletResponse response) throws IOException {byte[] datas = FastDFSUtils.download(group, remote);response.setContentType("application/octet-stream");// 设置下载文件的附件名称NameValuePair[] metaData = FastDFSUtils.getMetaData(group, remote);String fileName = "";for (NameValuePair metaDatum : metaData) {if ("fileName".equals(metaDatum.getName()))fileName = metaDatum.getValue();}response.setHeader("content-disposition","attachment;filename="+fileName.toString());// 输出要下载的文件内容到客户端 // byte[] datas = (byte[]) result.get("datas");response.getOutputStream().write(datas, 0, datas.length);response.getOutputStream().flush();}}
4)上传一张图片,在浏览器中访问图片
这里的端口号为8888,fastdfs中内置有nginx服务器,请求从nginx服务器转发到storage服务器.
二、RabbitMQ
publisher项目使用RabbitMQ软件将消息推送至交换机,交换机根据路由键将消息推送至相应队列中。Consumer项目中的监听器时刻监听提前设置好的监听队列,如果有消息进入队列中,会调用单元方法将消息中的数据取出消费,消费成功后返回信息在队列中删除消息
如果消息在Consumer项目中拿取数据或者消费过程中出现错误,这个时候不会被删除,而是会多次尝试再次获取 消息 消费。达到一定次数,停止尝试。
多个消费者同时监听一个消息队列时,采用轮循策略依次发送消息。
1)虚拟机使用docker安装RabbitMQ
0、docker命令:
docker pull rabbitmq:managementdocker run -d --name rabbitmq -p 15672:15672 -p 5672:5672 --restart=always -e DEFAULT_USER=wollo -e DEFAULT_PASS=wollo rabbitmq:management①、 访问 http:192.168.222.128:15672: //Docker宿主机IP:15672
这个是RabbitMQ提供的可视化界面,类似于Navicat。
②、使用可视化界面操作RabbitMQ:
创建交换机、创建队列、将交换机和队列绑定并设置路由键
2)使用java代码连接操作RabbitMQ
1.新建一个父工程统一管理springBoot的版本号
打包方式为 pom
2.新建子工程publisher、consumer 及依赖配置
两个子工程都添加springAMQP依赖。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
publisher配置文件:
#配置RabbitMq的链接参数 spring:rabbitmq:host: 192.168.222.128 # RabbitMQ服务器的IP。默认localhostport: 5672 # RabbitMQ服务器的端口。username: wollo # RabbitMQ的访问用户名。默认guest。password: wollo # RabbitMQ的访问密码。默认guestvirtual-host: / # 连接RabbitMQ中的哪一个虚拟主机。默认 /publisher-confirm-type: correlated # 开启到达交换器确认机制。默认值:none,不开启确认机制。publisher-returns: true # 开启到达消息队列确认机制。默认值:none,不开启确认机制。
consumer:
#配置RabbitMq的链接参数 spring:rabbitmq:host: 192.168.222.128 # RabbitMQ服务器的IP。默认localhostport: 5672 # RabbitMQ服务器的端口。username: wollo # RabbitMQ的访问用户名。默认guest。password: wollo # RabbitMQ的访问密码。默认guestvirtual-host: / # 连接RabbitMQ中的哪一个虚拟主机。默认 /listener:simple:retry:enabled: true # 开启重试机制max-attempts: 3 # 重试消费1次
2.1)第一次使用Publisher发送消息,Consumer消费消息
1.前面在可视化界面中已经配置了交换机,绑定的消息队列,路由键
交换机 rk.direct
消息队列 rk.queue
路由键 route.regex
2.在publisher发送消息运行test()方法 ,别忘了编写启动类文件

3.在Consumer中接收消息,需要指定接收的消息队列,同样别忘了编写启动类

4.在运行的Consumer项目控制台中会打印"皇室"。
2.2)发送和接收一个序列化对象User
1.新建commen子模块,publisher和consumer引入该模块
commen子模块新建User类,实现Serializable接口
2.可视化界面新建交换机rk.direct1 , 消息队列rk.queue1 ,发送user对象:
publisher的测试类:

consumer的消息队列:

consumer项目控制台:

2.3)其他类型交换器 基于注解创建交换机、消息队列
1.交换机类型有四种:
direct为完全匹配路由键
fanout为广播
topic为模糊匹配
2.这里创建一个广播类型的交换机
key值任意写,因为广播针对绑定的所有消息队列。
@Component public class FanoutConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "fanout.queue",durable = "true",autoDelete="false"),exchange = @Exchange(name = "rk.fanout",type = "fanout",durable = "true",autoDelete = "false"),key = {"route.regex"})})public void OnMessage(String messageBody){System.out.println("messageBody = " + messageBody);}}
3.topic交换机
@Component public class MyTopicConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.1", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.同学"})})public void onMessage1(String message){System.out.println("小学.同学 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.2", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.老师"})})public void onMessage2(String message){System.out.println("小学.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.3", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.*"})})public void onMessage3(String message){System.out.println("小学.* - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.4", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"大学.老师"})})public void onMessage4(String message){System.out.println("大学.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.5", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"*.老师"})})public void onMessage5(String message){System.out.println("*.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.6", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"#"})})public void onMessage6(String message){System.out.println("# - " + message);}}
2.4)消息传递失败的处理方法
①publisher推送的消息失败的回调方法
1. 开启回调方法的确认机制。
2.实现回调接口
@Component
public class PublisherHandle implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback{@Autowiredprivate RabbitTemplate rabbitTemplate;@PostConstructpublic void init(){this.rabbitTemplate.setConfirmCallback(this);this.rabbitTemplate.setReturnsCallback(this);}@Overridepublic void confirm(CorrelationData correlationData, boolean b, String s) {System.out.println("到达交换机:"+b);}/*** @description:* System.out.println( 交换器 : returnedMessage.getExchange ());* System.out.println("路由键 : " + returnedMessage.getRoutingKey());* System.out.println("路由失败编码 : " + returnedMessage.getReplyCode());* System.out.println("路由失败描述 : " + returnedMessage.getReplyText());* System.out.println("消息 : " + returnedMessage.getMessage());* @author:rk* @date: 2024/9/24 10:47* @param: returnedMessage**/@Overridepublic void returnedMessage(ReturnedMessage returnedMessage) {System.out.println("到达消息队列:"+returnedMessage.getReplyCode());}
}
②consumer
配置中设置重试次数、或者开启手工ACK方式解决消息处理失败问题

2.5)手动发送确认ACK
1.配置开启手工确认
2. 创建交换机、消息队列并设置手工ACK
@Component
public class MyAckConsumer {//测试消费的ACK:@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "ack.queue"),exchange = @Exchange(name = "ack.direct"),key = {"ack.routing"})})public void testAckMessage(String message, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG)Long deliveryTag) throws Exception {System.out.println("消息消费:"+message+"---"+deliveryTag);//主动通知RabbitMq消息被正确消费,RabbitMq会将消息从队列中移除//channel.basicAck(deliveryTag, false);//主动通知RabbitMq消息没有被正确消费(消息的ID,消费结果,是否重试消费false表示删除消息true表示重复消费)//channel.basicNack(deliveryTag,false,true);//主动通知RabbitMq消息没有消费,直接丢弃(消息的ID,false表示删除消息true表示尝试重复消费),丢失一般是在消息消费的代码之前channel.basicReject(deliveryTag, false);}
}
2.6)同步消息处理
1.配置同步时长

2.消费者代码
@Component
public class SynchronizationMessageConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "return.queue"),exchange = @Exchange(name = "return.direct"),key = {"return.routing"})})public String testAckMessage(String message , Channel channel, @Header(AmqpHeaders.DELIVERY_TAG)Long deliveryTag) throws Exception {System.out.println("消息的消费内容为:"+message);return "今天天气不错,适合学习";}
}
3.推送者代码:

4.测试

相关文章:
文件服务器FastDFS 消息队列中间件RabbitMQ
新标签页 (chinaunix.net) FastDFS - Browse Files at SourceForge.net 一、FastDFS Tracker和Storage: tracker用来管理所有的storage,只是管理服务器,负责负载均衡。 storage是存储服务器,每一个storage服务器都是一个单独的个…...
工作纪实58-Idea打jar包
有时候需要配合算法使用spark定时DP,调用java相关的jar包做数据处理 idea打jar包有以下三种场景 SpringBoot的Maven项目【Maven打包即可】非SpringBoot的Maven项目【添加maven打包参数,使用Maven打包】 借助maven的配置进行打包,新增以下配置…...
ELK-03-skywalking监控linux系统
文章目录 前言一、下载node_exporter二、启动node_exporter三、下载OpenTelemetry Collector四、启动OpenTelemetry Collector4.1 将配置文件下载到同级目录4.2 启动 五、查看总结 前言 skywalking安装完成后,开始我们的第一个监控-监控linux系统。 参考官方文档&a…...
HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13
HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13...
开源图像降噪算法与项目介绍【持续更新】
Intel Open Image Denoise 介绍:Intel Open Image Denoise(OIDN)是一个开源库,它提供了一系列高性能、高质量的去噪滤镜,专门用于光线追踪渲染的图像。这个库是Intel Rendering Toolkit的一部分,并且是在宽…...
RealSense、ZED 和奥比中光Astra几款主流相机介绍及应用
以下是英特尔 RealSense、Stereolabs ZED 和奥比中光Astra几款相机的详细对比,包括参数、性能以及二次开发等支持,附带代码示例。 详细信息对比和二次开发示例 1. 英特尔 RealSense (例如 D435/D455) 深度技术:立体视觉 红外投影分辨率&a…...
启动 Ntopng 服务前需先启动 redis 服务及 Ntopng 常用参数介绍
启动Ntopng服务之前需要先启动redis服务,因为Ntopng服务依赖于redis服务的键值存储。 服务重启 服务启动 Ntopng常用参数: -d 将 Ntopng 进程放入后台执行。默认情况下,Ntop 在前台运行。 -u 指定启动Ntopng执行的用户,默认为…...
vector的模拟实现以及oj题(2)
前言 上篇博客介绍了大部分vector的接口,其中包括begin()、end()、const begin()、 const end()、size、capacity、reserve、empty、push_back、pop_back、insert、operator[],这篇博客将介绍剩下的部分接口,以及一些oj题解法和思路。 vect…...
数据技术进化史:从数据仓库到数据中台再到数据飞轮的旅程
随着大数据时代的到来,数据已经成为企业的核心资产之一。在过去几十年间,数据技术也随之不断演进,从早期的数据仓库到近年来热门的数据中台,再到正在快速发展的数据飞轮概念,每一步都是技术革新的体现。 一、数据仓库&…...
JAVA JDK华为云镜像下载,速度很快
直达下载地址 https://repo.huaweicloud.com/java/jdk/ https://repo.huaweicloud.com/java/jdk/欢迎各位收藏享用!!!...
【RKNN系列】官方函数:querystring
querystring 函数 功能 查询获取当前芯片平台RGA硬件版本与功能支持信息,以字符串的形式返回。 语法 std::string querystring(int query_type);参数 query_type: 要查询的 RGA 信息类型(整数) 描述 这个函数用于获取特定类型的 RGA 信…...
Stable Diffusion零基础学习
Stable Diffusion学习笔记TOP14 _插件篇之ControlNet功能篇 ControlNet目前支持的10多种预处理器,根据数据检测种类可分为两种类型: 1、功能型:拥有着不同的能力 2、构图型:控制着SD扩散图形的构图规则 部分未编写预处理器的功…...
C#基于SkiaSharp实现印章管理(9)
将印章设计模块设计的印章保存为图片并集中存放在指定文件夹内。新建印章应用项目,主要实现对图片及PDF文件加盖印章功能。本文实现给图片加盖印章功能。 给图片加盖印章的逻辑比较简单,就是将印章图片绘制到图片指定位置,使用SKControl控…...
研究生如何利用ChatGPT帮助开展日常科研工作?
小白可做!全自动AI影视解说一键成片剪辑工具https://docs.qq.com/doc/DYnl6d0FLdHp0V2ll 作为当代研究生,科研工作三部曲----读文献、开组会、数据分析。无论哪一个,都令研究生们倍感头疼,简直就是梦魇。每当看到导师发来的消息&a…...
汽车零部件开发流程关键阶段
目录 1、定点阶段 1.1、定点前的准备工作 1.2、定点决策过程 1.3、定点后的工作交接 2、A样阶段:设计验证与基本功能实现 2.1、样件制作:从设计图纸到实物转化 2.2、功能测试:初步验证与性能评估 2.3、评估与优化:A样阶段…...
Magnific推V2图像生成服务 可直出4K图像
人工智能 - Ai工具集 - 集合全球ai人工智能软件的工具箱网站 近日,AI图像处理领域再迎重大突破,Magnific推出的V2图像生成服务引领行业潮流。此次升级,不仅使Magnific从高端软件跻身为顶级AI图像生成器,更彰显了其在技术创新及用…...
E9OA解决文档附件没有关联文档正文问题
业务背景: OA通知流程已经提交后在审批中发现漏上传了文档附件。临时放开审批结点文档附件编辑,请审批结点领导将附件上传后再审批。最终在流程中查看可以看到正文和附件,但是在通知文档正文中没有关联文档附件,导致大多数人员在通…...
EasyExcel日常使用总结
文章目录 概要引入依赖常用操作方法折叠或隐藏列折叠或隐藏行单元格样式单行表头设置多行表头设置多个sheet写入自动列宽 概要 EasyExcel日常使用总结。 引入依赖 引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</a…...
人只活一次,活出一道光吧
人只活一次, 你怎么舍得让自己的短暂的一生是丑陋的, 你怎么舍得让自己短暂的一生, 只是在往下坠落, 即便是坠落, 也应该具有落日般的华丽吧, 你会漫漫的活成一束光, 谁若接近你, 就是接近光, 【人人都想向上,人人都想老而不衰,但现实是当你想活成一道光…...
sqli-labs:1~16(sql注入点稳定判断语句、全回显半回显报错回显无回显利用思路、sql注入tips)
怎么验证sql注入的存在呢? 首先,双引号单引号注入,看看有没有报错,或者与正常参数的区别,有报错说明大概率可以注入成功,但是,很可能单引号和双引号测试可能没有报错回显,或者与正常…...
Julia语言深度解析:高性能科学计算与机器学习实战指南
1. Julia语言:是技术革命还是营销泡沫? 最近几年,技术圈里关于Julia的讨论热度一直没降下来过。每次有朋友问我“该不该学Julia”或者“Julia是不是要取代Python了”,我都得先让他们冷静一下,然后从我的实际体验出发&…...
AI智能体配置管理实战:基于agent-config-manager的解决方案
1. 项目概述与核心价值最近在折腾一个多智能体协作的项目,发现配置文件的管理简直是个灾难。每个智能体(Agent)都有自己的一堆参数:API密钥、模型选择、系统提示词、温度值、最大token数……更别提不同环境(开发、测试…...
Crypto AI Agent:基于LangChain与Web3的加密交易智能体实战
1. 项目概述:当AI智能体闯入加密世界最近在GitHub上看到一个挺有意思的项目,叫“Crypto-AI-Agent”。光看名字,你大概就能猜到它想干什么——让AI来玩转加密货币。这可不是简单的价格查询机器人,从项目描述和代码结构来看…...
从AwesomeCursorPrompt看提示工程:如何设计高效AI编程指令
1. 项目概述:从“AwesomeCursorPrompt”看提示工程的工程化实践最近在折腾AI编程助手,特别是Cursor这个工具,发现一个挺有意思的现象:很多人觉得它“不够聪明”,或者用起来效果时好时坏。其实,这背后往往不…...
Allegro PCB设计避坑:用Shape Keepout巧妙隔离大小电流GND(附16.6实操步骤)
Allegro PCB设计中的地平面隔离艺术:用Shape Keepout实现电流路径优化 在高速PCB设计中,地平面的处理往往决定着整个系统的成败。当大电流地与小信号地不得不共享同一网络名称时,如何在不违反设计规则的前提下实现物理隔离?这个问…...
5分钟掌握OBS虚拟摄像头:让所有视频软件都能用上专业直播效果
5分钟掌握OBS虚拟摄像头:让所有视频软件都能用上专业直播效果 【免费下载链接】obs-virtual-cam 项目地址: https://gitcode.com/gh_mirrors/obs/obs-virtual-cam 你是否曾经羡慕主播们精美的直播画面,却苦于无法在Zoom、Teams等日常软件中实现同…...
Windows极速ADB驱动一键安装:告别繁琐配置的终极指南
Windows极速ADB驱动一键安装:告别繁琐配置的终极指南 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirrors/la/Lat…...
解锁B站高清与会员视频:基于you-get与EditThisCookie的自动化下载方案
1. 为什么需要you-get与EditThisCookie组合方案 每次在B站看到喜欢的视频想保存下来,你是不是也遇到过这样的烦恼?用普通下载工具要么画质模糊得像打了马赛克,要么遇到会员专属内容直接提示"无权限"。作为常年混迹技术社区的老司机…...
别再死记硬背排序了!‘原地哈希’如何用交换搞定特定数组排序(保姆级图解)
别再死记硬背排序了!‘原地哈希’如何用交换搞定特定数组排序(保姆级图解) 每次提到排序算法,你的第一反应是不是快速排序、归并排序这些经典方法?但面对特定场景的数组排序,这些"大炮打蚊子"式的…...
从硬盘分区到系统重装:一套完整的CSGO机器码解封操作流程(附磁盘精灵使用指南)
从硬盘分区到系统重装:CSGO设备标识重置全流程实战指南 当游戏设备标识遭遇封禁时,单纯修改表层参数往往难以彻底解决问题。本文将系统性地介绍一套从底层存储结构到操作系统环境的完整重置方案,帮助玩家重建全新的硬件身份标识。不同于简单的…...
















