Android ART知多少?

news2024/11/16 9:29:37

Android 虚拟机 ART(Android Runtime)是 Android 平台上的应用程序运行时环境,用于执行应用程序的字节码。ART 自 Android 5.0(Lollipop)开始取代了 Dalvik,成为 Android 的默认运行时环境。本文将从以下几个方面详细系统地介绍 ART,并结合部分源码来探讨其实现原理:

  1. ART 简介
  2. ART 与 Dalvik 的对比
  3. ART 的架构与核心模块
  4. 关键技术
    • Ahead-of-Time 编译 (AOT)
    • Just-In-Time 编译 (JIT)
    • 垃圾回收 (GC)
    • 内存管理与优化
  5. 源码剖析
  6. 性能优化的设计理念
  7. 总结

1. ART 简介

ART 是 Android 平台上的一种高效、稳定的运行时,专为移动设备优化。与 Dalvik 的解释执行不同,ART 结合了提前编译和即时编译,显著提升了应用性能和响应速度,同时降低了内存消耗。

主要特点:

  • 高性能:通过 AOT 和 JIT 提高应用运行效率。
  • 优化内存使用:改进 GC 算法,减少暂停时间。
  • 改进调试工具:支持更强大的调试和分析功能,如 TraceView 和 HPROF。
  • 兼容性强:支持运行旧的 Dalvik 字节码。

2. ART 与 Dalvik 的对比

特性ARTDalvik
编译模式AOT + JIT解释执行 + JIT
初次启动时间较长较短
应用运行性能中等
内存消耗较低较高
垃圾回收并发、低暂停的 GC停止-复制的 GC
支持工具TraceView、Perfetto 等基本调试工具

3. ART 的架构与核心模块

ART 的架构分为以下几个核心部分:

  • ClassLoader: 负责加载字节码。
  • Compiler (AOT/JIT): 提供提前和即时编译功能。
  • Garbage Collector (GC): 负责内存分配与回收。
  • Runtime: 提供运行时环境,管理线程、类、方法调用等。
  • Debugger 和 Profiler: 提供调试和性能分析工具。
    下面是架构图示意:

在这里插入图片描述

4. 关键技术

4.1 Ahead-of-Time 编译 (AOT)

Android Runtime (ART) 的 Ahead-of-Time (AOT) 编译 是一种在应用安装时,将字节码(Bytecode)直接编译为机器码(Native Code)的技术,从而提升应用运行时的性能。下面详细说明:

背景与原理
  1. Dalvik VM 的问题在 Android ART 之前,Android 使用的是 Dalvik 虚拟机,它主要依赖 Just-in-Time (JIT) 编译技术。在应用运行时,字节码被即时编译为机器码,尽管灵活性较高,但存在以下问题:
  • 启动速度慢:每次启动应用时,字节码需要重新编译。
  • 内存占用高:需要维护额外的 JIT 缓存。
  • 性能不稳定:即时编译会增加 CPU 负载,影响用户体验。
  1. ART 的改进:引入 AOT 编译ART 使用 AOT 技术,在应用安装时直接编译字节码为机器码并保存。应用运行时不需要即时编译,直接执行机器码,大大提升了性能。

工作原理

AOT 编译发生在应用安装过程中,主要步骤包括:

  1. 字节码加载从应用的 .dex 文件(包含应用代码的 Dalvik Executable 格式)加载字节码。
  2. 静态编译使用编译器(如 dex2oat)将字节码转换为目标设备的机器码。
  3. 生成 OAT 文件编译后的机器码保存在 OAT 文件中(Optimized Android Runtime 文件),这些文件通常存储在设备的 /data/dalvik-cache 路径下。
  4. 优化与校验
  • ART 在编译过程中会根据设备的 CPU 架构(如 ARM 或 x86)生成优化的机器码。
  • 还会执行验证(Verification),确保编译后的代码不会造成崩溃或安全问题。

优点

  1. 启动更快由于机器码已经编译好,应用启动时无需等待即时编译。
  2. 性能更高
  • 减少运行时的 JIT 编译负担,提升应用流畅性。
  • 更高效的内存使用,因为无需维护 JIT 缓存。
  1. 节能省电运行时的 CPU 开销减少,有助于延长电池续航。

缺点

  1. 安装时间更长 AOT 编译会显著延长应用安装时间,因为需要完成编译和优化过程。
  2. 存储空间占用大编译后的 OAT 文件会占用额外的存储空间。
  3. 灵活性降低动态语言特性(如反射)和运行时修改代码的能力会受到一定限制。

ART 的 AOT 与 JIT 的结合

在 Android 7.0(Nougat)及之后的版本中,ART 引入了 混合编译模式,将 AOT 与 JIT 优势结合:

  • 应用安装时只进行部分 AOT 编译(主要是核心代码)。
  • 运行时,使用 JIT 编译未优化的代码片段,同时记录 JIT 编译结果。
  • 应用闲置时,通过后台编译(Profile-Guided Optimization, PGO),将热点代码进一步转为 AOT 编译,提高性能。

代码示例与工具

  1. dex2oat 工具
    在 Android 系统中,dex2oat 是主要的 AOT 编译工具。你可以使用以下命令查看相关信息:
dex2oat --help
  1. 检查 AOT 文件
    运行设备上的命令,查看已生成的 OAT 文件:
ls /data/dalvik-cache/
  1. 关键函数 art/compiler
bool CompilerDriver::CompileAll() {
    // 遍历所有的类和方法
    for (Class c : classes) {
        for (Method m : c.GetMethods()) {
            CompileMethod(m);
        }
    }
    return true;
}

总结

ART 的 AOT 编译通过将字节码提前编译为机器码,显著提升了 Android 应用的启动速度和运行性能。尽管有安装时间较长、存储占用等问题,但通过与 JIT 的结合,ART 在后续版本中进一步优化了运行效率和用户体验,是 Android 性能优化的里程碑技术。

在这里插入图片描述

4.2 Just-In-Time 编译 (JIT)

Android Runtime (ART) 的 Just-In-Time (JIT) 编译 是在应用运行时动态编译字节码为机器码的技术,与 Ahead-of-Time (AOT) 编译互为补充,用于提升运行效率并减少应用安装时间。以下是 JIT 编译的详细介绍。

JIT 编译的背景

  1. Dalvik VM 的传统 JIT在 ART 之前,Android 使用的是 Dalvik VM,其核心编译方式就是 JIT。JIT 的特点是按需即时编译,虽然减少了安装时的编译负担,但运行时性能受限,具体表现为:
  • 每次运行时都需要重新编译。
  • 占用额外的 CPU 和内存资源,导致运行时性能波动。
  1. ART 的早期缺陷:全量 AOT 编译在早期 ART(Android 5.0 和 6.0)中,全量 AOT 编译优化了运行时性能,但增加了应用安装时间,且存储占用较高。为平衡性能与灵活性,Android 在 7.0(Nougat)引入了 JIT + AOT 混合模式

JIT 编译的工作原理

ART 中的 JIT 编译在运行时按需触发,以下是其主要工作流程:

  1. 字节码解释执行
  • 应用启动时,ART 会使用解释器逐条执行字节码,快速响应用户请求。
  • 如果某些代码片段(如循环或常用方法)被多次调用,ART 会将其标记为热点代码。
  1. 热点代码的动态编译
  • 当热点代码的执行次数超过一定阈值时,JIT 编译器会将其即时编译为机器码。
  • 编译后的机器码保存在内存中,并直接执行,提高运行效率。
  1. Profile 文件记录
  • 在应用运行过程中,ART 会将热点代码的信息记录到 Profile 文件中。
  • 这些 Profile 数据可用于后续优化,如后台编译(Profile-Guided Optimization,PGO)。
  1. 后台优化与 AOT 的结合
  • 应用空闲时,ART 使用 JIT 记录的 Profile 数据进行增量 AOT 编译,将热点代码进一步优化为高效的机器码。

JIT 的优点

  1. 灵活性高
  • 仅对频繁使用的代码进行编译,减少了不必要的编译开销。
  • 支持动态语言特性(如反射)和运行时动态加载。
  1. 安装时间短
  • 应用安装时无需进行全量 AOT 编译,安装速度更快。
  1. 优化运行性能
  • 动态编译热点代码,提升执行效率。
  • 配合 Profile 数据进行长期优化。

JIT 的缺点

  1. 启动速度相对慢
  • 初次执行代码时,仍需解释执行,直到热点代码触发编译。
  1. 内存占用高
  • 编译后的机器码保存在内存中,占用更多 RAM。
  1. 性能波动
  • 编译过程需要消耗 CPU 资源,在高负载情况下可能影响用户体验。

JIT + AOT 的混合模式

Android 7.0(Nougat)及之后版本中,ART 实现了 JIT 与 AOT 的混合编译模式,以兼顾运行效率和灵活性:

  1. 运行时使用 JIT 编译
  • 应用初次运行时,通过 JIT 编译热点代码,快速优化性能。
  1. 后台优化 AOT 编译
  • 应用空闲时,利用 Profile 数据增量编译机器码,生成优化的 OAT 文件,供后续运行使用。
  1. 适应设备环境
  • JIT 和 AOT 编译结果均针对设备的 CPU 架构优化,提供更好的运行效率。

示例与工具

  1. Profile 文件查看Profile 文件通常存储在以下路径:
/data/data//code_cache/profile/
  1. ART 的优化工具使用 profman 工具分析 Profile 数据:
profman --dump-profile-info --profile-file=
  1. 实时调试 JIT 编译开启 ART 的 JIT 调试日志:
setprop dalvik.vm.extra-opts -verbose:jit
  1. JIT 编译示例代码 art/runtime/jit
void Jit::CompileMethod(Method* method) {
    if (IsHotMethod(method)) {
        CompileToMachineCode(method);
    }
}

总结

ART 的 JIT 编译通过动态编译热点代码,提供了高效灵活的性能优化方式,与 AOT 编译相辅相成。在应用安装、运行和优化的不同阶段,JIT 编译减少了安装时间,提升了运行性能,同时为后台 AOT 优化提供了数据支持。这种混合编译模式在 Android 系统中实现了性能与灵活性的良好平衡。

在这里插入图片描述

4.3 垃圾回收 (GC)

Android Runtime (ART) 的垃圾回收(Garbage Collection, GC)机制负责自动管理应用的内存,释放不再使用的对象所占用的空间,从而避免内存泄漏和提升性能。ART 的垃圾回收相较于 Dalvik 虚拟机有显著改进,以下是详细介绍:

ART 垃圾回收的基本原理

  1. 对象分配与生命周期
  • ART 管理的内存堆分为不同区域(如年轻代和老年代)。
  • 应用运行时在堆上分配内存,对象的生命周期决定了它被回收的时机。
  1. 垃圾回收触发条件垃圾回收的触发通常基于以下条件:
  • 堆内存不足:新对象分配时发现堆已满。
  • 手动触发:某些 API(如 System.gc())可能提示进行回收。
  • 内存优化:系统主动回收内存以提升性能。
  1. 标记-清除算法ART 的 GC 使用 标记-清除(Mark-and-Sweep) 算法,分为以下步骤:
  • 标记阶段:找到所有活跃的对象(可达的对象)。
  • 清除阶段:释放未标记(不可达)的对象所占的内存。
    在这里插入图片描述

ART 垃圾回收的特点

  1. 并发垃圾回收ART 使用并发 GC,将垃圾回收的部分任务分摊到多个线程中,从而减少对主线程的影响,提高应用的流畅性。
  2. 低延迟设计
  • ART 针对交互式应用进行了优化,尽可能缩短 GC 的暂停时间(GC Pause Time)。
  • 在用户操作频繁的时刻(如滑动列表),ART 尽量避免大规模的回收操作。
  1. 分代回收ART 使用分代式垃圾回收策略,将堆分为以下几部分:
  • 年轻代(Young Generation):存放生命周期短的对象,回收频率高。
  • 老年代(Old Generation):存放生命周期长的对象,回收频率低。
  1. 增量回收ART 的 GC 还支持增量回收(Incremental GC),将一次性的大量回收操作分解为小批量的任务,降低应用响应的卡顿。

ART 的垃圾回收类型

ART 提供多种垃圾回收类型,根据需求自动切换:

  1. Partial GC(部分回收)
  • 仅回收年轻代对象。
  • 触发快,暂停时间短。
  1. Full GC(完全回收)
  • 回收整个堆,包括年轻代和老年代。
  • 通常在堆内存不足时触发,暂停时间较长。
  1. Concurrent GC(并发回收)
  • 在后台线程执行垃圾回收。
  • 减少对主线程的影响,提高性能。
  1. Compacting GC(压缩回收)
  • 重新整理内存堆,将分散的内存块合并为连续的内存。
  • 提高后续对象分配的效率,避免内存碎片问题。
  1. Sticky GC(粘性回收)
  • 仅清理应用运行期间新分配的短生命周期对象。
  • 触发快,适用于频繁分配对象的场景(如动画或 UI 渲染)。

ART GC 的优化

  1. 避免频繁触发 GC
  • 频繁分配短生命周期对象可能导致频繁的垃圾回收,从而影响性能。
  • 优化方法:减少临时对象的创建,尤其是在循环中。
  1. 减小堆内存压力
  • 控制对象大小,避免一次性分配过多大对象(如 Bitmap)。
  • 优化方法:使用 Bitmap.recycle() 主动释放资源。
  1. 监控 GC 行为
  • 通过 Android Studio Profiler 或 adb logcat 查看 GC 日志,了解回收频率和暂停时间:
adb logcat | grep GC
  1. 调整堆大小
  • AndroidManifest.xml 中通过 android:largeHeap 属性申请更大的堆内存,但仅在必要时使用。
  • 示例:
<application
    android:largeHeap="true">
</application>

在这里插入图片描述

GC 日志示例

以下是 ART GC 的典型日志:

GC concurrent freed 2048K, 10% free 20480K/22528K, paused 5ms+2ms, total 10ms

日志含义:

  • GC concurrent:并发回收。
  • freed 2048K:释放了 2MB 内存。
  • 10% free:堆剩余 10% 的空闲空间。
  • 20480K/22528K:堆当前使用 20MB,总大小为 22MB。
  • paused 5ms+2ms:主线程暂停时间分别为 5ms 和 2ms。
  • total 10ms:总回收时间为 10ms。

总结

ART 的垃圾回收机制通过分代式设计、并发回收和增量回收等方式,实现了低延迟、高效的内存管理。这种机制在减少内存泄漏、优化性能方面有显著效果,但开发者仍需遵循最佳实践(如减少对象分配和合理使用内存)来配合 GC 的高效运行,从而保证应用的流畅性和稳定性。

在这里插入图片描述

4.4 内存管理与优化

Android Runtime (ART) 的内存模型和优化机制是其高性能运行的核心。相比于早期的 Dalvik 虚拟机,ART 在内存管理和优化方面做出了许多改进,使得应用运行更加高效、流畅且节能。以下是 ART 的内存模型及其优化原理的详细介绍:

ART 的内存模型

ART 的内存模型由以下几个主要部分组成:

1. 堆内存

堆是 ART 中分配对象的主要区域,由以下几个部分组成:

  • **年轻代(Young Generation):**存储生命周期较短的对象。包括 Eden 区和两个 Survivor 区。对象大多在此区域被创建和回收。采用高频率的垃圾回收机制,回收快,暂停时间短。
  • **老年代(Old Generation):**存储生命周期较长的对象(多次在年轻代垃圾回收中幸存)。回收频率低,但占用空间大。通常在 Full GC 时进行回收。

2. 栈内存

  • 每个线程都有自己的独立栈,用于存储局部变量、方法调用信息等。
  • 栈内存生命周期与线程一致,线程结束时栈内存自动释放。

3. 方法区

  • 用于存储类的元信息(如方法、字段等)。
  • 在 ART 中,这部分被称为 Class Metadata,其管理更加高效且占用较少内存。

4. 本地内存(Native Heap)

  • 由 JNI 或底层库分配,与 ART 的堆分开管理。
  • 主要用于直接与操作系统交互的资源(如 Bitmap、OpenGL 等)。

ART 内存管理的关键特性

1. 分代式内存管理

ART 实现了分代式内存管理,针对不同生命周期的对象采用不同的策略:

  • **短生命周期对象(年轻代):**采用高效的复制垃圾回收(Copying GC)算法,快速回收。
  • **长生命周期对象(老年代):**使用标记-清除(Mark-and-Sweep)算法进行回收,减少停顿时间。
  • **粘性垃圾回收(Sticky GC):**仅回收最近分配的短生命周期对象,适用于频繁内存分配的场景。

2. 内存对齐与压缩

ART 优化了内存分配的方式:

  • **对象内存对齐:**保证对象存储在对齐的地址上,提升访问效率。
  • **指针压缩(Pointer Compression):**在 64 位架构下,通过压缩指针(将 64 位指针压缩为 32 位),减少内存占用。

3. 增量分配与回收

  • ART 引入增量内存分配和回收机制,将内存操作分散到多个时刻,降低单次分配或回收的延迟。

4. 垃圾回收优化

  • **并发垃圾回收(Concurrent GC):**在后台线程完成标记和清除工作,减少主线程的阻塞时间。
  • **压缩垃圾回收(Compacting GC):**防止内存碎片,通过整理内存堆空间提升后续分配效率。

ART 内存优化的核心技术

1. 即时与延迟分配

ART 在对象分配时,使用线程本地分配缓冲区(Thread Local Allocation Buffer, TLAB):

  • **分配效率提升:**每个线程独立分配小块内存,减少锁竞争。
  • **减少全局锁冲突:**提高多线程环境下的内存分配效率。

2. 内存释放与复用

ART 优化了内存释放的机制:

  • 回收后的内存块会直接进入内存池,供后续对象分配复用,减少操作系统层的内存申请。

3. 代码与数据共享

  • **Dex 文件优化:**ART 将 .dex 文件编译为更高效的 OAT 文件,减少内存消耗。
  • **字符串池:**ART 实现了全局字符串池,共享重复字符串以减少内存占用。

4. 多用户优化

  • ART 针对 Android 多用户模式优化了资源共享机制,例如系统类的元信息仅加载一次并共享。

ART 内存模型优化的效果

1. 提高运行性能

  • 减少垃圾回收引起的停顿时间,提升应用响应速度。
  • 增强内存分配效率,特别是高频次对象分配场景(如 UI 渲染)。

2. 降低内存占用

  • 通过指针压缩、字符串池等技术,减少应用的内存足迹。
  • 内存复用机制避免了频繁的内存分配和回收。

3. 提升设备续航

  • 更高效的内存管理降低了 CPU 和内存的使用率,从而减少电池消耗。

开发者优化内存的最佳实践

1. 避免内存泄漏

  • **Context 管理:**避免长生命周期对象持有短生命周期的 Context。
  • **工具检测:**使用 Android Studio Profiler 或 LeakCanary 检测内存泄漏。

2. 减少临时对象分配

  • 避免在循环中频繁分配短生命周期对象。
  • 使用对象池(Object Pool)复用高频创建的对象。

3. 优化大对象使用

  • 对于 Bitmap 等大对象,使用 Bitmap.recycle() 主动释放内存。
  • 尽量使用合适的压缩格式(如 WebP)降低图片大小。

4. 使用 Android 平台特性

  • 配置适当的 android:largeHeap 仅在必要时使用。
  • 利用 Profile-Guided Optimization (PGO) 提升运行时效率。

总结

ART 的内存模型通过分代管理、并发回收、压缩优化等技术,提供了高效的内存分配和回收机制,减少了内存泄漏和性能瓶颈。此外,ART 针对特定设备和应用场景的优化(如指针压缩和 TLAB)显著提升了应用的运行效率。开发者需结合 ART 的内存特性,配合最佳实践,确保应用在各种设备上的内存使用和性能表现达到最佳状态。

在这里插入图片描述

5. 源码剖析

5.1 ART 初始化

ART 在启动时初始化环境,包括类加载器、GC 和编译器等。

源码路径:

  • art/runtime/runtime.cc
    关键函数:
void Runtime::Init() {
    // 初始化 GC
    InitGC();
    // 初始化编译器
    InitCompiler();
    // 加载基本类
    LoadBaseClasses();
}
5.2 方法执行

ART 通过解释器或编译器执行方法。

源码路径:

  • art/runtime/interpreter/interpreter.cc
    核心代码:
void Interpreter::ExecuteMethod(Thread* thread, Method* method) {
    if (method-&gt;IsCompiled()) {
        ExecuteCompiledCode(thread, method);
    } else {
        ExecuteDexCode(thread, method);
    }
}

6. 性能优化的设计理念

  1. 冷热分离:通过 JIT 编译和 Profiling 分析,将热方法进行动态优化。
  2. 减少停顿时间:通过并发 GC 减少应用的响应延迟。
  3. 内存优化:利用 TLAB 和大型对象空间优化内存分配。

7. 总结

ART 作为 Android 平台的核心运行时环境,大幅度提升了应用性能和用户体验。它的 AOT 和 JIT 编译器、并发垃圾回收和先进的内存管理为 Android 应用的高效运行提供了强有力的保障。

通过分析 ART 源码,我们能够深入理解其设计理念和实现细节,为开发高性能 Android 应用打下坚实基础。如果您有更多深入学习的需求,可以进一步探索 ART 的调试工具和优化方法。

参考

Memory Management in Android
Android CPU, Compilers, D8 & R8

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

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

相关文章

Vulnhub靶场 Billu_b0x 练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 文件包含2. SQL注入3. 文件上传4. 反弹shell5. 提权&#xff08;思路1&#xff1a;ssh&#xff09;6. 提权&#xff08;思路2&#xff1a;内核&#xff09;7. 补充 0x04 总结 0x00 准备 下载链接&#…

软间隔支持向量机支持向量的情况以及点的各种情况

软间隔支持向量 ​ 这一节我们要回答的问题是&#xff1f;如何判断一个点是软间隔支持向量机中的支持向量&#xff0c;在硬间隔支持向量机中&#xff0c;支持向量只需要满足一个等式&#xff1a; y i ( w T x i b ) − 1 0 y_i(w^Tx_i b) -1 0 yi​(wTxi​b)−10 ​ 在软间…

PCA 原理推导

针对高维数据的降维问题&#xff0c;PCA 的基本思路如下&#xff1a;首先将需要降维的数据的各个变量标准化&#xff08;规范化&#xff09;为均值为 0&#xff0c;方差为 1 的数据集&#xff0c;然后对标准化后的数据进行正交变换&#xff0c;将原来的数据转换为若干个线性无关…

在Ubuntu 24.04 LTS上安装飞桨PaddleX

前面我们介绍了《在Windows用远程桌面访问Ubuntu 24.04.1 LTS》本文接着介绍安装飞桨PaddleX。 PaddleX 3.0 是基于飞桨框架构建的一站式全流程开发工具&#xff0c;它集成了众多开箱即用的预训练模型&#xff0c;可以实现模型从训练到推理的全流程开发&#xff0c;支持国内外多…

Web_前端_HTML入门学习的案例案例1

HTML入门学习的案例 来源: HTML入门学习的案例_给学生讲html内容案例-CSDN博客 案例1&#xff1a;hello.html <html><body><title>html技术</title></body><body>hello</body> </html>&#xff08;但是有乱码&#xff09; …

【C#】C#编程入门指南:构建你的.NET开发基础

文章目录 前言&#xff1a;1. C# 开发环境 VS的基本熟悉2. 解决方案与项目的关系3. 编辑、编译、链接、运行4. 托管代码和CLR4.1 CLR&#xff1a;4.2 C# 代码第编译过程&#xff08;两次编译的&#xff09; 5. 命名空间6. 类的组成与分析7. C# 的数据类型7.1 值类型7.2 引用类型…

115页PDF | 埃森哲_XX集团信息化能力成熟度评估及能力提升方案(限免下载)

一、前言 这份报告是埃森哲_XX集团信息化能力成熟度评估及能力提升方案&#xff0c;报告首先分析了集团的战略规划&#xff0c;包括调整优化期、转型升级期和跨越发展期的目标&#xff0c;然后识别了集团面临的内部挑战和外部压力&#xff0c;如管控体系不完善、业务板块多样化…

面试时问到软件开发原则,我emo了

今天去一个小公司面试&#xff0c;面试官是公司的软件总监&#xff0c;眼镜老花到看笔记本电脑困难&#xff0c;用win7的IE打开leetcode网页半天打不开&#xff0c;公司的wifi连接不上&#xff0c;用自己手机热点&#xff0c;却在笔记本电脑上找不到。还是我用自己的手机做热点…

Wi-Fi背后的工作原理与技术发展历程介绍【无线通信小百科】

1个视频说清楚WIFI&#xff1a;频段/历程/技术参数/常用模块 智能手机拥有率越来越高的今天&#xff0c;大家已经习惯了通过无线网络上网的方式。除了在外面需要用手机流量&#xff0c;我们通常在家里或者机场&#xff0c;商场都可以通过Wi-Fi连接上网。本期文章将为大家介绍Wi…

【MySQL 保姆级教学】详细讲解视图--(15)

视图 1. 为什么要有视图&#xff1f;2.视图的定义和特点3. 创建视图4. 视图的使用举例4.1 创建表并插入数据4.2 举例 5. 视图和基表之间有什么联系呢&#xff1f; 1. 为什么要有视图&#xff1f; 当我们频繁地使用用多表查询和复合查询出的结果时&#xff0c;就需要频繁的使用…

Python中的HTTP协议

文章目录 一. 网址URL二. HTTP协议1. HTTP协议的概念2. HTTP协议的作用3. HTTP请求报文与响应报文① HTTP请求报文Ⅰ. GET请求报文格式Ⅱ. GET请求报文分析Ⅲ. POST请求报文格式Ⅳ. POST请求报文分析Ⅴ. GET与POST请求报文总结 ② HTTP响应报文Ⅰ. HTTP响应报文格式Ⅱ. HTTP响应…

108. UE5 GAS RPG 实现地图名称更新和加载关卡

在这一篇里&#xff0c;我们将实现对存档的删除功能&#xff0c;在删除时会有弹框确认。接着实现获取玩家的等级和地图名称和存档位置&#xff0c;我们可以通过存档进入游戏&#xff0c;玩家在游戏中可以在存档点存储存档。 实现删除存档 删除存档需要一个弹框确认&#xff0…

DNS批量解析管理软件有什么用

在复杂的网络环境中&#xff0c;DNS批量解析管理软件犹如一把功能强大的钥匙&#xff0c;开启了高效网络管理的大门&#xff0c;为网络运营和维护带来了诸多便利。 1、对于网络服务提供商而言&#xff0c;DNS批量解析管理软件极大地提高了工作效率 传统的DNS解析管理方式在处…

IoT [remote electricity meter]

IoT [remote electricity meter] 物联网&#xff0c;远程抄表&#xff0c;电表数据&#xff0c;举个例子

sql数据库-排序查询-DQL

目录 语法 排序方式 举例 将表按年龄从小到大排序 将表按年龄从大到小排序 ​编辑 多重排序 将表按年龄升序&#xff0c;年龄相同按入职时间降序 语法 select * from 表名 order by 字段名1 排序方式1&#xff0c;字段2 排序方式2; 排序方式 升序&#xff1a;ASC&…

在spring boot工程中使用Filter时,@WebFilter 注解不生效的问题分析和解决方案

1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中&#xff0c;通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建&#xff0c;代码如下。 import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import org.springframework.st…

学习threejs,使用TWEEN插件实现动画

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PLYLoader PLY模型加…

TypeScript在现代前端开发中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 TypeScript在现代前端开发中的应用 TypeScript在现代前端开发中的应用 TypeScript在现代前端开发中的应用 引言 TypeScript 概述…

CTF-Crypto-简单加密

打开首页看题目 描述看起来是一段乱码&#xff0c;拉入随波逐流&#xff0c;未解决 e6Z9i~]8R~U~QHE{RnY{QXg~QnQ{^XVlRXlp^XI5Q6Q6SKY8jUAA 观察字符串&#xff0c;末尾是AA&#xff0c;其中可能含有base64加密 找寻Ascll码表&#xff0c;发现A的Ascll是65&#xff0c;的Ascl…

MacOS下,如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能

MacOS下&#xff0c;如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能 在Mac上的Safari浏览器中&#xff0c;可以通过实况文本功能来实现图片中的文本翻译。关闭步骤具体步骤如下&#xff1a; 在浏览器地址栏&#xff0c;鼠标右击翻译按钮&#xff0c;然后点击“首选…