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

java怎么找bug?Arthas原理与实战指南

Arthas原理与实战指南

1. Arthas简介

Arthas是阿里巴巴开源的Java诊断工具,其名字取自《魔兽世界》的人物阿尔萨斯。它面向线上问题定位,被广泛应用于性能分析、定位问题、安全审计等场景。Arthas的核心价值在于它能够在不修改应用代码、不重启Java进程的情况下,实时动态地监控和分析运行中的Java程序。

Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的Tab自动补全功能。

2. 核心原理深度解析

2.1 Java Agent技术

Arthas基于Java Agent技术,Java Agent是JDK 1.5引入的一种能够在不修改Java源代码的情况下,动态修改Java字节码的技术。

Java Agent通过以下两种方式工作:

  • 静态加载:通过JVM启动参数-javaagent指定
  • 动态加载:通过Attach API动态附加到运行中的JVM

Arthas采用了动态加载的方式,使其能够在Java应用运行过程中被加载。

Arthas工作原理
Java Agent
Instrumentation API
premain方法/agentmain方法
类字节码转换
JVM Attach机制
VirtualMachine.attach
loadAgent方法
字节码操作
ASM库
动态代理
命令处理框架
命令解析
命令执行
结果输出

2.2 Instrumentation API

Java的java.lang.instrument包提供了一套API,允许Java Agent程序修改已加载的类的字节码。Arthas利用这一API来实现类和方法的监控和分析。

关键接口和类:

  • Instrumentation:提供注册类文件转换器、获取所有已加载类等功能
  • ClassFileTransformer:类文件转换器,用于修改类的字节码
  • Agent:Agent程序的入口点,通过premainagentmain方法启动

2.3 JVM Attach机制

Attach机制允许一个JVM进程连接到另一个JVM进程,实现进程间通信。Arthas使用该机制动态加载Agent到目标JVM中。

核心实现在com.sun.tools.attach包中,关键类有:

  • VirtualMachine:代表一个JVM进程
  • VirtualMachineDescriptor:JVM进程的描述信息

2.4 ASM字节码操作

Arthas使用ASM库操作Java字节码,通过修改字节码来实现方法拦截、监控等功能。ASM是一个轻量级的字节码操作框架,能够动态生成和修改Java字节码。

字节码转换过程:

  1. 读取原始类字节码
  2. 使用ASM分析字节码结构
  3. 修改字节码(如添加方法入口/出口的监控代码)
  4. 返回修改后的字节码

2.5 命令处理引擎

Arthas采用命令行交互方式,内部实现了一套完整的命令处理引擎:

  • 命令解析:将用户输入解析为命令对象
  • 命令执行:根据命令执行相应操作
  • 结果渲染:将执行结果格式化输出

3. 安装与启动详解

3.1 安装方式

方式一:使用arthas-boot(推荐)

# 下载启动脚本
curl -O https://arthas.aliyun.com/arthas-boot.jar# 启动
java -jar arthas-boot.jar

方式二:使用全量包

# 下载全量包
curl -O https://arthas.aliyun.com/arthas-packaging.jar# 解压
java -jar arthas-packaging.jar# 启动
cd arthas
./arthas.sh

方式三:使用as.sh

# 下载并安装
curl -L https://arthas.aliyun.com/install.sh | sh# 启动
./as.sh

3.2 启动选项详解

启动Arthas时,可以指定多种参数:

# 指定目标Java进程
java -jar arthas-boot.jar [PID]# 指定目标进程名称的关键字
java -jar arthas-boot.jar --select JAVA_HOME# 启动时禁用某些命令
java -jar arthas-boot.jar --exclude-commands=jvm,thread# 指定端口号
java -jar arthas-boot.jar --telnet-port 9998 --http-port 9999# 以批处理模式执行命令
java -jar arthas-boot.jar --command "thread" -c "thread" > output.txt

3.3 连接方式

Arthas提供多种连接方式:

  1. 本地命令行模式
    直接在启动终端操作

  2. Telnet连接

    telnet 127.0.0.1 3658
    
  3. WebSocket连接
    通过浏览器访问http://127.0.0.1:8563/

  4. HTTP API

    curl http://127.0.0.1:8563/api
    

4. 核心功能与命令详解

4.1 JVM相关命令

dashboard - 系统实时数据面板

提供系统整体情况的实时数据,包括线程、内存、GC、运行环境等信息。

# 每5秒刷新一次
dashboard -i 5000# 只显示前10个线程
dashboard -n 10

输出示例:

ID     NAME                   GROUP                  PRIORITY  STATE    %CPU     DELTA_TIME TIME     INTERRUPTED DAEMON
17     pool-2-thread-1        main                   5         RUNNABLE 27       0.136      0:0.203  false       false
21     pool-2-thread-5        main                   5         RUNNABLE 26       0.132      0:0.096  false       false
22     pool-2-thread-6        main                   5         RUNNABLE 26       0.132      0:0.097  false       false
......Memory                    used    total    max      usage    GC
heap                      32M     155M     1820M    1.76%    gc.ps_scavenge.count              118
ps_eden_space             14M     65M      672M     2.21%    gc.ps_scavenge.time(ms)           1890
ps_survivor_space         4M      5M       5M       81.92%   gc.ps_marksweep.count             5
ps_old_gen                12M     85M      1365M    0.91%    gc.ps_marksweep.time(ms)          1140
jvm - JVM信息
# 显示JVM信息
jvm# 同时显示ClassLoader信息
jvm -c

输出包含:

  • Java运行时版本与厂商
  • JVM参数
  • 类加载统计
  • JVM内存区域使用情况
  • 垃圾收集器信息
  • 操作系统和硬件信息
thread - 线程分析
# 显示所有线程
thread# 查看指定线程的栈信息
thread 1# 查看最忙的前3个线程栈
thread -n 3# 查看阻塞其他线程的线程
thread -b# 查找指定状态的线程
thread --state BLOCKED# 线程池信息
thread -i

线程池参数解析:

- corePoolSize: 核心线程数
- maximumPoolSize: 最大线程数
- keepAliveTime: 线程存活时间
- queueCapacity: 队列容量
- taskCount: 已执行和未执行的任务总数
- completedTaskCount: 已完成的任务数
- largestPoolSize: 历史最大线程数
- poolSize: 当前线程数
- activeCount: 当前活动线程数
sysprop - 系统属性
# 查看所有系统属性
sysprop# 查看指定属性
sysprop java.version# 设置系统属性
sysprop user.country US
heapdump - 堆转储
# 生成堆转储文件到指定路径
heapdump /tmp/dump.hprof# 只转储活着的对象
heapdump --live /tmp/dump.hprof

4.2 类相关命令

sc - 查找类
# 模糊查找类
sc *List*# 查找指定类的详细信息
sc -d java.util.ArrayList# 查找类的方法信息
sc -d -f java.util.ArrayList# 显示类加载器信息
sc -c -d java.util.ArrayList# 指定类加载器查找
sc -c classLoaderHash *MathGame*
sm - 查找方法
# 查找类的所有方法
sm java.util.ArrayList# 查找方法的详细信息
sm -d java.util.ArrayList add# 正则匹配方法
sm java.util.ArrayList "add|remove"
jad - 反编译
# 反编译指定类
jad com.example.demo.arthas.user.UserController# 指定反编译结果输出路径
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java# 只反编译指定的方法
jad com.example.demo.arthas.user.UserController getUserById
mc - 内存编译
# 编译指定Java文件
mc /tmp/UserController.java# 指定输出目录
mc -d /tmp/output /tmp/UserController.java# 指定ClassLoader编译
mc -c 5a54a66 /tmp/UserController.java
redefine - 热加载
# 重新加载类
redefine /tmp/output/com/example/demo/arthas/user/UserController.class# 指定ClassLoader
redefine -c 5a54a66 /tmp/output/com/example/demo/arthas/user/UserController.class# 批量重新加载
redefine -p /tmp/output/

4.3 方法相关命令

monitor - 方法监控
# 监控方法执行情况
monitor -c 5 com.example.demo.arthas.user.UserController * # 匹配正则表达式方法 
monitor -c 5 com.example.demo.arthas.user.UserController get*# 监控异常统计
monitor -e -c 5 com.example.demo.arthas.user.UserController *# 监控匹配的构造函数
monitor -c 5 com.example.demo.arthas.user.UserController <init>

监控指标说明:

- timestamp: 时间戳
- class: 类名
- method: 方法名
- total: 调用次数
- success: 成功次数
- fail: 失败次数
- rt: 平均响应时间(ms)
- fail-rate: 失败率
watch - 方法观察
# 观察方法的入参和返回值
watch com.example.demo.arthas.user.UserController getUserById '{params, returnObj}' -x 3# 观察异常信息
watch com.example.demo.arthas.user.UserController getUserById '{params, throwExp}' -e -x 2# 观察入参和返回值,并按照条件过滤
watch com.example.demo.arthas.user.UserController getUserById '{params, returnObj}' 'params[0] > 100' -x 3# 观察入参和返回值,限制次数
watch com.example.demo.arthas.user.UserController getUserById '{params, returnObj}' '#cost > 10' -n 3# 按表达式过滤,只有耗时大于10ms的才会输出
watch com.example.demo.arthas.user.UserController getUserById '{params, returnObj, #cost}' '#cost > 10' -n 3 -x 3

watch支持的表达式工具类:

  • params:参数列表
  • returnObj:返回值
  • throwExp:抛出的异常
  • target:当前对象实例
  • clazz:当前类
  • method:当前方法
  • #cost:执行耗时
trace - 方法调用链分析
# 跟踪方法执行的调用链
trace com.example.demo.arthas.user.UserController getUserById# 指定最大展开层级
trace -j 2 com.example.demo.arthas.user.UserController getUserById# 按调用耗时过滤
trace com.example.demo.arthas.user.UserController getUserById '#cost > 10'# 只跟踪本地方法
trace --skipJDKMethod false com.example.demo.arthas.user.UserController getUserById

输出示例:

`---ts=2018-12-04 18:11:45;thread_name=http-nio-8080-exec-5;id=31;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@6bc168e5`---[10.127743ms] com.example.demo.arthas.user.UserController:getUserById()+---[0.060919ms] com.example.demo.arthas.user.UserController:getUserById:before()`---[9.732368ms] com.example.demo.arthas.user.UserRepository:findById()`---[9.499895ms] org.hibernate.jpa.internal.EntityManagerImpl:find()`---[9.187044ms] org.hibernate.jpa.internal.EntityManagerImpl:find()
stack - 调用栈跟踪
# 查看调用来源
stack com.example.demo.arthas.user.UserController getUserById# 条件表达式过滤
stack com.example.demo.arthas.user.UserRepository findById 'params[0]==1'# 指定采样次数
stack -n 5 com.example.demo.arthas.user.UserController getUserById
tt - 方法执行时空隧道

tt命令记录方法执行的详细信息,支持回放。

# 记录方法执行过程
tt -t com.example.demo.arthas.user.UserController getUserById# 查看记录的调用信息
tt -l# 查看记录的详细信息
tt -i 1000# 重新执行一次调用
tt -i 1000 -p# 指定方法入参重新执行
tt -i 1000 -p '{params[0] = 2}'# 条件过滤
tt -t com.example.demo.arthas.user.UserController getUserById 'params[0]==1'

4.4 增强功能

profiler - 性能剖析
# 查看profiler支持的事件
profiler list# 开始采样,按CPU采样
profiler start# 指定采样事件
profiler start --event alloc# 指定文件输出格式(支持svg、html、jfr等)
profiler start --format html# 采样一段时间后停止
profiler stop# 将结果保存到指定文件
profiler stop --file /tmp/result.html# 支持火焰图
profiler start --event cpu --format svg
profiler stop --file /tmp/cpu.svg
vmtool - JVM工具
# 获取对象
vmtool --action getInstances --className java.lang.String --limit 10# 查看对象信息
vmtool --action getInstances --className com.example.demo.arthas.user.User --express 'instances[0].username'# 强制GC
vmtool --action forceGc
ognl - 执行OGNL表达式
# 获取静态字段
ognl '@com.example.demo.arthas.user.UserService@INSTANCE'# 调用静态方法
ognl '@java.lang.System@currentTimeMillis()'# 获取变量值
ognl '#user=@com.example.demo.arthas.user.UserController@userService.findById(1), #user.username'# 调用对象方法
ognl '#user=@com.example.demo.arthas.user.UserController@userService.findById(1), #user.setUsername("arthas"), #user'

5. 实战案例详解

5.1 CPU使用率过高问题分析

当应用CPU使用率异常升高时,使用Arthas可以快速定位问题:

用户 Arthas JVM 1. 执行dashboard命令观察系统情况 获取线程和CPU信息 返回高CPU线程信息 2. 执行thread -n 3命令查看最繁忙线程 获取繁忙线程栈 返回线程栈信息 3. 执行thread [threadId]查看具体线程栈 获取指定线程详细信息 返回线程详细信息 4. 执行trace命令跟踪热点方法 开始方法调用链跟踪 返回方法调用耗时 5. 执行profiler命令进行性能剖析 开始CPU采样 返回CPU采样结果 用户 Arthas JVM

实战步骤

  1. 首先执行dashboard查看系统整体情况:

    dashboard -n 10
    
  2. 发现有线程CPU使用率很高,执行thread命令查看线程状态:

    # 查看占用CPU最高的3个线程
    thread -n 3
    
  3. 定位到问题线程,查看其栈信息:

    thread 16234
    
  4. 发现可疑方法,使用trace跟踪执行链路:

    trace com.example.service.OrderService calculatePrice '#cost > 200'
    
  5. 使用profiler进行火焰图分析:

    profiler start --event cpu
    # 等待30秒
    profiler stop --format svg --file /tmp/cpu.svg
    

5.2 内存泄漏分析

持续上升
偶发暴涨
内存泄漏问题
观察JVM内存趋势
使用dashboard命令
使用heapdump导出堆内存
使用MAT分析堆转储文件
使用watch观察可疑方法
使用vmtool查看对象实例
定位问题对象

实战步骤

  1. 首先执行dashboardmemory观察内存使用情况:

    # 观察内存趋势
    dashboard -i 5000# 查看详细内存信息
    memory
    
  2. 发现Old区内存持续增长,使用heapdump导出堆内存:

    heapdump --live /tmp/heap.hprof
    
  3. 使用MAT分析堆转储文件(离线分析)

  4. 根据MAT分析结果,定位到可疑类,使用vmtool查看实例:

    vmtool --action getInstances --className com.example.cache.UserCache --limit 10
    
  5. 使用ognl查看对象详情:

    ognl '#cache=@com.example.cache.UserCache@INSTANCE, #cache.cacheMap.size()'
    
  6. 使用watch监控可疑方法:

    watch com.example.cache.UserCache put '{params, target.cacheMap.size()}' -x 3
    

5.3 线上修复Bug

发现线上Bug
使用jad反编译
修改代码
使用mc编译
使用redefine热加载
验证问题是否修复

实战步骤

  1. 首先定位到问题代码,使用jad反编译:

    jad --source-only com.example.service.OrderService > /tmp/OrderService.java
    
  2. 修改源代码,修复Bug:

    vim /tmp/OrderService.java
    
  3. 使用mc编译修改后的代码:

    mc -d /tmp/classes /tmp/OrderService.java
    
  4. 使用redefine热加载修改后的类:

    redefine /tmp/classes/com/example/service/OrderService.class
    
  5. 使用watch验证修复效果:

    watch com.example.service.OrderService calculatePrice '{params, returnObj}' -x 3
    

5.4 定位接口超时问题

用户 Arthas JVM 执行trace命令跟踪接口调用链 开始调用链跟踪 返回方法调用耗时 找到耗时长的方法,使用stack查看调用来源 获取方法调用栈 返回调用栈信息 使用watch命令观察方法执行 监控方法执行 返回方法入参和执行结果 使用tt命令记录执行历史 记录方法调用 保存调用记录 用户 Arthas JVM

实战步骤

  1. 首先用trace跟踪超时接口:

    trace com.example.controller.ApiController handleRequest '#cost > 1000'
    
  2. 发现有方法特别耗时,使用stack查看其调用来源:

    stack com.example.service.RemoteService requestData
    
  3. 使用watch观察方法的入参和返回值:

    watch com.example.service.RemoteService requestData '{params, returnObj, #cost}' -x 3
    
  4. 使用tt记录多次调用,分析变化趋势:

    tt -t com.example.service.RemoteService requestData
    
  5. 回放某次执行,调试分析:

    tt -i 1000 -p
    

6. 高级应用场景

6.1 Spring Boot应用诊断

诊断Spring应用的常用命令组合:

# 查找所有Controller
sc -d *Controller# 查看一个Bean的详细信息
ognl '#context=@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(#request.getServletContext()), #context.getBean("userService")'# 查找所有RequestMapping
ognl '#springContext=@org.springframework.web.context.ContextLoader@getCurrentWebApplicationContext(), #springContext.getBean("requestMappingHandlerMapping").getHandlerMethods().entrySet()' -x 2

6.2 动态日志调整

运行时调整日志级别是Arthas的强大功能:

# 查看logger信息
logger# 查看指定logger信息
logger -n org.springframework.web# 修改日志级别
logger --name org.springframework.web --level debug# 在方法调用时临时调高日志级别
watch com.example.service.UserService update '{params, returnObj}' -x 3 '#cost>100' 'logger:org.springframework.web:TRACE'

6.3 性能优化

对应用进行性能优化的常用方法:

# 查找热点类和方法
profiler start --event cpu
profiler stop --format html --file /tmp/cpu-profiler.html# 用watch命令观察方法执行次数与耗时
monitor -c 5 com.example.service.* *# 对比优化前后性能变化
tt -t com.example.service.OrderService calculatePrice
# 优化后
tt -t com.example.service.OrderService calculatePrice
tt -l

6.4 多应用实例问题

当有多个同类型应用实例时,如何诊断问题:

# 启动时选择特定实例
java -jar arthas-boot.jar --select "demo-app"# 设置唯一tunnel id
java -jar arthas-boot.jar --tunnel-server "ws://tunnel-server:7777/ws" --agent-id "app1_instance1"# 使用Web Console连接特定实例
http://tunnel-server:8080/arthas-web-console/index.html?agentId=app1_instance1

7. 最佳实践与注意事项

7.1 性能影响控制

Arthas虽然强大,但使用不当会影响线上系统性能:

  1. 避免长时间使用trace/watch等命令

    # 限制采样次数
    trace -n 10 com.example.service.OrderService calculatePrice# 限制命令执行时间
    trace --duration 30 com.example.service.OrderService calculatePrice
    
  2. 使用条件表达式过滤

    # 只监控耗时超过100ms的调用
    trace com.example.service.OrderService calculatePrice '#cost > 100'
    
  3. 合理设置采样间隔

    # 增加采样间隔,降低对系统的影响
    monitor -c 10 -i 5000 com.example.service.OrderService calculatePrice
    

7.2 安全措施

生产环境使用Arthas需注意以下安全事项:

  1. 设置访问认证

    java -jar arthas-boot.jar --username admin --password admin
    
  2. 使用tunnel server模式保证网络安全

    java -jar arthas-boot.jar --tunnel-server 'ws://tunnel-server:7777/ws'
    
  3. 限制命令使用

    java -jar arthas-boot.jar --exclude-commands=jad,mc,redefine
    
  4. 及时退出Arthas会话

    # 使用完后退出
    quit# 完全退出,卸载Agent
    stop
    

7.3 版本兼容性

Arthas的不同版本可能有命令差异,建议:

  1. 总是使用与JDK版本兼容的Arthas版本
  2. 定期更新Arthas到最新版本以获取bug修复和新功能
  3. 在测试环境验证Arthas命令后再在生产环境使用

7.4 与其他工具配合使用

Arthas可以与其他工具结合使用,形成完整的问题诊断体系:

  1. 与MAT配合分析内存问题
  2. 与JMC/JFR结合进行性能分析
  3. 与ELK结合进行日志分析
  4. 与APM工具结合进行全链路追踪

8. 总结

Arthas作为一款强大的Java诊断工具,通过Java Agent技术实现了对JVM运行时的深度观测和操控能力。它的优势在于:

  1. 无侵入性:不需要修改应用代码或重启应用
  2. 实时分析:能够动态获取运行时数据
  3. 功能丰富:从线程分析到字节码操作,覆盖了诊断需求
  4. 易于使用:命令行界面简单直观

掌握Arthas使你在面对复杂的Java生产环境问题时,能够像手术刀一样精准定位并解决问题,真正做到知其所以然。

在实际应用中,建议通过大量实践熟悉各个命令的使用场景和优缺点,形成自己的问题诊断方法论。通过不断实践,你会发现Arthas不仅是一个工具,更是一种解决问题的思路和方法。

相关文章:

java怎么找bug?Arthas原理与实战指南

Arthas原理与实战指南 1. Arthas简介 Arthas是阿里巴巴开源的Java诊断工具&#xff0c;其名字取自《魔兽世界》的人物阿尔萨斯。它面向线上问题定位&#xff0c;被广泛应用于性能分析、定位问题、安全审计等场景。Arthas的核心价值在于它能够在不修改应用代码、不重启Java进程…...

2024年国考

数学 一&#xff0c;逻辑符号表示&#xff08;3 分&#xff09; 1&#xff0c;只有获得奥运会资格的运动员才可以参加奥运会&#xff0c;参加奥运会的云动员不一定获奖。 设&#xff1a; ( Q(x) )&#xff1a;运动员 ( x ) 获得奥运会资格( P(x) )&#xff1a;运动员 ( x )…...

fastlio用mid360录制的bag包离线建图,提示消息类型错误

我用mid360录制的bag包&#xff0c;激光雷达的数据类型是sensor_msgs::PointCloud2&#xff0c;但是运行fast_lio中的mid360 launch文件&#xff0c;会报错&#xff08;没截图&#xff09;&#xff0c;显示无法从livox_ros_driver2::CustomMsg转换到sensor_msgs::PointCloud2。…...

015-C语言字符函数和字符串函数

C语言字符函数和字符串函数 文章目录 C语言字符函数和字符串函数1. 字符分类函数2. 字符转换函数3. strlen4. strcpy5. strcat6. strcmp7. strncpy8. strncat9. strncmp10. strstr11. strtok12. strerror 1. 字符分类函数 C语言中有一系列函数是专门做字符分类的&#xff0c;也…...

docker 搭建nacos 2.2.1版本单机版

通过docker-compose搭建 services:nacos:image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nacos/nacos-server:v2.2.1container_name: nacosenvironment:- PREFER_HOST_MODEhostname- MODEstandalone- NACOS_AUTH_ENABLEtrue- NACOS_AUTH_IDENTITY_KEYxiaogang- N…...

stack,queue和priority_queue

1. stack 1.1 stack 的介绍 栈是一种容器适配器&#xff0c;专门设计用于LIFO环境&#xff08;后进先出&#xff09;&#xff0c;其中元素仅从容器的一端插入和提取。 容器适配器&#xff0c;也就是使用特定容器类的封装对象作为其底层容器&#xff0c;提供一组特定的成员函…...

服务治理-搭建Nacos注册中心

运行nacos.sql文件。 将准备好的nacos目录和nacos.tar包上传。 192.168.59.101是我的虚拟机ip&#xff0c;8848是我们设置的访问端口号。...

《Operating System Concepts》阅读笔记:p738-p747

《Operating System Concepts》学习第 63 天&#xff0c;p738-p747 总结&#xff0c;总计 10 页。 一、技术总结 1.network structure local-area networks (LAN)、wide-area networks (WAN). 2.communication structure naming and name resolution、communication proto…...

【Datawhale AI春训营】Java选手初探数据竞赛

自然语言处理基础&#xff1a; 自然语言处理(Natural Language Processing&#xff0c;NLP) 是计算机科学与人工智能领域中的一个极具挑战性和应用前景的研究方向。 它旨在使计算机能够理解、生成和处理人类的自然语言&#xff0c;从而实现人机高效交互。 NLP技术在搜索引擎、…...

React-useRef

如果我们想在hooks里面获同步取最新的值&#xff0c;那么则可以使用useRef, 关键源码如下&#xff1a; function mountRef<T>(initialValue: T): {|current: T|} {const hook mountWorkInProgressHook();const ref {current: initialValue};hook.memoizedState ref;re…...

得物官网sign签名逆向分析

打开得物官网&#xff0c;点击鞋类&#xff0c;可以看到请求 直接搜sign function p(e) {return f()("".concat(e ? s()(e).sort().reduce(function(t, n) {return "".concat(t).concat(n).concat(e[n])}, "") : "", "048a9…...

网络爬虫和前端相关知识

一 爬虫发展历史,概念与反爬机制 (一)爬虫发展历史 早期爬虫(1990s)起源 :早期的爬虫主要是为了构建搜索引擎。典型案例: Yahoo!人工目录 → 谷歌PageRank算法驱动的自动化爬虫。功能特点 :这些爬虫的功能比较单一,主要以抓取网页的文本内容为主,采用简单的广度优先…...

山东科技大学人工智能原理考试回忆复习资料

全部资料&#xff1a;https://mbd.pub/o/around_01 考试回忆版 简答题 人工智能定义 图灵测试基本思想 人工智能主要研究领域写八个以上 专家系统是什么及其特点 遗传算法流程图 综合题 语义网络表示 书上习题 证明S不满足性 用归结原理求问题 谁说真话假话的 书上例题…...

单元测试的一般步骤

Qt Test Qt Test 是 Qt 开发人员发布的一个单元测试框架&#xff0c;用于测试基于 Qt 框架的应用程序或库。它提供了单元测试框架中常见的所有功能以及用于测试图形用户界面的扩展。 1.自动化测试包络ui测试>接口测试>单元测试&#xff1b;现问如何使用Qt进行单元测试&…...

c++题目_P1443 马的遍历

P1443 马的遍历 # P1443 马的遍历 ## 题目描述 有一个 $n \times m$ 的棋盘&#xff0c;在某个点 $(x, y)$ 上有一个马&#xff0c;要求你计算出马到达棋盘上任意一个点最少要走几步。 ## 输入格式 输入只有一行四个整数&#xff0c;分别为 $n, m, x, y$。 ## 输出格式 …...

并发网路通信-套接字通信

套接字通信就是网络通信 在网络通信时,客户端和服务器的比例是N:1 服务器如何处理多个客户端的请求 并发处理方式 1.多线程并发处理->线程池并发处理,线程池可以对多个线程进行管理 2.多进程->进程池 3.io多路转接,使用select或者epoch进行处理,使用io转接函数…...

STM32N6如何调试下载代码

关键词&#xff1a;STM32N6、调试代码、开发者模式、外部Flash模式 文章目录 前言一、开发者模式调试1.1 CubeIDE调试1.2 IAR调试 二、如何下载代码&#xff08;外部FLASH模式&#xff09;2.1 准备工作2.2 编译下载2.2.1 Appli编译头文件下载2.2.2 FSBL编译头文件下载 2.3 运行…...

【2025】Datawhale AI春训营-蛋白质预测(AI+生命科学)-Task2笔记

【2025】Datawhale AI春训营-蛋白质预测&#xff08;AI生命科学&#xff09;-Task2笔记 本文对Task2使用的代码进行理解。 任务描述 Task2的任务仍然是通过对反应中包含的蛋白质残基信息&#xff0c;运用深度学习模型构建蛋白质3D结构的隐式模型&#xff0c;从而达成准确预测…...

Python基于知识图谱的医疗问答系统【附源码、文档说明】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…...

Unreal 从入门到进阶 之 如何实现Pixel Streaming

文章目录 前言核心概念工作原理主要应用场景Pixel Streaming和Pixel Streaming2部署准备编辑器推流打包推流最后前言 Unreal Engine 5 (UE5) 的 Pixel Streaming 是一项基于云端的实时流媒体技术,允许将 UE5 应用的高质量图形渲染结果通过 WebRTC 协议传输到用户的浏览器或轻…...

作业2 CNN实现手写数字识别

# 导入必要库 import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 用于高级可视化 from tensorflow import keras from tensorflow.keras import layers from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay import time # 用于…...

Linux驱动开发--阻塞、非阻塞I/O

2. 阻塞、非阻塞I/O IO 指的是 Input/Output&#xff0c;也就是输入/输出&#xff0c;是应用程序对驱动设备的输入/输出操作。当应用程序对设备驱动进行操作的时候&#xff0c;如果不能获取到设备资源&#xff0c;那么阻塞式 IO 就会将应用程序对应的线程挂起&#xff0c;直到…...

运筹学之模拟退火

目录 一、历史二、精髓思想三、案例与代码实现 一、历史 问&#xff1a;谁在什么时候提出模拟退火&#xff1f;答&#xff1a;模拟退火算法&#xff08;Simulated Annealing&#xff0c;SA&#xff09;是由斯图尔特柯尔斯基&#xff08;Scott Kirkpatrick&#xff09; 等人在 …...

JavaScript 的演变:2023-2025 年的新特性解析

随着Web技术的飞速发展&#xff0c;ECMAScript&#xff08;简称ES&#xff09;作为JavaScript的语言标准&#xff0c;也在不断进化。 本文将带你学习 ECMAScript 2023-2025 的新特性。 一、ECMAScript 2023 新特性 1.1 数组的扩展 Array.prototype.findLast()/Array.protot…...

CSS继承

CSS继承 CSS继承是一种机制&#xff0c;允许子元素自动继承父元素的某些样式属性&#xff0c;从而减少重复代码。 以下是一些常见的具有继承性的CSS属性&#xff1a; color : 文字颜色 font-family &#xff1a; 字体族名称 font-size &#xff1a; 字体大小 font-weight &am…...

游戏引擎学习第236天:GPU 概念概述

回顾并展望通过视频采集卡进行流媒体传输的未来 昨天&#xff0c;我们迈出了大胆的一步&#xff0c;决定初始化硬件的 3D 加速&#xff0c;因为我有点厌倦了我们的游戏没有垂直同步&#xff08;vsync&#xff09;。如今&#xff0c;在 Windows 上&#xff0c;我找不到一种可靠…...

HFSS3(limy)——建模学习记录

前言——笔者使用的是21版HFSS 1.基本模型 为什么没有环形的天线 2.创建基本模型方法 常用&#xff1a;先粗略建好模型再编辑输入准确坐标和大小尺寸&#xff08;这里长方体起始点是左上角下方的点&#xff0c;也就是说要输入模型起点相对于坐标原点的位置尺寸就可以确定具体…...

php实现zip压缩

可以使用ZipArchive类来创建ZIP压缩文件。ZipArchive是PHP内置的一个类&#xff0c;提供了创建、打开、读取、写入和关闭ZIP文件的功能。 示例&#xff1a;压缩单个文件 <?php$fileToZip path/to/your/file.txt; $zipFileName compressed.zip;$zip new ZipArchive(); …...

【STM32单片机】#10 USART串口通信

主要参考学习资料&#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装&#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…...

goc命令大全

颜色0黑1红2蓝3浅绿4浅蓝5淡黄6棕7深蓝8灰9粉10深绿11紫12蓝绿13黄14橙15白 绘图命令功能pen笔.fd()前进.rt()右转.c()颜色.up()抬笔.o(,)圆.e(,)椭圆.r(,,)长方形.picL(,)调图片.text(,,)文字.hide()隐藏.moveTo(,)移动wait();等待.soundL()调声音pause();暂停 绘图命令功能…...

Linux | 软件仓库管理

一. 软件包 1.1 软件包的分类 DEB&#xff1a;主要用于基于 Debian 的系统&#xff0c;如 Ubuntu。这种软件包格式具有良好的依赖管理机制&#xff0c;方便用户安装、升级和卸载软件。RPM&#xff1a;广泛应用于 Red Hat、CentOS、Fedora 等系统。RPM 包将软件打包成一个文件…...

Python实现对目标Word文档进行自动化排版【4万字精讲】(14)

前言 本文是该专栏的第14篇,后面会持续分享Python办公自动化干货知识,记得关注。 注意:本文涵盖4万字以及实战操作代码的精讲攻略,带你轻松掌握一键式“文档自动化排版”程序功能。 如果说当你在工作项目中,遇到这样的需求,需要如何处理——假设,现在有大批量的docx格…...

LeetCode每日一题4.19

2563. 统计公平数对的数目 题目 问题分析 输入&#xff1a;一个整数数组 nums 和两个整数 lower 和 upper。 输出&#xff1a;返回满足条件的公平数对的数目&#xff0c;即对于所有 0 < i < j < n&#xff0c;lower < nums[i] nums[j] < upper 的数对 (i, j)…...

Spring AI 开发 - 快速入门

先看效果 项目搭建 Spring AI 是 Spring 推出的一个项目&#xff0c;目标是提供统一的API抽象层&#xff0c;屏蔽不同AI模型和服务的底层差异&#xff0c;实现跨平台兼容性。 演示使用的模型是阿里的 qwq-32b。 环境要求&#xff1a; JDK &#xff1a;17以上&#xff08;包括…...

leetcode哈希表(六)-三数相加

题目 15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复…...

Photoshop安装与配置--简单攻略版

下载地址:Photoshop软件工具下载 安装完成后&#xff0c;即可运行Photoshop.exe&#xff1b;打开工具页面后&#xff0c;按照下面简单配置即可 1.编辑-》首选项-》常规 或者直接快捷键CtrlK 暂存盘&#xff1a;一定要设置为非C盘 2.性能 3.文件处理 以上配置比较基础&#xf…...

一个 CTO 的深度思考

今天和一些同事聊了一会&#xff0c;以下是我的观点 我的观点&#xff0c;成年人只能筛选&#xff0c;不能培养在组织中&#xff0c;应该永远向有结果的人看齐。不能当他站出来讲话的时候&#xff0c;大家还要讨论讨论&#xff0c;他虽然拿到结果了&#xff0c;但是他就是有一…...

Java:使用Maven构建项目无src解决方案

创建箭头所指的包和类以及yml文件&#xff1a; 类中&#xff1a; package com.itheima;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class BigEventApplication …...

Git 命令速查手册

听说用美图可以钓读者&#xff1f; 一、基础操作核心命令 1. 仓库初始化与克隆 命令作用示例git init创建新仓库git init my-projectgit clone克隆远程仓库git clone [https://github.com/user/repo.git](https://github.com/user/repo.git)git remote add关联远程仓库git re…...

office软件中word里面的编号库和列表库功能

在Microsoft Word中,编号库和列表库是两大核心排版工具,分别服务于不同层级的文档结构化需求。以下从功能定义、核心差异、应用场景及操作技巧等维度进行详细解析: 一、编号库(Numbering Library) 1. 定义与功能 编号库是Word中预设或用户自定义的有序列表格式集合,用于…...

C++入门七式——模板初阶

目录 函数模板 函数模板概念 函数模板格式 函数模板的原理 函数模板的实例化 模板参数的匹配原则 类模板 类模板的定义格式 类模板的显式实例化 当面对下面的代码时&#xff0c;大家会不会有一种无力的感觉&#xff1f;明明这些代码差不多&#xff0c;只是因为类型不…...

Python+Selenium+Pytest+POM自动化测试框架封装(完整版)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、测试框架简介 1&#xff09;测试框架的优点 代码复用率高&#xff0c;如果不使用框架的话&#xff0c;代码会显得很冗余。可以组装日志、报告、邮件等一…...

matlab 处理海洋数据并画图的工具包--ocean_data_tools

matlab 处理海洋数据并画图的工具包–ocean_data_tools matlab 处理海洋数据并画图的工具包–ocean_data_tools ocean_data_tools 简化了提取、格式化和可视化免费可用的海洋学数据的过程。虽然可以在线访问大量海洋学数据&#xff0c;但由于获取这些数据并将其格式化为可用数据…...

软件开发指南——GUI 开发方案推荐

1. LVGL (Light and Versatile Graphics Library) 适用场景&#xff1a;嵌入式设备、资源受限环境 优势&#xff1a; 专为嵌入式设计的开源 GUI 库&#xff0c;内存占用极小&#xff08;最低仅需 64KB RAM&#xff09;支持触摸屏、硬件加速&#xff08;如 STM32 的 LTDC&…...

JDK8 HashMap的实现原理

一 HashMap底层存储结构 HashMap底层结构采用&#xff08;数组&#xff09;&#xff08;链表 or 红黑树&#xff09;的形式来存储节点。 首先HashMap是一个数组&#xff0c;而且数组里面每个位置可以放入多个元素&#xff0c;形象一点&#xff0c;咱们把数组的这些个位置称为桶…...

YOLO拓展-锚框(anchor box)详解

一.锚框&#xff08;anchor box&#xff09;概述 1.1什么是锚框 锚框就是一种进行预测的像素框&#xff0c;通过遍历输入图像上所有可能的像素框&#xff0c;然后选出正确的目标框&#xff0c;并对位置和大小进行调整就可以完成目标检测任务。 对于yolo锚框的建设须基于实际…...

U-Boot(Universal Bootloader)简介

U-Boot 是一种开源的、高度可定制的 引导加载程序&#xff08;Bootloader&#xff09;&#xff0c;专为嵌入式系统和特定硬件平台设计。它负责在设备上电后初始化硬件、加载操作系统内核&#xff0c;并将控制权移交给操作系统&#xff0c;是嵌入式设备启动过程中不可或缺的核心…...

turtle库绘制进阶图形

要求&#xff1a; 1.绘制嵌套彩色五角星&#xff08;大小逐层递减&#xff09; 2. 设计函数绘制自定义正多边形&#xff08;边数与颜色参数化&#xff09; 3. 扩展&#xff1a;实现动态旋转花瓣图案 代码&#xff1a; import turtledef draw_nested_star():colors ["…...

[matlab]南海地形眩晕图代码

[matlab]南海地形眩晕图代码 请ChatGPT帮写个南海地形眩晕图代码 图片 图片 代码 .rtcContent { padding: 30px; } .lineNode {font-size: 12pt; font-family: "Times New Roman", Menlo, Monaco, Consolas, "Courier New", monospace; font-style: n…...

3. 进程概念

目录 1. 冯诺依曼体系结构 2. 操作系统 3. 理解进程的一般思路 4. 查看进程 5. fork初识 6. 进程状态 6.1 一般操作系统 6.2 Linux系统是怎么维护进程状态的 7. 进程优先级 先谈硬件-再谈软件-最后谈进程。 1. 冯诺依曼体系结构 我们常见的计算机&#xff08;笔记本电…...