Luyu Huang's Tech Blog

搞清楚令人头疼的乱码问题

相信我们每个人都被乱码的问题困扰过. 乱码常常令人十分头疼, 这主要是因为没有搞清楚字符编码的问题: 何为 encode 何为 decode, UTF-8 和 Unicode 是什么关系, 它与 UTF-16 和 UTF-32 的区别又是什么, BOM 头又是什么东西等等. 这里我们彻底地捋一遍字符编码问题. 首先搞清楚几个概念: 基本概念 字符 字符指语言中的书写原子, 是不可再分的最小单元, 例如字母 a é, 表达符号 ; 。, 汉字 阿, 假名 あ, emoji 😂 等等. 总之是书写的最小单位, 它们都应该看作一个字符. 字符库 人类的字符太多了, 我们一次用不了这么多. 所以我们根据不同的情况, 取全体字符的一个子...

Read more

使用 LPeg 解析语法

LPeg 是一个 Lua 的模式匹配库. 笔者刚刚接触到 LPeg 时, 以为它只是另一种形式的正则表达式; 深入了解才发现, 它的功能远远强于正则表达式, 能够轻易匹配正则表达式难以匹配的复杂模式, 乃至解析语法. 事实上, LPeg 即是 Parsing Expression Grammars for Lua, 它设计出来就是用来解析语法的. 使用 LPeg 能够轻松地解析各种语法, 比如用四百行代码将 Lua 源码解析成抽象语法树. 有了它, 静态分析代码, 自定义 DSL(Domain Specific Language) 将会变得易如反掌. 本文不会详细介绍 LPeg 中的每一个函数, 每一个操作符, 这些内容官方文档中都很清楚; 这里主要介绍 LPeg 的匹配机制以及使用...

Read more

使用 Cloudflare 免费搭建 HTTPS 服务

细心的朋友可能发现博客的域名变了. 笔者最近买了一个域名, 让它映射到我的 Github Pages 上. 然后我还在搬瓦工买了一个廉价 VPS 用于搭建一些服务, 比如 RSSHub 和 TTRSS, 同样把域名映射到这上面. 为什么要用域名而不直接使用 IP 地址呢? 一是域名要比 IP 地址好记, 可以使用主机名区分不同的服务 (而不是端口); 二是可以使用 HTTPS. SSL 证书通常很贵, 这里我使用 Cloudflare 的免费代理服务实现免费 HTTPS. 这篇文章总结一下我是怎么做的. Cloudflare 代理 HTTPS 证书实在是太贵了, 一个通配符域名证书一年要至少花上一两千. 那么如何满足广大人民群众建站需求呢? Cloudflare 就是一个很好的选择...

Read more

[翻译] Nginx 入门指南

本文由 Luyu Huang 翻译, 原文地址 http://nginx.org/en/docs/beginners_guide.html. 欢迎提 issue 来帮助我改进翻译 本文给出一个 nginx 的基本介绍并展示一些能用 nginx 实现的简单例子. 这里假设你的机器上已经安装好了 nginx, 如果没有, 请先参见 nginx 安装. 本文介绍如何启动和停止 nginx, 如何重新加载配置, 介绍配置文件的结构以及介绍如何设置 nginx 来提供静态内容服务, 如何配置 nginx 作为代理服务器, 还有如何连接 FastCGI 应用. Nginx 由一个主进程(master process)和若干个工作进程(worker process)组成. 主进程的作用是读取并...

Read more

Synchronize time and time zone between client and server

The time in online games is generally based on the server time, which include the time used by the client for calculation and display, since the time in the client may be incorrect. In addition, my game project'll be released globally, so it's important to synchronize time zone between client and server. I have to deal with the time zone problem...

Read more

Gzip 格式和 DEFLATE 压缩算法

1. 引言 当你键入 tar -zcf src.tar.gz src, 就可以将 src 下的所有文件打包成一个 tar.gz 格式的压缩包. 这里的 "tar" 是归档格式, 将多个文件组合成一个文件; 而 "gz" 指的就是 gzip 压缩格式, 使用 DEFLATE 算法压缩得到. 作为使用最广泛的无损压缩算法, DEFLATE 是怎样工作的, 背后的原理是什么? 这篇文章我们来讨论下这个问题. DEFLATE 算法结合了 LZ77 算法和 Huffman 编码, 由 Phil Katz 设计, 并被 RFC1951 标准化. 本文是笔者对 RFC1951 和 zlib 研究的总结, 首先介绍 LZ77 算法, 再阐述 Huffman 编码在 DEFLATE 中的作用; 最后...

Read more

给 VSCode 做了个 RSS 阅读器插件

一直比较喜欢使用 RSS 订阅一些新闻和技术博客, 但总觉得 Windows 上除了雷鸟外没有什么好用的阅读器. 后来突然想到既然平时 VSCode 用得这么多, 为什么不给它写个 RSS 阅读插件呢, 而且 VSCode 扩展性这么强, 又天生支持 HTML 渲染. 于是清明节这几天就搞出了这个: luyuhuang/vscode-rss. 在 VSCode 扩展商店中搜 "RSS" 就能找到它. 它用起来就像这样: 嗯, 这样以后写代码写累了就可以摸鱼看看 RSS 订阅了. 目前已经实现了一个 RSS 阅读器所需的基本功能了, 自动刷新, 已读未读标记, 识别相对 URL 等都是有的. 它的配置非常简单, 直接在 settings.json 中加一个 RSS 源列表即可: ...

Read more

为什么说 Lua 5.3 中没有全局变量了

过去笔者一直使用 Lua 5.1, 对 Lua 5.3 中的 _ENV 一知半解. 最近新项目中使用了 Lua 5.3, 于是特意研究了下. 这篇文章总结下 Lua 5.3 中的环境和全局变量, _ENV 的含义以及与之相关的用法. Lua 变量的类型 Lua 中的变量可分为局部变量, 上值(upvalue)和全局变量. 经常使用 Lua 的同学应该都很熟悉, 举个例子: local up = "str" local function foo(a) local b = a print(up, b) end 对于 function foo 来说, a 和 b 是局部变量, up 是上值, print 则是全局变量. 局部变量和上值 一个变量是什么变量在编译时...

Read more