Thrift 与 Protocol Buffers

每个字段一个标记号码,字段名可以随意调整因为编码信息中只有标记号码,没有字段名称,但是标记号码不能随意调整,基于此可以实现: 向前兼容 旧代码忽略不能识别的标记号码,并根据类型的注释来通知解析器跳过特定的字节数。 向后兼容 标记号码不变的情况下新的代码总是能够解析旧代码序列化的数据,但是新添加的字段不能标记为 required,不然会触发运行时错误。 同时为了保证前后兼容,删除字段也不能删除设置为 required 的字段,同时再次新添字段标记号码不能被再次使用。 改变类型同时也会导致前后兼容问题。

June 10, 2021 · 1 min · Gray King

数据编码与演化

模式演化要保证: 向后兼容 较新的代码可以读取旧代码编写的数据 向前兼容 较旧的代码可以读取较新代码编写的数据 数据编码格式 语言特定格式 Python pickle Java java.io.Serializable Ruby Marshal JSON、XML与二进制变体 二进制变体 Message Pack:二进制的 JSON Thrift 与 Protocol Buffers Avro 数据流模式 基于数据库的数据流 不同是写写入不同的值 归档存储 基于服务的数据流:REST 和 RPC RPC 的问题 给人一种本地调用的错觉,却需要面临网络的不确定性:延迟和超时。 基于消息传递的数据流 消息中间件:RabbitMQ、Kafka 分布式Actor 框架:Akka、Erlang OTP

June 10, 2021 · 1 min · Gray King

OLAP

在线分析处理(Online Analytic Processing,OLAP)。

June 10, 2021 · 1 min · Gray King

OLTP

在线事务处理(Online Transaction Processing,OLTP)。

June 10, 2021 · 1 min · Gray King

B-trees

B-tree 是最广泛使用的索引结构。和排序字符串表:SSTables一样,B-tree 保留按键排序的 key-value 对, 这样可以实现高效的 key-value 查找和区间查询。 结构 B-tree 将数据库分解成固定大小的页或块,传统上 4KB,这种设计更接近底层硬件,磁盘也是以固定大小的块排列的。 分页因子 B-tree 中一个页所包含的子页引用数量称为分支因子。 添加新键 找到其范围新键的页 如果页没有足够的可用空间来容纳新键,则将其分裂为两个半满的页,并更新父页以包含新的键范围。 算法确保树保持平衡:具有 n 个键的 B-tree 总是具有 \(O(log n)\) 的深度。大多数据库适合 3~4 层的 B-tree。 分支因子为 500 的 4KB 页的四级树可以存储高达 256TB。 可靠性:WAL B-tree 底层的基本写操作是使用新的数据覆盖磁盘上的旧页。 如果发生页分裂则需要覆盖多个不同的页,同时更新父页,这个操作比较危险,如果此时发生崩溃则会破坏索引。 常见的 B-tree 使用额外的数据结构:预写日志(WAL): 追加的写 WAL; 每个 B-tree 必须先更新 WAL 然后再修改树本身的页。 通过使用「锁存器」保护进行并发控制,保护 B-tree 页被多个线程访问而看到树不一样的状态。 优化 通过复制方案替代 WAL 进行崩溃恢复,修改的页被写入不同的位置,树中父页的新版本被创建,并指向新的位置。 保存键的缩略信息,可以压入更多的键,保持更高的分支因子,减少层数。 对树进行布局,相邻叶子页按顺序保存在磁盘。 添加额外的指针到树中,如左右兄弟页。 变体,如分形树:借鉴日志结构减少磁盘寻道。

June 6, 2021 · 1 min · Gray King

哈希索引

索引 先来看一个世界上由 Bash 实现的最简单的数据库实现: #!/bin/bash db_set() { echo "$1,$2" >> database } db_get() { grep "^$1," database | sed -e "s/^$1,//" | tail -n 1 } 这种数据库通过追加文件尾部的方式高效写入,许多数据库内部都是用日志,日志是一个仅支持追加更新的数据文件。但是 db_get 的性能会随着数据量的变大而下降,为了解决这个问题就需要引入新的数据结构: 索引 。 索引是基于原始数据而派生而来的额外数据结构:适当的索引可以加速读取查询,但是回减慢写速度。 key-value 索引通常使用 hash map 来实现,最简单的索引策略:保存内存中的 hash map,把每个键一一映射到数据文件中特定的字节偏移量。 优化磁盘占用 将日志分解成一定大小的段,当文件达到一定大小时就关闭它,并将后续写入到新的段文件中。 然后可以在这些段上执行压缩:丢弃重复的键,并且只保留每个键最近的更新。 同时将变小后的多个段在后台合并在一起(段在写入后不再会进行修改所以不会出现竞争)。 合并完成后将读取请求切换到新的合并段上,然后可以安全的删除旧的段文件。 实现中面临的问题 文件格式:二进制。 删除记录:通过特殊的墓碑标记。 崩溃恢复:Bitcask 通过将 hash map 快照存储到磁盘。 部分写入:文件校验丢弃损坏的部分。 并发控制:只有一个写线程。 追加的好处 顺序写性能高。 并发控制和崩溃恢复简单。 段合并避免文件碎片化。 局限性 大量的键存储在内存可能导致内存耗尽,同时需要处理哈希冲突 区间查询效率不高。

June 6, 2021 · 1 min · Gray King

排序字符串表:SSTables

SSTables 通过按照键的顺序存储在日志段文件中来解决哈希索引面临的一些问题。它要求每个键在每个合并的段文件中只能出现一次(通过压缩确保)。 对比哈希索引的日志段 优点 合并段更加高效,即使文件大于可用内存。类似于归并排序算法中使用的方法。并发读取多个输入段文件,比较每个文件的第一个键,把最小的键拷贝到输出文件,并重复。 解决多个段文件重复:保留最新的值,因为每个段包含在某段时间内写入数据库的所有值,意味着肯定有一个值比其他所有值更新。 基于键有序的特性可以采用稀疏索引避免内存中包含所有键的索引。 将一定范围内的所有键存储到一个块中,便于需要请求范围内多个 key-value,降低磁盘 I/O。 构建和维护 保证顺序 内存中痛哦红黑树或者 AVL 树支持任意顺序插入并以排序后的顺序读取它们。 写入时,将其添加到内存中的平衡树数据结构中,成为内存表。 内存表大于某个阈值(MB级别),将其作为 SSTable 文件写入磁盘。写入同时,写入可以继续添加到一个新的内存表实例中。 处理请求顺序:首先从内存表中查找键 -> 最新的磁盘段文件 -> 次新磁盘段文件,以此类推。 后台进程周期性执行段合并与压缩,合并多个段文件并丢弃被覆盖或着删除的值。 崩溃处理 为了避免数据库崩溃最近的写入(在内存表中尚未写入磁盘)将会丢失的问题: 在磁盘上保留单独的日志,每个写入都会立即追加到该日志。并且无需排序。 内存表写入 SSTable 时,丢弃相应的日志。 使用此技术的数据库 LevelDB RocksDB 类似的 Cassandra HBase

June 6, 2021 · 1 min · Gray King

LSM-Tree

tags: Tree 日志结构合并树(Log-Structured Merge-Tree):基于合并和压缩排序文件原理的存储引擎通常都被称为 LSM 存储引擎。 压缩排序文件基于排序字符串表:SSTables。 LSM-Tree 基本思想:保存在后台并合并的排序字符串表:SSTables。即使数据集远远大于可用内存,仍然能够正常工作。 基于有序的特性,可以有效的执行区间查询,并且由于磁盘是顺序写入,所以 LSM-Tree 可以支持非常高的写入吞吐量。 性能优化 通过布隆过滤器优化 LSM-Tree 查找不存在的键性能低下的问题。 通过大小分级和分层压缩优化 SSTables 压缩和合并时的具体顺序和时机。 大小分级:较新和较小的 SSTables 被连续合并到较旧和较大的 SSTables。 分层压缩:键的范围分裂成多个更小的 SSTables,就数据被移动到单独的“层级”,这样压缩可以逐步进行并节省磁盘空间。

June 6, 2021 · 1 min · Gray King

数据存储与检索

存储引擎 哈希索引 日志结构存储引擎:LSM-Tree 面向页的存储引擎:B-trees 对比 LSM-Tree 和 B-trees 项目 LSM-Tree B-trees 备注 性能 写入更快,吞吐更高 读取更快 具体场景上需要进行基准测试 存储 可变大小的段,通常 nMB 固定大小的页,传统 4KB 写入 追加,写入更多不利于 SSD 新的数据覆盖磁盘上旧的页 并发控制 后台合并进行原子替换 锁存器 其他索引结构 在索引中存储值 多列索引 全文索引和模糊索引 在内存中保存所有内容 优点:可以支持更复杂的数据结构,而无需考虑数据存储结构。 事务处理与分析处理 事务处理:OLTP 分析处理:OLAP 对比 属性 OLTP OLAP 主要读属性 基于键,每次查询返回少量记录 对于大量记录进行汇总 主要写属性 随机访问,低延迟写入用户的输入 批量导入(ETL)或事件流 典型使用场景 终端用户,通过网络应用程序 内部分析师,为决策提供支持 数据表征 最新的数据状态(当前时间点) 随着事件而变化的所有事件历史 数据规模 GB 到 TB TB 到 PB 数据仓库 星型与雪花型分析模式 星型模型也称为维度建模。 列式存储 列压缩

June 6, 2021 · 1 min · Gray King

数据模型与查询语言

数据模型 关系模型 突出数据之间的关联。 文档模型 数据来自于包含文档,文档间关联很少。 图状数据模型 针对所有数据都可能互相关联。 数据查询语言 Web 上声明式查询 CSS 选择器。 MapReduce 查询 MapReduce 是一种编程模型,用于在许多机器上批量处理海量数据。 MongoDB 中的 MapReduce db.observations.mapReduce( function map() { // 2 var year = this.observationTimestamp.getFullYear(); var month = this.obbservationTimestamp.getMonth() + 1; emit(year + "-" + month, this.numAnimals); // 3 }, function reduce(key, values) { // 4 return Array.sum(values); // 5 }, { query: {family: "Sharks"}, // 1 out: "monthlySharkReport" // 6 } ); 过滤器声明式执行鲨鱼种类(MongoDB 特有扩展)。 mapper:对于每个匹配的文档都会调用一次这个 JavaScript 函数。 mapper 发射一个「键-值」对,键是 “2013-12” 格式的字符串,值是动物的数量 mapper 发射的键值对按键分组,对于相同键的所有「键-值」对,调用 reduce 函数。 reducer 函数将特定月份的所有观察到的动物数量相加。 最终输出写入到 monthlySharkReport 集合中

June 6, 2021 · 1 min · Gray King

可靠、可扩展与可维护的应用系统

可靠性 故障与失效 故障(faults)或者错误:组件偏离其正常规格,可以提供容错(fault-tolerant)机制 失效(failure)意味系统作为一个整体停止 硬件故障 软件错误 人为失误 避免优化方式: 以最小出错方式设计系统。抽象、提供管理界面,使“做正确的事很轻松”,防止限制过多。 分离最容易出错的地方,提供沙箱用以放心尝试。 充分测试。 提供快速恢复机制尽量减少故障影响:快速回滚,提供校验数据的工具。 设置详细而清晰的监控系统 培训和流程 可扩展性 描述负载 QPS 数据库写入比例 同时在线活动用户数 缓存命中率等。 描述性能 吞吐量(throughput)/每秒处理数据量 延迟(latency)/响应时间(response time):延迟是处理时间,响应时间是客户端看到的。 最好通过百分位数来监控指标:p50/p80/p90/p95/p99/p999,p50 指标表示一半请求在这个指标之下,一半在这个指标之上。 应对负载增加 无状态很方便扩容 但有状态的分布式面临一定的挑战 可维护性 可运维性:运维更轻松 监控、文档、自动化、良好的默认配置、可手动控制系统状态让系统自我修复(比如熔断机制)。 简单性:简化复杂度 抽象! 可演化性:易于改变 TDD 重构

June 4, 2021 · 1 min · Gray King

《数据密集型应用系统设计》读书笔记

tags: 读书笔记,Bigdata,分布式,数据库 数据系统基础 可靠、可扩展与可维护的应用系统 数据模型与查询语言 数据存储与检索 数据编码与演化 分布式数据系统 目的:扩展性、容错和高可用、延迟考虑(多机房) 扩展: 垂直扩展:提升单机性能 水平扩展:无共享结构,由软件实现核心逻辑 复制与分区: 复制:多节点冗余 分区:数据库拆分 分片:分区分配给不同的节点 数据复制 数据分区 事务 分布式系统挑战 一致性与共识 派生数据 记录系统:真实数据系统,拥有数据的权威版本。 派生数据系统:从另一个数据系统获取,丢失可以根据数据源重建,如缓存等。 批处理系统 流处理系统

June 4, 2021 · 1 min · Gray King

项目代号

tags: 技术随想 几何结构 mobius Klein Trefoil knot Penrose triangle 植物 bonsai broccoli 科幻 tardis dalek 消灭 神话

May 25, 2021 · 1 min · Gray King

macOS 问题解决三板斧

tags: macOS,macOS Cheatsheet 通常你沟通苹果的官方支持一般都会给你三板斧: 重启:按住电源键 10 秒中,然后等几秒钟后再开机 重置 SMC:关机然后按住:Ctrl + Option + 右侧Shift + 电源键 7 秒钟关机,等待几秒钟后开机。

March 22, 2021 · 1 min · Gray King

macOS TimeMachine 日志

tags: macOS 查看 TimeMachine 日志: printf '\e[3J' && log show --predicate 'subsystem == "com.apple.TimeMachine"' --debug --last 6m

March 22, 2021 · 1 min · Gray King

English IPA

tags: Learning English 一些通用的规则: 音标后面的 ː 提示拖长音。 元音 大而圆 音标 中文 发音技巧 常见单词 拼读规则 /​æ​/ 爱 张大嘴发中文的「爱」,发音短促有力。 bag map dad sad a /​e​/ 爱 音同 /​æ​/ 但是嘴形要小一些。 get let pen yes e /​ɔː​/ 哦 嘴巴轮圆了发音,并拖长音 floor door store sport oor,ore,or /​ɔ​/ 哦 /​ɔː​/ 的短音 lot dog hot shop o 扁扁扁 音标 中文 发音技巧 常见单词 拼读规则 /iː​/ 一 相比一嘴要扁一些,稍稍更用力一些 see meet he she ee, e /​i​/ 一 /iː​/ 短音 happy daddy honey 词尾的 y 或 ey /​I​/ 一 用 /​e​/ 的嘴形发 /​i​/ this give it city i /əː​/ 呃 相比中文嘴要扁一些,稍稍更用力一些 work girl dirt sir or, ir /​ə​/ 呃 /əː​/ 的短音 again a father weather 单独的 a 及词尾的 er 需要额外注意的: ...

March 17, 2021 · 2 min · Gray King

二叉树的遍历

tags: Algorithm,Data Structures,Binary Search Tree 分为三种:前序、后序和中序,其中最容易用栈改写的是后序。 前序(Preorder):Root -> Left -> Right class Solution { public: void processPreorderTraversal(TreeNode* root, vector<int> & collector) { if (root == nullptr) { return; } processPreorderTraversal(root->left, collector); collector.push_back(root->val); processPreorderTraversal(root->right, collector); } vector<int> inorderTraversal(TreeNode* root) { vector<int> ret; if (root == nullptr) { return ret; } processPreorderTraversal(root, ret); return ret; } }; 中序(Inorder): Left -> Root -> Right class Solution { public: void processInorderTraversal(TreeNode* root, vector<int> & collector) { if (root == nullptr) { return; } processInorderTraversal(root->left, collector); collector.push_back(root->val); processInorderTraversal(root->right, collector); } vector<int> inorderTraversal(TreeNode* root) { vector<int> ret; if (root == nullptr) { return ret; } processInorderTraversal(root, ret); return ret; } }; 后序(Postorder):Left -> Right -> Root class Solution { public: void processPostorderTraversal(TreeNode* root, vector<int> & collector) { if (root == nullptr) { return; } processPostorderTraversal(root->left, collector); processPostorderTraversal(root->right, collector); collector.push_back(root->val); } vector<int> postorderTraversal(TreeNode* root) { vector<int> ret; if (root == nullptr) { return ret; } processPostorderTraversal(root, ret); return ret; } }; 非递归遍历 【刷题】二叉树非递归遍历

February 20, 2021 · 1 min · Gray King

OX-HUGO 批量导出 Markdown

tags: Taking Notes, Org Mode 方案一:通过 Emacs 批处理模式 emacs file.org --batch -f org-hugo-export-wim-to-md --kill --batch 默认不启用配置文件,可以使用 -l emacs file.org --batch -l ~/.emacs.d/init.el -f org-hugo-export-wim-to-md --kill 方案二:通过 LISP 遍历 (mapc (lambda (x) (with-current-buffer (find-file-noselect x) (org-hugo-export-wim-to-md t))) (directory-files "/Users/wh/codes/notes/roam-research-notes-hugo/journal" nil "^[0-9]+$" t))

February 20, 2021 · 1 min · Gray King

中间件

tags: 技术,技术概念 中间件可以对系统进行解耦,比如上层系统对下层系统进行网络请求,考虑下面结构 - U - / | \ /--- | ---\ / | \ A B C 如果下层系统增加节点的话就需要重启 U。 引入 HAProxy 或者 Nginx 之类的中间件可以对两层系统进行解耦: U | +------+ | HA | +------+ / | \ /--- | ---\ / | \ A B C 这样上层和下层系统都依赖中间件,但是系统之间不再强耦合,下层系统可以依赖中间件随意的进行所扩容而不用被上层系统感知。 这时候中间件只要保证中间件稳定即可,可以在中间件上进行热重启。

February 20, 2021 · 1 min · Gray King

技术随想

项目代号 技术概念

February 20, 2021 · 1 min · Gray King

C/C++ thread-local storage

tags: C/C++ source: All about thread-local storage

February 19, 2021 · 1 min · Gray King

macOS max open files

tags: macOS fix “Too many open files in system” error

January 25, 2021 · 1 min · Gray King

GDB 打出所有线程的 Backtrace

tags: GDB thread apply all bt

January 18, 2021 · 1 min · Gray King

C++ LSP

tags: Emacs,LSP,C/C++,CMake 通过如下命令生成 clangd 识别的编译配置文件 mkdir build cd build cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. mv compile_commands.json ../ 然后重启 M-x lsp-restart-workspace RET 即可。

January 14, 2021 · 1 min · Gray King

Python behind the scenes #2: how the CPython compiler works

tags: Translate,Incomplete,Python Python 幕后 #2: CPython 编译器如何工作 今天的主题(Today’s subject) 在本系列的第一篇文章中我们研究了 Python 虚拟机。我们学了解到它通过执行一系列叫做字节码(bytecode)的指令。 我们也看到 Python 字节码没有完全描述代码片段的行为。这也是为什么存在一个代码对象(code object)的概念。 执行诸如函数或模块的代码块也就是执行对应的代码对象。代码对象包含了代码块的字节码,包含代码中使用的常量和变量名, 还有代码块的一些属性。 通常,一个 Python 程序员不用编写字节码,并且也不用创建代码对象,而是编写正常的 Python 代码。所有 CPython 必须 能够将源代码转换成代码对象。CPython 编译器就负责这部分工作。我们将通过这部分内容探索它是如何工作的。 Note: 本文参考 CPython 3.9。一些实现细节将必然会随着 CPython 的演进而改变。 我将会尝试关注一些重要的改变并添加更新备注。 什么是 CPython 编译器(What CPython compiler is) 我们已经了解了 CPython 编译器的职责,但是在我们进入到它是如何实现的之前,让我们首先来搞清楚为什么我们称之为编译器? 在通常情况加,编译器是一个将一个程序语言翻译到另一个与之等价的程序语言的程序。编译器有许多种类,但是通常情况下我们 讨论的都是静态编译:将一个高级语言的程序翻译成机器码。CPython 编译器也是这样吗?要回答这个问题,我们先看一下静态编 译器的传统三阶段设计(three-stage design)。 编译器前端(frontend)将源代码转换成一种中间语言(IR,intermediate representation)。然后优化器(optimzer)拿到中间语言 对其进行优化并把优化过的中间语言传递给编译器后端生成机器码。如果我们选择一种源语言和目标机器无关的中间语言,我们就 得到了三阶段设计的关键益处:对于一个编译器来说,支持一种新的源语言仅仅需要新增一个对应的编译器前端,支持一种新的目标机器 仅仅需要新增一个对应的编译器后端。 LLVM 工具集(toolchain)就是这个模型的一个很好的成功的例子。有很多编译器前端如 C、Rust、Swift 等其他很多编程语言基于 LLVM 提供给编译器更加复杂的部分。LLVM 的创建者 Chris Latter 提供了一个很好的 LLVM 架构概览。 CPython 尽管不需要支持多个源语言和目标机器,尔仅仅需要支持 Python 代码和 CPython 虚拟机。不过,CPython 同样实现了三阶段设计。 如果想知道为什么,我们需要更加详细的解释编译器的三阶段的每个阶段。 ...

October 15, 2020 · 5 min · Gray King

straight.el 命令

tags: Emacs M-x straight-thaw-versions RET 恢复到锁定的版本 M-x straight-pull-all RET 更新所有包 M-x straight-freeze-versions RET 锁定当前版本 Duplicated with straight.el 更新所有已安装的包

October 6, 2020 · 1 min · Gray King

straight.el 更新所有已安装的包

straight-thaw-versions straight-pull-all straight-freeze-versions

October 6, 2020 · 1 min · Gray King

Emacs Buffer 名字去重

tags: Emacs source: https://www.gnu.org/software/emacs/manual/html%5Fnode/emacs/Uniquify.html

September 27, 2020 · 1 min · Gray King

范数(norm)

具有“长度”概念的函数。在线性代数、泛函分析等相关数学领域,是一个函数,其为向量空间内所有向量赋予非零的正长度或大小。

September 12, 2020 · 1 min · Gray King

MAE(平均绝对误差)

\[MAE(X,h) = \frac{1}{m}\sum_{i=1}^{m}\left\lvert h(x^{(i)} - y ^{i})\right\rvert\]

September 12, 2020 · 1 min · Gray King

RMSE(均方根误差)

测量预测过程中的预测错误的标准差。 公式 \[RMSE(X,h)=\sqrt{\frac{1}{m}\sum_{i=1}^{m}(h(x^{(i)}) - y^{(i)})^2}\] m 是你在测量 RMSE 时,所使用的数据集中实例的数量 \(x^{(i)}\) 是数据集中第 \(i\) 个实例的所有特征值的向量(标签特征除外),\(y{(i)}\) 是标签(也就是我们期待该实例的输出值) X 是数据集中所有实例所有特征值的矩阵(标记特征除外)。每个实例一行,也就是说第 \(i\) 行等于 \(x^{(i)}\) 的转置矩阵1,记作 \((x^{(i)})^T\) h 是系统的预测函数,也称为一个假设。当给定系统一个实例的特征向量 \(x^{(i)}\) ,他会输出一个预测值 \(\hat{y}=h(x^{(i)})\) RMSE(X,h) 是使用假设 h 在示例上测量的成本函数。 转置运算符会将列向量转换成行向量。 ↩︎

September 12, 2020 · 1 min · Gray King

机器学习涉及数学概念

公式 RMSE(均方根误差) MAE(平均绝对误差) 概念 标准差(Std Dev) 范数 方差 皮尔逊相关系数(标准相关系数) 线性相关性

September 12, 2020 · 1 min · Gray King

Python behind the scenes #1: how the CPython VM works

tags: Translate,Python 原文链接:Python behind the scenes #1: how the CPython VM works。 Python 幕后 #1: CPython 虚拟机如何工作 介绍(Introduction) 你是否曾经好奇过当你运行 Python 代码时 python 做了些什么? $ python script.py 这篇文章将开启一个系列来尝试解答这个问题。我们将深入 Python 最流行的实现 CPython 的内部。 通过深入 CPython 的内部我们将更深一层的去理解这门编程语言本身。这也是我们这个系列的最主要的目标。 如果你熟悉 Python 并且可以阅读 C 代码,但是对 CPython 源码本身没有太多的经验, 那么你可能非常适合本系列,并且对本系列感兴趣。 什么是 CPython 并且为什么有人想学习它(What CPython is and why anyone would want to study it) 我们首先来说明一些众所周知的事情。CPython 是用 C 编写的 Python 解析器。他是 Python 语言的众多实现 的一种,其他还有诸如 PyPy、Jython、IronPython 等。CPython 的独特之处在于它是 Python 的起源、维护时间最长也是最受欢迎的。 CPython 实现了 Python,但是 Python 是什么?最简单的一个答案可能是:Python 是一门编程语言。 当正确问相同的问题,那么答案将会更加明确:什么定义了 Python?Python 不像 C 语言有正式的规范, 但是与之相近的是 Python 语言参考(Python Language Reference),它以如下内容开始: ...

September 8, 2020 · 6 min · Gray King

机器学习测试与验证

将数据分成两部分:训练集和测试集,通常使用 80% 的数据进行训练,20% 的数据用来测试。 验证集 单独分出来一个保留集合作为验证集,防止调整模型和超参数拟合测试集的最佳模型。 交叉验证 为避免验证集浪费太多数据,交叉验证将训练集分成若干个互补子集,然后每个模型都通过这些子集的不同组合来 训练,之后用剩余的子集进行验证。

September 7, 2020 · 1 min · Gray King

机器学习的主要挑战

训练数据的数量不足 训练数据不具代表性 质量差的数据 无关特征 特征工程 一个成功的机器学习项目,关键部分是提取一组好的用了训练的特征集,这个过程叫做特征工程。 特征选择 特征提取 通过手机数据创造新的特征 训练数据过度拟合 在模型的训练数据上表现良好,但是泛化时却不尽人如意。 解决方法 简化模型 收集更多的训练数据 减少训练数据中的噪声(修复数据错误和消除异常值) 正则化 通过约束模型使其更简单,并降低过度拟合风险。 超参数 通过调整超参数来调整应用正则化的程度。调整超参数是构建机器学习系统的非常重要的组成部分。 训练数据拟合不足 解决方法: 选择一个带有更多参数、更强大的模型 给学习算法提供更好的特征集 减少模型中的约束(如减少正则化超参数)

September 7, 2020 · 1 min · Gray King

机器学习系统的种类

监督式/无监督式学习 监督式学习 定义 训练数据经过标注包含素所需解决方案(标签或标记) 相关算法 K-邻近算法 线性回归 逻辑回归:广泛用于分类,输出“属于某个给定类别的概率”的值 支持向量机 决策树和随机森林 神经网络 适应场景 分类任务 预测变量 无监督式学习 定义 训练数据未经标注 相关算法 聚类算法 K-平均算法 分层聚类分析 最大期望算法 可视化和降维 主成分分析 核主成分分析 局部线性嵌入 t-分布随机临近嵌入 关联规则学习 Apriori Eclat 适应场景 通过聚类算法检测相似(层次聚类算法精度更高,可以再次细分) 可视化算法 降维:不丢失太多信息的前提下简化数据,方法之一是合并特征,过程叫做特征提取 异常检测:判断新的输入是正常还是异常,数据初筛、防作弊等 关联规则学习:发现属性之间有趣的联系 半监督式学习 大量未标记数据和少量标记数据进行学习。 强化学习 观察环境、作出选择、执行操作、并获得回报(负值则为惩罚)。 批量学习和在线学习 在数据流中进行增量学习。 批量学习 在线学习 在线学习也称为增量学习,同时支持恢复到上一状态,便于检测到性能下降及时中断和回滚。 核外学习 超大数据集超出一台计算机的主存储器,每次加载部分数据并不断重复直至完成训练。 学习率 学习率高系统迅速适应新数据,同时快速忘记老数据,学习率低则反之。 基于实例和基于模型的学习 基于实例的学习 系统完全记住学习示例,然后通过某种相似度度量方式将其泛化到新的实例。 基于模型的学习 模型选择 观察数据得出模型的过程。 衡量模型表现 定义效用函数(或适应度函数)来衡量模型有多好 定义成本函数来衡量模型有多差 线性回归通常选择成本函数来衡量线性模型的预测和训练实例之间的差距。 线性回归算法的意义所在:通过你提供的训练样本,找出最符合所提供数据的线性模型的参数,这就是训练过程。

September 7, 2020 · 1 min · Gray King

《机器学习实战》读书笔记

概览 机器学习系统的种类 机器学习的主要挑战 机器学习测试与验证 模型是观察的简化。 相关数学概念 机器学习涉及数学概念

September 5, 2020 · 1 min · Gray King

Machine Learning

scikit-learn 提供一些常见的机器学习算法 逻辑回归(Logistic Regression aka LR) 线性分类器 XGBoost 提供随机森林解决逻辑回归特征不明显的问题

September 3, 2020 · 1 min · Gray King

Rust Obscure Words for non-native English speakers

tags: Rust,Learning English unwinding

August 29, 2020 · 1 min · Gray King

Rust Asynchronous Programming

tags: Rust Future async fn 将一个代码块转换为一个 Future 对象, Future 对象维护一个状态机 Future 对象必须运行在一个 Executor 上 Executor futures::executor::block_on 阻塞当前线程直到 future 完成 // `block_on` blocks the current thread until the provided future has run to // completion. Other executors provide more complex behavior, like scheduling // multiple futures onto the same thread. use futures::executor::block_on; async fn hello_world() { println!("hello, world!"); } fn main() { let future = hello_world(); // Nothing is printed block_on(future); // `future` is run and "hello, world!" is printed } await await 异步的等待 future 完成,不阻塞当前线程,可以配合 futures::join! 可以同时 await 多个 future futures::try_join! 如果其中一个子 future 返回错误则立即返回(join! 需要等所有 future 全部返回) futures::select! 任意一个 future 完成则立即返回 async fn learn_and_sing() { // Wait until the song has been learned before singing it. // We use `.await` here rather than `block_on` to prevent blocking the // thread, which makes it possible to `dance` at the same time. let song = learn_song().await; sing_song(song).await; } async fn async_main() { let f1 = learn_and_sing(); let f2 = dance(); // `join!` is like `.await` but can wait for multiple futures concurrently. // If we're temporarily blocked in the `learn_and_sing` future, the `dance` // future will take over the current thread. If `dance` becomes blocked, // `learn_and_sing` can take back over. If both futures are blocked, then // `async_main` is blocked and will yield to the executor. futures::join!(f1, f2); } fn main() { block_on(async_main()); }

August 28, 2020 · 2 min · Gray King

Go Swagger 实现代码即文档

tags: Go 目标 当跟随这篇文章完成后将产出如下内容: 代码 http://gitlab.17zuoye.net/vgo/go-swagger-example 文档 http://swagger.17zuoye.net/?url=http%3A%2F%2F10.200.242.61%3A9090%2Fswagger.json 准备 Go1.14 及以上版本 安装 go-swagger :参见 官方文档。 接下来使用 gin 框架作为示例,如果之前没接触过可以先了解下该框架 创建一个项目 $ mkdir go-swagger-example $ cd go-swagger-example/ $ go mod init gitlab.17zuoye.net/vgo/go-swagger-example 开始使用 首先在你的 `main.go` 定义 go generate 像下面这样: //go:generate swagger generate spec -o ./swagger.yml package main func main() { println("Hello world!"); } 此时如果运行 go generate 在项目目录下就会生成一个 swagger.yml 文件: paths: {} swagger: "2.0" 使用单独的包托管 swagger 相关定义 在之前实践的过程中发现,如果在多个包中定义了相同名称的结构体会到只一个结构体覆盖另外一个结构体的定义。 所以为了解决这个问题,我把所有 swagger 相关的定义都放在同一个包下来避免相同名字的结构体。 创建 swagger/swagger.go 填充如下内容: // Package swagger defines API documentation. // // Swagger 演示后端接口 // // Schemes: http // Host: 10.200.242.35:8080 // BasePath: /api/ // Version: 0.1.0 // Contact: 王会<hui.wang.a@17zuoye.com> // // Consumes: // - application/json // // Produces: // - application/vnd.17zuoye.v1+json // // swagger:meta package swagger 上面文件通过注释来定义了一些接口相关的信息,包括: ...

August 28, 2020 · 5 min · Gray King

MySQL forget password

tags: MySQL 启动 mysqld 时加上 --skip-grant-tables 参数可以无密码进入 MySQL。

August 27, 2020 · 1 min · Gray King

MVCC

tags: MySQL https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/ 来自《高性能 MySQL》: InnoDB 在每一行都隐式的多存储两个字段: 事务更新版本 事务删除版本 当事务开始时记录这两个版本,在读取的时候根据 Undo Log 和 Redo Log 来实现隔离级别的控制。序列化隔离级别下只能通过行锁来保证。 在可重复读隔离级别下: 首先判断事务更新版本是否大于事务开始前的版本 如果大于则根据 Undo Log 进行回退实现可重复读,这样在同一事务下不管读多少遍读取到的内容都是一样的。 可重复读隔离即便下无法避免幻读:即一开始没有读取到,随着其他插入事务的提交在同一事务里执行查询又能读取到的情况。

August 27, 2020 · 1 min · Gray King

MySQL grant subnet

tags: MySQL,Network https://stackoverflow.com/a/38389851/2873718 MySQL 授权用户子网段需要使用: 172.16.0.0/255.240.0.0 而不能使用 172.16.0.0/12

August 27, 2020 · 1 min · Gray King

Network

August 27, 2020 · 0 min · Gray King

逻辑右移

位移产生的空白填上 0,会导致有符号的负数变成正数。

August 2, 2020 · 1 min · Gray King

算数右移

位移的产生的空白填上符号位。

August 2, 2020 · 1 min · Gray King

汇编

tags: Computer Systems,《深入理解计算机系统》读书笔记 程序编码 $ gcc -Og -S mstore.c # outputs mstore.s $ gcc -Og -c mstore.c # outptus mstore.o $ objdump -d mstore.o 所有以 ‘.’ 开头额行都是指导汇编器和链接器工作额伪指令。 数据格式 C 声明 Intel 数据类型 汇编代码后缀 大小(字节) char 字节 b 1 short 字 w 2 int 双字 l 4 long 四字 q 8 char* 四字 q 8 float 单精度 l 4 double 双精度 q 8 访问信息 寄存器 一个 x86-64 的中央处理单元(CPU)包含一组 16 个存储 64 位值的 通用目的寄存器 。 四字 双字 字 字节 用途 %rax %eax %ax %al 返回值 %rbx %ebx %bx %bl 被调用者保存 %rcx %ecx %cx %cl 第四个参数 %rdx %edx %dx %dl 第三个参数 %rsi %esi %si %sil 第二个参数 %rdi %edi %di %dil 第一个参数 %rbp %ebp %bp %bpl 被调用者保存 %rsp %esp %sp %spl 栈指针 %r8 %r8d %r8w %r8b 第五个参数 %r9 %r9d %r9w %r9b 第六个参数 %r10 %r10d %r10w %r10b 调用者保存 %r11 %r11d %r11w %r11b 调用者保存 %r12 %r12d %r12w %r11b 被调用者保存 %r13 %r13d %r13w %r13b 被调用者保存 %r14 %r14d %r14w %r14 被调用者保存 %r15 %r15d %r15w %r15 被调用者保存 相关规则: ...

August 2, 2020 · 3 min · Gray King

IEEE 浮点数

tags: Computer Systems,《深入理解计算机系统》读书笔记 浮点数小数表示形式 .0111 = \(0x2^{-1}+2^{-2}+2^{-3}+2^{-4}\) IEEE 浮点数表示形式 \[ V=(-1)^s X M X 2^E \] s = 0 表示负数, s = 1 表示正数 M 是二进制表示的小数 E 是阶码 浮点数二进制组成 一个单独符号位 s 表吗符合 k 位阶码字段 exp 编码阶码 E n 位小数字段 frac 编码尾数 M 两种常见的格式 float s = 1 k = 8 n = 23 double s = 1 k = 11 n = 52 三种计算方式 前置的一些值 e 是 exp 位表示的无符号数 f 是 frac 位表示的小数 \(Bias = 2^{k-1} -1\) 规格化的值 规则:阶码字段 exp 的位模式即不全为 0,也不全为 1(单精度 255,双精度 2047) 计算方式 \(E = e - Bias\) $M = 1 + f $ 非规格化的值 规则:阶码字段 exp 全是 0(用于表示 0) 计算方式 \(E = 1 - Bias\) \(M = f\) 可以表示 +0 和 -0。 ...

August 2, 2020 · 1 min · Gray King

Choosing a Rust web framework, 2020 edition

tags: Rust source: Choosing a Rust web framework, 2020 edition

July 10, 2020 · 1 min · Gray King