关于 smali:2. 从 Java 到 Smali 的映射

一、对照 Java 代码与 Smali 代码差异

1.1 方法调用差异:Java vs Smali

Java 方法分类:

方法类型Java 示例Smali 指令特点说明
静态方法Utils.print("hi")invoke-static没有 this 指针
实例方法obj.show()invoke-virtual有 this,虚函数调用
构造函数new Person()invoke-direct用于构造对象
私有方法this.hidden()invoke-direct调用私有方法
接口方法list.size()invoke-interface调用接口方法
父类方法super.toString()invoke-super调用父类方法
动态调用(API)Java 8 lambdainvoke-polymorphic用于一些特殊函数,如反射调用

示例对照

1)静态方法调用

Java

Logger.log("test");

Smali

const-string v0, "test"
invoke-static {v0}, Lcom/example/Logger;->log(Ljava/lang/String;)V

2)实例方法调用

Java

User u = new User();
u.say("hello");

Smali

new-instance v0, Lcom/example/User;
invoke-direct {v0}, Lcom/example/User;-><init>()Vconst-string v1, "hello"
invoke-virtual {v0, v1}, Lcom/example/User;->say(Ljava/lang/String;)V

3)构造器调用

构造器就是特殊方法 <init>

Java

Person p = new Person();

Smali

new-instance v0, Lcom/example/Person;
invoke-direct {v0}, Lcom/example/Person;-><init>()V

1.2 控制流语句差异:Java vs Smali

if-else 语句

Java

if (a > b) {doA();
} else {doB();
}

Smali

# a = v0, b = v1
if-le v0, v1, :else_block
invoke-static {}, Lcom/example/Utils;->doA()V
goto :end:else_block
invoke-static {}, Lcom/example/Utils;->doB()V:end

常用比较指令:

指令条件
if-eq等于(==)
if-ne不等(!=)
if-lt小于(<)
if-gt大于(>)
if-le小于等于(≤)
if-ge大于等于(≥)

switch 语句

Java

switch (x) {case 1: f1(); break;case 5: f5(); break;default: fDefault();
}

Smali

sparse-switch v0, :switch_data  # v0 是 switch 的变量
goto :default                   # 如果没匹配任何 case,跳转 default:switch_data.sparse-switch0x1 -> :case10x5 -> :case5.end sparse-switch:case1invoke-static {}, Lcom/example/Util;->f1()Vgoto :end:case5invoke-static {}, Lcom/example/Util;->f5()Vgoto :end:defaultinvoke-static {}, Lcom/example/Util;->fDefault()V:end# 后续逻辑继续执行

while 循环

Java

int i = 0;
while (i < 10) {i++;
}

Smali

const/4 v0, 0x0       # i = 0
:loop_start
const/4 v1, 0xA
if-ge v0, v1, :loop_endadd-int/lit8 v0, v0, 1
goto :loop_start:loop_end

说明:

  • if-ge v0, v1, :loop_end当 i ≥ 10 跳出循环

  • goto用于跳转控制流

1.3 类字段与方法修饰符差异

字段定义差异

Java

public int count;
private String name;

Smali

.field public count:I
.field private name:Ljava/lang/String;

字段类型缩写表:

Java 类型Smali 类型
intI
booleanZ
byteB
charC
shortS
longJ
floatF
doubleD
对象L类路径;

字段访问指令

Java

this.count = 1;
int x = this.count;

Smali

const/4 v1, 0x1
iput v1, v0, Lcom/example/MyClass;->count:Iiget v2, v0, Lcom/example/MyClass;->count:I

说明:

  • iput = instance put,写入字段

  • iget = instance get,读取字段

方法定义与修饰符

Java

public void print(int n) { ... }
private int getNum() { return num; }

Smali

.method public print(I)V.locals 1# ...代码
.end method.method private getNum()I.locals 1# ...代码
.end method
Java 修饰符Smali 前缀
publicpublic
privateprivate
protectedprotected
staticstatic
finalfinal
abstractabstract
synchronizedsynchronized
nativenative

1.4 总结:Java ↔ Smali 快速对照表

Java 表达式Smali 表达说明
静态方法调用invoke-staticthis
实例方法调用invoke-virtualthis
构造函数调用invoke-direct<init>() 构造器
if 条件控制if-eq / if-lt / if-ge条件跳转
switch 分支.sparse-switch / .packed-switch分支跳转表
字段定义.field public/private 名:类型类成员变量
字段访问iget / iput实例字段读写
方法定义.method public 名(参数)返回值类方法定义

二、方法调用

2.1 Smali 方法调用指令分类

指令调用类型用途(Java 等价)
invoke-static静态方法ClassName.method()
invoke-virtual实例方法(常用)obj.method()
invoke-direct构造方法、私有方法new Obj()this.privateMethod()
invoke-super调用父类方法super.method()
invoke-interface接口方法interfaceObj.method()
invoke-virtual/range处理参数多的用于参数超过 5 个时

2.2 基础格式说明

通用格式:

invoke-xxx {参数寄存器列表}, L类名;->方法名(参数类型)返回类型

说明:

  • {} 中写的是使用的寄存器(如 {v0, v1}

  • L类名; 是类路径(如 Ljava/lang/String;

  • (参数类型):方法的参数签名

  • 返回类型:返回值类型(V 表示 void)

2.3 详细讲解每个指令

1)invoke-static:调用静态方法

Java 中 Class.method(),如 Math.abs(-1)

示例:

invoke-static {v0}, Ljava/lang/Math;->abs(I)I

说明:

  • 调用 Math.abs(int) 方法

  • v0 是传入的参数

  • (I)I 表示:参数是 int,返回也是 int

特点:

  • 不需要实例对象

  • 类方法、工具方法、public static 方法都用这个调用

2)invoke-virtual:调用实例方法(最常用)

Java 中 obj.method(),例如 str.length()

示例:

invoke-virtual {v0}, Ljava/lang/String;->length()I

说明:

  • v0 是一个 String 对象

  • 调用它的 length() 方法

  • ():无参数,返回 int

特点:

  • 用于非私有的实例方法(包括 publicprotected

  • 支持虚方法分发(多态)

3)invoke-direct:调用构造方法、私有方法

Java 中 new MyObject()this.privateMethod()

示例 1:调用构造函数

new-instance v0, Lcom/example/MyClass;
invoke-direct {v0}, Lcom/example/MyClass;-><init>()V

说明:

  • v0 是要构造的对象

  • 调用其构造器 MyClass()

  • <init>()V 是构造函数签名(返回类型是 void)

示例 2:调用私有方法

invoke-direct {v0}, Lcom/example/MyClass;->myPrivateMethod()V

特点:

  • 只能调用当前类的 private 方法 或 构造函数

  • 无法用于调用继承的或 public/protected 方法

补充:invoke-super

调用父类的方法,通常在子类中使用 super.method()

示例:

invoke-super {v0}, Lcom/example/ChildClass;->toString()Ljava/lang/String;

补充:invoke-interface

调用接口方法(Java 接口)

示例:

invoke-interface {v0}, Ljava/util/List;->size()I

2.4 几个重要的调用场景示例

调用静态方法(工具类)

Utils.sayHello();
invoke-static {}, Lcom/example/Utils;->sayHello()V

调用实例方法(普通对象方法)

myObj.getName();
invoke-virtual {v0}, Lcom/example/MyClass;->getName()Ljava/lang/String;

调用构造器(创建对象)

new MyClass();
new-instance v0, Lcom/example/MyClass;
invoke-direct {v0}, Lcom/example/MyClass;-><init>()V

调用私有方法(类内部)

this.secret();
invoke-direct {v0}, Lcom/example/MyClass;->secret()V

2.5 寄存器数量限制说明

最多可以用 5 个寄存器调用 invoke-*,如果超过 5 个参数(例如构造函数参数很多):

  • 使用 invoke-* /range 版本:

invoke-static/range {v0 .. v6}, Lcom/example/MyClass;->bigMethod(IJFLD)V

2.6 小结

指令用途说明
invoke-static静态方法不需要对象实例
invoke-virtual实例方法(普通调用)可被 override(多态)
invoke-direct构造方法/私有方法无法 override,调用 <init>
invoke-super父类方法用于 super.xxx()
invoke-interface接口方法用于接口对象

三、控制流语句

3.1 if-else 结构

Java 示例:

if (v0 == 1) {Log.i("TAG", "Equal");
} else {Log.i("TAG", "Not Equal");
}

Smali 实现:

# v0 已有值
const/4 v1, 0x1
if-eq v0, v1, :equal    # 如果 v0 == 1 跳转到 :equal:not_equalconst-string v2, "TAG"const-string v3, "Not Equal"invoke-static {v2, v3}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)Igoto :end:equalconst-string v2, "TAG"const-string v3, "Equal"invoke-static {v2, v3}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I:end

Smali 中常见条件跳转指令:

指令含义
if-eq相等跳转
if-ne不等跳转
if-lt小于跳转
if-gt大于跳转
if-le小于等于跳转
if-ge大于等于跳转
if-eqzv == 0 跳转(zero)
if-nezv != 0 跳转

3.2 switch-case

Java 示例:

switch (v0) {case 1: f1(); break;case 5: f5(); break;default: fDefault();
}

Smali 实现(sparse-switch):

sparse-switch v0, :switch_data
goto :default:switch_data.sparse-switch0x1 -> :case10x5 -> :case5.end sparse-switch:case1invoke-static {}, Lcom/example/Util;->f1()Vgoto :end:case5invoke-static {}, Lcom/example/Util;->f5()Vgoto :end:defaultinvoke-static {}, Lcom/example/Util;->fDefault()V:end

packed-switch vs sparse-switch

类型用法
packed-switchcase 是连续整数时使用
sparse-switchcase 是稀疏整数时使用

3.3 while 循环

Java 示例:

int i = 0;
while (i < 5) {Log.d("loop");i++;
}

Smali 实现:

const/4 v0, 0x0         # i = 0:loop_startconst/4 v1, 0x5if-ge v0, v1, :loop_end  # if i >= 5 -> endconst-string v2, "loop"invoke-static {v2}, Landroid/util/Log;->d(Ljava/lang/String;)Iadd-int/lit8 v0, v0, 0x1 # i++goto :loop_start:loop_end

3.4 for 循环(其实就是 while)

Java 示例:

for (int i = 0; i < 3; i++) {Log.e("for");
}

Smali 实现:

const/4 v0, 0x0         # int i = 0:for_beginconst/4 v1, 0x3if-ge v0, v1, :for_end   # if i >= 3 -> endconst-string v2, "for"invoke-static {v2}, Landroid/util/Log;->e(Ljava/lang/String;)Iadd-int/lit8 v0, v0, 0x1 # i++goto :for_begin:for_end

3.5 常见跳转逻辑总结表

Java 控制结构Smali 表达方式
if (a == b)if-eq a, b, :label_true
if (a != 0)if-nez a, :label_true
while (...)标签 :begin + 条件跳转 + goto :begin
for (...)与 while 相同结构
switchsparse-switch / packed-switch + 标签

四、类字段

4.1 什么是类字段

在 Java 中,字段就是类的成员变量:

public class Person {public String name;private static int count;
}

在 Smali 中,这些字段会写成:

.field public name:Ljava/lang/String;.field private static count:I

4.2 字段的 Smali 语法结构

.field [修饰符] 字段名:类型

常见修饰符:

修饰符含义
public公有
private私有
protected受保护
static静态字段(属于类)
final常量
volatile多线程可见性(较少见)
transient不序列化(与 Java 一致)
synthetic编译器自动生成(反混淆重要)

4.3 字段类型表示法(Smali 中)

Java 类型Smali 符号
intI
booleanZ
byteB
charC
shortS
longJ
floatF
doubleD
voidV(方法返回专用)
StringLjava/lang/String;
MyClassLcom/example/MyClass;
数组[I(int[]),[Ljava/lang/String;(String[])

4.4 Smali 中访问字段

字段分为 实例字段静态字段,对应不同的访问指令。

1)实例字段(每个对象一份)

操作指令名示例
读取字段igetiget v1, v0, Lcom/demo/User;->name:Ljava/lang/String;
写入字段iputiput v2, v0, Lcom/demo/User;->name:Ljava/lang/String;

2)静态字段(类级别共享)

操作指令名示例
读取字段sgetsget v0, Lcom/demo/User;->count:I
写入字段sputsput v1, Lcom/demo/User;->count:I

4.5 例子分析:完整的字段声明与访问流程

Java 示例:

public class User {public String name;private static int count = 0;public void setName(String n) {this.name = n;count++;}
}

Smali 对应(简化版):

.class public Lcom/demo/User;
.super Ljava/lang/Object;.field public name:Ljava/lang/String;
.field private static count:I.method public setName(Ljava/lang/String;)V.locals 1# 把参数 n(p1)赋值给 this.nameiput-object p1, p0, Lcom/demo/User;->name:Ljava/lang/String;# sget 静态字段sget v0, Lcom/demo/User;->count:Iadd-int/lit8 v0, v0, 0x1sput v0, Lcom/demo/User;->count:Ireturn-void
.end method

4.6 几个实战技巧与细节

判断字段是静态还是实例

特征静态字段实例字段
修饰符static不带 static
读取指令sget / sputiget / iput
所属类级别共享每个对象一份
典型用途常量、计数器每个对象的属性,如 name

Frida Hook 中字段的常用操作

// 获取实例字段
Java.use("com.demo.User").name.value// 获取静态字段
Java.use("com.demo.User").count.value// 设置字段
Java.use("com.demo.User").name.value = "hack"

4.7 .field 高级用法

初始值:

.field public static final CONST:I = 0x5

表示该字段常量为 5(int 型)

4.8 小结

类型声明指令访问读取写入修改
实例字段.field name:Typeiget / iget-objectiput / iput-object
静态字段.field static name:Typesget / sget-objectsput / sput-object

五、方法访问修饰符在 Smali 中如何体现

5.1 方法的 Smali 定义格式

.method [修饰符] 方法名(参数)返回类型

比如:

.method public static final doSomething(I)Ljava/lang/String;

这是一个:

  • public 公有

  • static 静态

  • final 不可重写
    的方法,接受一个 int 参数,返回一个 String

5.2 常见修饰符说明(对照 Java)

Smali 修饰符Java 对应含义解释
publicpublic任何类都可以调用(最常见)
privateprivate仅类内部调用
protectedprotected同包或子类中可调用
staticstatic属于类本身,不依赖实例对象
finalfinal不可被子类重写(继承中常见)
abstractabstract抽象方法(无实现体,interface、abstract class 中出现)
synthetic编译器自动添加编译生成的方法(如桥接方法、Lambda 方法),用于反混淆
constructor构造函数表示这是构造方法(即 <init>
nativenative本地方法,用 JNI 实现(通常没代码体)
bridge编译器桥接泛型擦除后生成的桥接方法(一般逆不了逻辑)
varargsT... args可变参数(只是标记,不影响 Smali 写法)

5.3 完整示例分析

Java 源码

public class Demo {public static final void log(String msg) {Log.d("TAG", msg);}private int compute(int a, int b) {return a + b;}protected abstract void work();  // 抽象方法
}

对应 Smali

.method public static final log(Ljava/lang/String;)V.locals 1const-string v0, "TAG"invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)Ireturn-void
.end method.method private compute(II)I.locals 1add-int v0, p1, p2return v0
.end method.method protected abstract work()V

5.4 修饰符的实际作用和实战用途

修饰符实战应用举例
public可直接用 Frida/Java 调用(常用于静态分析)
private需要 Frida Bypass 或 Java.use(...).$init.overload(...)
static无需创建实例,Frida 中直接 .valueinvokeStatic
final子类不能 override,意味着 Hook 只能静态覆盖
abstract没有方法体,不能直接 Hook,要 Hook 实现类
synthetic混淆后生成的自动方法,可包含核心逻辑(Frida 分析重点)
constructor对应 <init>,实例化时会调用,可以 hook $init
native没有 Smali 代码体,常需要 native 层分析或 trace

5.5 Hook 时与修饰符的注意事项

1)Hook 静态方法(static)

Java.use("com.test.Demo").log.overload('java.lang.String').implementation = function(msg) {console.log("log hooked: " + msg);
};

2)Hook 实例方法(非 static)

Java.use("com.test.Demo").compute.implementation = function(a, b) {return a + b + 999;
};

3)Hook 构造方法 <init>

Java.use("com.test.Demo").$init.overload('int', 'java.lang.String').implementation = function(i, s) {console.log("构造函数拦截:" + i + ", " + s);return this.$init(i, s);
};

5.6 总结速查表

修饰符组合含义
.method public公有方法(类外可访问)
.method private私有方法(类内访问,hook 时需绕过)
.method static静态方法(不依赖实例)
.method constructor构造方法 <init>
.method abstract抽象方法(无实现体)
.method public static final常量型工具函数
.method synthetic编译器生成,可能是混淆后的关键方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年05月29日Github流行趋势

项目名称&#xff1a;agenticSeek 项目地址url&#xff1a;https://github.com/Fosowl/agenticSeek项目语言&#xff1a;Python历史star数&#xff1a;11898今日star数&#xff1a;2379项目维护者&#xff1a;Fosowl, steveh8758, klimentij, ganeshnikhil, apps/copilot-pull-…

Dubbo高频面试题

引言 作为分布式服务框架的标杆&#xff0c;Dubbo凭借其高性能RPC通信、灵活的服务治理能力和丰富的容错机制&#xff0c;成为Java技术栈中微服务领域的核心考点。本文系统梳理Dubbo高频面试核心知识点&#xff0c;涵盖容错策略、负载均衡、注册中心原理、服务上下线感知等关键…

氮气吹扫电磁阀

一、氮气吹扫电磁阀的概述 氮气吹扫电磁阀是一种重要的工业自动控制设备&#xff0c;用于对工业设备中出现的杂质和沉淀物进行清理&#xff0c;以保证生产线的畅通和生产效率的稳定。其作用是在需要吹扫清洗的工业设备中&#xff0c;通过控制气源的气压&#xff0c;打开电磁阀…

网络安全的守护者:iVX 如何构建全方位防护体系

一、安全技术的三大趋势 在数字化时代&#xff0c;网络安全面临着前所未有的挑战。随着企业级应用的普及&#xff0c;安全技术也在不断演进。目前&#xff0c;安全技术架构的发展呈现出三大趋势&#xff1a; 零信任架构的崛起&#xff1a;传统的网络安全依赖于边界防护&#…

微软云如何申请使用

微软云&#xff08;Azure&#xff09;新手“开荒”指南&#xff1a;5步搞定账户&#xff0c;直达云端&#xff01; 还在为云计算的复杂门槛发愁吗&#xff1f;别担心&#xff01;当全球83%的企业都在加速“上云”&#xff0c;微软智能云Azure凭借其在全球34个区域、200服务的庞…

magic-api配置Git插件教程

一、配置gitee.com 1&#xff0c;生成rsa密钥&#xff0c;在你的电脑右键使用管理员身份运行&#xff08;命令提示符&#xff09;&#xff0c;执行下面命令 ssh-keygen -t rsa -b 2048 -m PEM一直按回车键&#xff0c;不需要输入内容 找到 你电脑中的~/.ssh/id_rsa.pub 文件…

ojs导入显示空白页错误信息

ojs技术支持:ojs.net.cn error: Uncaught Error: Call to a member function getData() on null in /var/www/html/ojs3/classes/search/ArticleSearchIndex.inc.php:38 Stack trace: #0 /var/www/html/ojs3/plugins/importexport/esci/filter/esciXmlArticleFilter.inc.php(…

【ConvLSTM第一期】ConvLSTM原理

目录 &#x1f9e0; 一、ConvLSTM 原理详解1.1 背景1.2 ConvLSTM 的结构 参考 ConvLSTM&#xff08;Convolutional Long Short-Term Memory&#xff09;是一种结合了卷积神经网络&#xff08;CNN&#xff09;与循环神经网络&#xff08;RNN&#xff09;中 LSTM&#xff08;长短…

4.8.1 利用Spark SQL实现词频统计

在利用Spark SQL实现词频统计的实战中&#xff0c;首先需要准备单词文件并上传至HDFS。接着&#xff0c;可以通过交互式方法或创建Spark项目来实现词频统计。交互式方法包括读取文本文件生成数据集&#xff0c;扁平化映射得到新数据集&#xff0c;然后将数据集转成数据帧&#…

Linux相关概念和易错知识点(41)(UDP、TCP报头结构)

目录 1.UDP&#xff08;1&#xff09;传输层&#xff08;2&#xff09;UDP报头&#xff08;3&#xff09;缓冲区和sk_buff①缓冲区②sk_buff 2.TCP&#xff08;1&#xff09;发送和接受缓冲区&#xff08;2&#xff09;报头结构①按序到达②可靠传输③流量控制④紧急指针 1.UDP…

光谱相机在生态修复监测中的应用

光谱相机通过多维光谱数据采集与智能分析技术&#xff0c;在生态修复监测中构建起‌“感知-评估-验证”‌的全周期管理体系&#xff0c;其核心应用方向如下&#xff1a; 一、土壤修复效能量化评估 ‌重金属污染动态监测‌ 通过短波红外&#xff08;1000-2500nm&#xff09;波…

[网页五子棋]项目介绍以及websocket的消息推送(轮询操作)、报文格式和握手过程(建立连接过程)

文章目录 项目背景核心技术创建项目WebSocket消息推送轮询操作 报文格式握手过程(建立连接过程) 项目背景 用户模块 用户的注册和登录管理用户的天梯分数&#xff0c;比赛场数&#xff0c;获胜场数等信息 匹配模块 依据用户的天梯积分&#xff0c;来实现匹配机制 对战模块 把两…

时序模型介绍

一.整体介绍 1.单变量 vs 多变量时序数据 单变量就是只根据时间预测&#xff0c;多变量还要考虑用户 2.为什么不能用机器学习预测&#xff1a; a.时间不是影响标签的关键因素 b.时间与标签之间的联系过于弱/过于复杂&#xff0c;因此时序模型依赖于时间与时间的相关性来进行预…

尚硅谷redis7 86 redis集群分片之3主3从集群搭建

86 redis集群分片之3主集群搭建 3主3从redis集群配置 找3台真实虚拟机,各自新建 mķdir -p /myredis/cluster 新建6个独立的redis实例服务 IP:192.168.111.175端口6381/端口6382 vim /myredis/cluster/redisCluster6381.conf bind 0.0.0.0 daemonize yes protected-mode no …

Python服务器请求转发服务

前言&#xff1a; 服务器无法连接外网 配置步骤 准备python脚本服务器内下载python 示例 1.下载python创建虚拟环境以及配置 -- 磁盘空间 df -h -- 下载apt sudo yum install apt -y-- 下载python pip sudo apt install python3 python3-pip python3-venv -y-- 测试查看 …

02.K8S核心概念

服务的分类 有状态服务&#xff1a;会对本地环境产生依赖&#xff0c;例如需要把数据存储到本地磁盘&#xff0c;如mysql、redis&#xff1b; 无状态服务&#xff1a;不会对本地环境产生任何依赖&#xff0c;例如不会存储数据到本地磁盘&#xff0c;如nginx、apache&#xff…

Java八股-Java优缺点,跨平台,jdk、jre、jvm关系,解释和编译

java优势劣势&#xff1f; 优势&#xff1a;面向对象&#xff0c;平台无关&#xff0c;垃圾回收&#xff0c;强大的生态系统 劣势&#xff1a;运行速度慢&#xff08;相比于c和rust这样的原生编译语言会比较慢&#xff09;&#xff0c;语法繁琐&#xff08;相比于python&…

Attention Is All You Need论文阅读笔记

Attention is All You Need是如今机器学习研究者必读的论文&#xff0c;该文章提出的Transformer架构是如今很多机器学习项目的基础&#xff0c;说该文章极大推动了机器学习领域的研究也不为过。 但这么重要&#xff0c;也是必读的文章对初学者来说其实并不友好&#xff0c;很多…

【MAC】YOLOv8/11/12 转换为 CoreML 格式并实现实时目标检测

在本文中,我们将详细介绍如何将 YOLOv8/11/12 模型转换为 CoreML 格式,并使用该模型在摄像头实时检测中进行目标检测。主要适用于M1、M2、M3、M4芯片的产品。 以下教程在YOLOv8/11/12均适用,此处就以 YOLOv11 举例 目录 前提条件YOLOv8/11/12 转换为 CoreML实时目标检测结论…

Redis--缓存击穿详解及解决方案

缓存击穿 缓存击穿问题也称热点key问题&#xff0c;就是一个高并发访问&#xff08;该key访问频率高&#xff0c;访问次数多&#xff09;并且缓存重建业务比较复杂的key突然失效了&#xff0c;大量的请求访问会在瞬间给数据库带来巨大的冲击。 缓存重建业务比较复杂&#xff…