0%

什么是TLS False Start?

TLS 协商第二阶段,浏览器发送 ChangeCipherSpecFinished 后,立即发送加密的应用层数据,而无需等待服务器端的确认。

如何启用TLS False Start?

  • 需要支持 NPN/ALPN
  • 服务器端配置支持前向安全(Forward Secrecy)

Introduction

ALPN(Application-Layer Protocol Negotiation)应用层协议协商, 当单个服务器端口号(例如端口 443)上支持多个应用程序协议时,客户端和服务器需要协商用于每个连接的应用程序协议。希望在不增加客户端和服务器之间的网络往返次数的情况下完成此协商,因为每次往返都会降低最终用户的体验。

ALPN 作为 TSL的扩展,客户端会将支持的应用程序协议列表作为 TLS ClientHello 消息的一部分发送给服务器,服务器选择一个协议,并将所选协议作为 TLS ServerHello 消息的一部分发送给客户端。因此,可以在 TLS 握手中完成应用协议协商,而无需添加网络往返,并且允许服务器根据需要,将不同的证书与每个应用协议相关联。

阅读全文 »

背景

高级语言经过编译器将源码转为机器指令运行,其中的运行顺序和代码中的顺序有很大差异,主要是下面三个原因:

  • 编译器重排
  • CPU 乱序执行
  • 存储器硬件设计,不同线程看到的顺序不一致。

c++ 中线程同步只有两种方式:

  • 原子变量进行同步
  • 锁(Mutex)

这里我们主要讨论原子变量的操作。

Memory Order

C++11 规定了六种不同的 memory order:

  • Relaxed
  • Consume
  • Acquire
  • Release
  • Acquire-Release
  • Sequential Consistent
    阅读全文 »

joindetach

  • join 或者 detach 只能调用一次

    当调用 join 或者 detach 之后会将持有的线程ID置为 0, 再次调用会抛异常。

    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
    void
    thread::join()
    {
    int ec = EINVAL;
    if (!__libcpp_thread_isnull(&__t_))
    {
    ec = __libcpp_thread_join(&__t_);
    if (ec == 0)
    __t_ = _LIBCPP_NULL_THREAD;
    }

    if (ec)
    __throw_system_error(ec, "thread::join failed");
    }

    void
    thread::detach()
    {
    int ec = EINVAL;
    if (!__libcpp_thread_isnull(&__t_))
    {
    ec = __libcpp_thread_detach(&__t_);
    if (ec == 0)
    __t_ = _LIBCPP_NULL_THREAD;
    }

    if (ec)
    __throw_system_error(ec, "thread::detach failed");
    }
阅读全文 »

Grid

fr

1
2
3
grid-template-columns: 1fr, 1fr, 1fr, 1fr;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: 1fr, 1fr, 1fr, auto;

grid-column

1
2
3
4
grid-column: 1
grid-column: 1 / 4;
grid-column: 1 / span 3;
grid-column: 1 / -1;

文档主键

文档主键 _id

文档主键 _id 是每篇文档必备的字段,具有以下特性:

  • 文档主键的唯一性
  • 支持所有数据类型(数组除外)
  • 复合主键

对象主键 ObjectId

当我们不提供主键,MongoDB 自动为我们生成的默认对象主键 ObjectId

  • 默认的文档主键
  • 可以快速生成的 12 字节 id
  • 包含创建时间

ObjectId 默认值

1
2
test> ObjectId()
ObjectId("64eeed51b64b9d7e95e6b8ea")

手动设置 ObjectId 的值

1
2
test> ObjectId("123456789011123456789011")
ObjectId("123456789011123456789011")

提取 ObjectId 的创建时间

1
2
test> ObjectId("123456789011123456789011").getTimestamp()
ISODate("1979-09-05T22:51:36.000Z")
阅读全文 »

索引

  • 对文档部分内容进行排序的数据结构
  • 加快文档查询和文档排序的速度
  • 复合键索引只能支持前缀子查询

索引操作

创建索引

1
db.<collection>.createIndex(<keys>, <options>)
  • <keys> 文档指定了创建索引的字段
  • <options> 创建索引的参数和设定索引的特性

创建一个单键索引

1
db.accountWithIndex.createIndex({name: 1})

创建一个复合键索引

1
db.accountWithIndex.createIndex({name: 1, balance: -1})

创建一个多键索引,创建在数组字段上, 数组字段中的每一个元素都会在多键索引中创建一个键

1
db.accountWithIndex.createIndex({currency: 1})

列出集合中的索引

1
2
db.accountWithIndex.getIndexes()

阅读全文 »

macOS 上,动态链接器使用特定的路径变量来解析运行时的库位置。这些路径变量包括:绝对路径、 @executable_path@loader_path@rpath

绝对路径

对于安装在系统中共享位置的框架很有用,一般是 /Library/Frameworks/xxx/usr/lib/xxx, 但是查找嵌入在应用内部的动态库就很难使用,应用安装的位置都不固定,所以引出新的方式。

@executable path

@executable_path 是用于指代当前正在执行的程序或应用的路径。当你的应用程序或其动态库需要引用位于与可执行文件相同路径(或其子目录)下的其他动态库时,这会非常有用。

阅读全文 »