0%

1. 为什么需要优化?

MongoDB 虽然灵活,但如果不加优化,可能出现:

  • 查询性能低(扫描全表)

  • 分片热点(某一分片压力过大)

  • 内存占用高(缓存无效)

  • 写入延迟大(锁竞争)

优化的核心目标是:减少扫描量,减少锁竞争,充分利用索引与缓存

阅读全文 »

1. 聚合(Aggregation Framework)

聚合是 MongoDB 中最强大的分析与数据处理工具,相当于 SQL 中的 GROUP BYJOINWHEREORDER BY 等组合。

1.1 聚合管道的基本原理

MongoDB 的聚合是一个数据流管道:

1
输入文档  →  $match$group$sort$project  →  输出结果

每个阶段都会对数据进行筛选、计算、排序或重塑。

阅读全文 »

1. 什么是 MongoDB?

MongoDB 是一种 面向文档的 NoSQL 数据库,与传统的关系型数据库(MySQLPostgreSQL)不同,它不使用表格和行,而是使用 BSON(二进制 JSON)存储数据。
简单来说,它是一个 JSON 存储与查询引擎

MongoDB 的核心特性:

  • 文档型存储:每条数据是一个 JSON 对象。

  • 无固定模式(Schema-less):字段可以灵活增加或减少。

  • 高扩展性:支持分片(Sharding)与副本集(Replica Set)。

  • 强大的查询语言:支持聚合(Aggregation)、全文检索(Full-Text Search)。

  • 天然适合大数据与高并发场景

阅读全文 »

一、什么是 Makefile

Makefile 是为 make 命令准备的脚本文件,它描述了项目中文件之间的依赖关系以及如何编译它们。它允许你只输入一条命令 make,即可自动编译项目中所有需要更新的部分。

二、Makefile 基本语法

最基本的格式如下:

1
2
目标: 依赖
命令
阅读全文 »

1. 找到sysent

1. find_kernel_base

    #define MACH_KERNEL_BASE 0xFFFFFE0007004000 // macOS 内核文件的基地址 for "/System/Library/Kernels/kernel.release.t8101"
    使用 vm_kernel_unslide_or_perm_external 找到 kernel_slide
    base_address = kernel_slide + MACH_KERNEL_BASE

完整调用流程

sequenceDiagram
    participant UserSpace as 用户空间程序
    participant IOKit as IOKit框架
    participant Driver as 内核驱动
    participant UserClient as UserClient实例

    Note over UserSpace,UserClient: 阶段1:服务发现
    UserSpace->>IOKit: IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &iterator)
    IOKit->>Driver: 内核遍历服务列表
    Driver-->>IOKit: 返回匹配的服务对象
    IOKit-->>UserSpace: 通过iterator返回服务句柄

    Note over UserSpace,UserClient: 阶段2:建立连接
    UserSpace->>IOKit: IOServiceOpen(service, mach_task_self(), type, &connection)
    IOKit->>Driver: 调用驱动的newUserClient()

    alt 自定义newUserClient实现
        Driver->>Driver: 1. 安全检查(task_is_privileged等)
        Driver->>Driver: 2. 通过OSTypeAlloc创建UserClient
        Driver->>UserClient: initWithTask(owningTask, type...)
        UserClient-->>Driver: 返回初始化结果
        Driver-->>IOKit: 返回UserClient实例
    else 默认实现
        IOKit->>UserClient: 自动创建标准UserClient
        UserClient->>UserClient: 默认initWithTask()
        UserClient-->>IOKit: 返回实例
    end

    IOKit-->>UserSpace: 返回connection句柄

    Note over UserSpace,UserClient: 阶段3:命令交互
    loop 多次调用
        UserSpace->>UserClient: IOConnectCallMethod(connection, selector, ...)
        UserClient->>UserClient: 根据sMethods分派到具体方法
        UserClient->>Driver: 调用驱动方法(如performCalculation)
        Driver-->>UserClient: 返回数据/状态
        UserClient-->>UserSpace: 返回结果
    end

    Note over UserSpace,UserClient: 阶段4:断开连接
    UserSpace->>UserClient: IOServiceClose(connection)
    UserClient->>UserClient: clientClose()
    UserClient->>Driver: 通知驱动(可选)
    UserClient->>UserClient: 释放资源

IODataQueueMemory

用户层代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void ControllerImpl::MsgRecvThreadFunc() {
kern_return_t kr;
UInt32 dataSize;
IODataQueueMemory* queueMappedMemory;
vm_size_t queueMappedMemorySize;
mach_vm_address_t address = 0;
mach_vm_size_t size = 0;
mach_port_t recvPort;
TestMessage msg;

// allocate a Mach port to receive notifications from the IODataQueue
if ((recvPort = IODataQueueAllocateNotificationPort()) == MACH_PORT_NULL) {
return;
}

// this will call registerNotificationPort() inside our user client class
kr = IOConnectSetNotificationPort(m_nConnection, QUEUETYPE_MONITOR, recvPort, 0);
if (kr != kIOReturnSuccess) {
mach_port_destroy(mach_task_self(), recvPort);
return;
}

// this will call clientMemoryForType() inside our user client class
kr = IOConnectMapMemory(m_nConnection, kIODefaultMemoryType, mach_task_self(), &address, &size, kIOMapAnywhere);
if (kr != kIOReturnSuccess) {
mach_port_destroy(mach_task_self(), recvPort);
return;
}

queueMappedMemory = (IODataQueueMemory*)address;
queueMappedMemorySize = size;

while (!m_bStop && IODataQueueWaitForAvailableData(queueMappedMemory, recvPort) == kIOReturnSuccess) {
while (!m_bStop && IODataQueueDataAvailable(queueMappedMemory)) {
dataSize = sizeof(msg);
kr = IODataQueueDequeue(queueMappedMemory, &msg, &dataSize);
if (kr != kIOReturnSuccess) {
continue;
}

Callback(msg);

} // end while (IODataQueueDataAvailable(queueMappedMemory))
} // end while (IODataQueueWaitForAvailableData

exit:

kr = IOConnectUnmapMemory(m_nConnection, kIODefaultMemoryType, mach_task_self(), address);
if (kr != kIOReturnSuccess) {
}

mach_port_destroy(mach_task_self(), recvPort);

}

什么是 macOS 内核扩展(KEXT)?

macOS 内核扩展是一种动态链接库(通常后缀为 .kext),用于扩展 XNU 内核的功能。KEXT 可被用于编写驱动程序、系统安全模块、文件系统支持等底层功能。

macOS Catalina(10.15)之后,Apple 推出 System ExtensionsDriverKit,逐步替代传统 KEXT,但 KEXT 仍广泛用于底层研究和安全相关开发。

阅读全文 »

HTTPS 通信中,浏览器如何判断一个网页使用的证书是否已经 吊销Revoked)?证书一旦吊销,就意味着它已不再可信,但如何通知用户浏览器,是一个非常关键的安全机制。

本篇文章将全面梳理浏览器判断证书吊销状态的几种主流机制,及其优缺点和实际表现。

阅读全文 »

什么是 security?

macOS 系统中,security 命令是一个强大的工具,可以让你管理密钥链(Keychain)中的敏感信息,如密码、证书、私钥等。


阅读全文 »

什么是 codesign?

codesignmacOSiOS 开发中用于代码签名的核心命令行工具,它确保应用程序的来源可信且未被篡改。无论是发布到 App Store 还是独立分发,代码签名都是必经流程。


阅读全文 »