假装自己是人类
及时获取反馈以提升工作效率

最近发现自己及整个团队的开发效率低下,思前想后认为跟反馈链太长脱不了干系,于是思考及时反馈的重要性,以及它如何影响我们的效率。这里做一个小结。

估算:古代水稻亩产量

用了金克垃,亩产一千八。古代没有金克垃,亩产有多少?有你现有的常识,能估算出来吗?

CSS 子元素依次收缩的实现

当子元素的宽度(或高度)超过父元素时,如果父元素设置了 display: flex,则子 元素将按比例缩小自己的宽度(或高度),但现在我们希望子元素按一定的优先级缩小。 即:当宽度不足时,优先缩小某一个子元素,当达到该元素的最小宽度(min-width) 时,再开始缩小另外的元素。下面是一个示例图:

可以看到,当宽度不足时,上例中优先缩小了最右的元素,当最右元素达到最小宽度 100px 时开始缩小左边的元素,依此类推。

Python Decorator(装饰器)

今天来说说 Python 里的装饰器 (decorator)。它不难,但却几乎是 “精通” Python 的路上的第一道关卡。让我们来看看它到底是什么东西,为什么我们需要它。

Underscore.js 源码阅读

(这是两年前的笔记,现在把它搬到博客上,Underscore 版本:1.8.3)

这篇文章 的启发,萌生阅读 underscore.js 源 码的念头,其中有许多不理解的地方,也是读了上述文章后才明白的.为了保持本文的完整 性,也尽量按自己的理解进行注释. 不再提及上述引用文章.

CSS position:sticky

大约两年看在看 ECMA 2015 的时候,发现在滚动时每个章节的标题都会固定在页面的顶端,好奇的我看了下它的 CSS,发现只有简单的一行 position: sticky。当时只有 Firefox 实现了这个特性,不免心生遗憾,今天恰巧注意到 Chrome 从 56 也支持这个特性了!这里我们就来介绍下这个神奇的特性吧。

理解 Python asyncio

协程 (coroutine) 几乎是 Python 里最为复杂的特性之一了,这篇文章我们来说一说 asyncio 的内部实现机制,借此来理解一门语言要支持协程需要做的工作。

评:30 多年的编码经验浓缩成的 10 条最佳实践

文章 30 多年的编码经验浓缩成的 10 条最佳实践 原文出自 10 Tips for Writting Better Code。我认为这 10 条原则挺有帮助,所以本文想对这些原则做一些评价,说说我的看法,可以的话顺便给一些例子。建议看这篇文章之前先阅读原文。

Python Generator

Python 中的生成器 (generator) 是一个十分有用的工具,它让我们能方便地生成迭代器 (iterator)。这篇文章里,我们就来说说什么是生成器,生成器有什么作用以及如何使用。

This is a slide I made explaining the ugly internal detail of git.

在面向对象语言中写纯函数!

通常我们说函数式编程时,提到的都是 lambda 表达式,也即函数式编程中的“函数是头等公民”的特点,然而函数式的另一个重要特点: 无副作用 ,在我看来更为重要。它可以在任何语言中实际应用。今天,我们来谈一谈面向对象中的“副作用”。

简谈 Rust 中的错误处理

在学习 Rust 的过程中,错误处理是一个必需要迈过的坎。主要原因是所有的标准库都以统一的方式处理错误,我们就来谈一谈 Rust 中是如何处理错误的吧。

理解 Rust 中的生命周期

Ownership, Borrowing 与 Lifetime 共同成就了 rust 中的内存安全,也是 rust 语言中最精髓的创造,我们就来学习学习它们究竟是什么,为什么要引入这些概念。

《慢思考》大脑超载时代的思考学

会有这样的感觉吗?忙碌了一整天,却不知道忙了些什么。《慢思考》这本书正是以科学的角度告诉了我们原因:我们无法一心二用,却分明又想一心多用!

再谈闭包

在 Algol/Fortran 世界生活的人们总是不相信在未来的编程中,函数闭包对编程的效率 能有多大的帮助。之后就发生了“面向对象编程”的革命,现在几乎人人都用函数闭包进行编程, 只是他们依旧不把它叫作“函数闭包”。

之前的文章里, 我们试图说服大家:闭包与面向对象在本质上是一样的。这篇文章中,我们要仔细看看什么是闭 包;闭包与 lambda 的区别;将函数作为数据的优缺点;以及其它一些你可能想了解的概念。

JSONP 简介

JSONP 不是 JSON,它是跨域访问的一种机制。那么什么是跨域访问?什么是 JSONP?如果你不清楚的话,不妨点开看看吧。

CSS 垂直居中

简单一句 margin: 0 auto 我们便能搞定水平居中,而正当我们开心地写出 margin: auto 0 时,浏览器却没却无情地拒绝了我们,那我们来看看如何用 CSS 实现垂直居中吧。

Let's Build a C Compiler (1) -- Design

This is the second chapter of series “Let’s Build a C Compiler”, In this chapter we will have an overview of the structures of our compiler.

Let's Build a C Compiler(0) -- Preface

EDIT: Note that I’ve include the full tutorial in the project write-a-C-interpreter. Please check that instead.

结构的悖论

The paradox of structure is that, whatever its nature, any structure is both enabling and limiting at the same time.

每一种结构既会赋予能力,同时又会限制能力。最近在网易公开课看了这节 结构的悖论,是宾夕法尼 亚大学的公开课《创造、创新和改变》中的一节。这里的结构可以代指任何事物,例如 法律,例如公司的制度,我们应该如何对待生活中的结构呢?

写一个 Mustache 模板引擎

前几天在伯乐在线上看到 介绍 mustache.js 的文章Mustache 是一种模板语言,语法简单,功能强大,已经有各个语言下的实现。那么我们今天就用 python 来一步步实现它吧!

Hexo 自动部署到 Github

使用 Hexo 写博客是十分惬意的事。唯一有点不爽的,就是每次修改后都要重新生成并部署到 Github 上,这也是所有静态博客生成工具的通病。那么本文我们就利用 Travis CI 来完成自动部署,解决心中最后一处搔痒。

手把手教你构建 C 语言编译器(9)- 总结

恭喜你完成了自己的 C 语言编译器,本章中我们发一发牢骚,说一说编写编译器值得注 意的一些问题;编写编译器时遇到的一些难题。

手把手教你构建 C 语言编译器(8)- 表达式

这是整个编译器的最后一部分,解析表达式。什么是表达式?表达式是将各种语言要素 的一个组合,用来求值。例如:函数调用、变量赋值、运算符运算等等。

表达式的解析难点有二:一是运算符的优先级问题,二是如何将表达式编译成目标代码。 我们就来逐一说明。

手把手教你构建 C 语言编译器(7)- 语句

整个编译器还剩下最后两个部分:语句和表达式的解析。它们的内容比较多,主要涉及 如何将语句和表达式编译成汇编代码。这章讲解语句的解析,相对于表达式来说它还是较 为容易的。

手把手教你构建 C 语言编译器(6)- 函数定义

由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定 义、函数定义、表达式。本章讲解函数定义相关的内容。

手把手教你构建 C 语言编译器(5)- 变量定义

本章中我们用 EBNF 来大致描述我们实现的 C 语言的文法,并实现其中解析变量定义 部分。

由于语法分析本身比较复杂,所以我们将它拆分成 3 个部分进行讲解,分别是:变量定 义、函数定义、表达式。

手把手教你构建 C 语言编译器(4)- 递归下降

本章我们将讲解递归下降的方法,并用它完成一个基本的四则运算的语法分析器。

手把手教你构建 C 语言编译器(3)- 词法分析器

本章我们要讲解如何构建词法分析器。

手把手教你构建 C 语言编译器(2)- 虚拟机

本章是“手把手教你构建 C 语言编译器”系列的第三篇,本章我们要构建一台虚拟的电 脑,设计我们自己的指令集,运行我们的指令集,说得通俗一点就是自己实现一套汇编 语言。它们将作为我们的编译器最终输出的目标代码。

手把手教你构建 C 语言编译器(1)- 设计

本章是“手把手教你构建 C 语言编译器”系列的第二篇,我们要从整体上讲解如何设计我 们的 C 语言编译器。

手把手教你构建 C 语言编译器(0)- 前言

“手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。 希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能 用的 C 语言编译器,尽管有许多语法并不支持。

Vim 小技巧——合并行块

看教程时,自己动手输入教程的例子有助于学习和理解。但有时会发现自己输入的代码跑不通,而粘贴的代码是正确的。这时我们希望能一行行地对比自己输入的代码和原始代码。用 Vim 怎么做到呢?

Vim 小技巧-删除行末空格

在编写代码时,我们时常一不留神就在行末多打了几个空格。却又看不出来,即使用 vim-airline 之类的插件能知道有行末空格(trailing spaces),删除起来也特别麻烦。本文就介绍一个我就常用的 vim 快捷键:删除行末空格。

Closure 内涵理解

某人学习了许久的闭包,认为自己已掌握了其中的精髓,于是问禅师: “禅师,闭包真心强大,相比对象:我觉得对象只能算是穷人的闭包!” 禅师微微摇头,并不说话。这人怎么也想不通,只得回去苦心钻研。 许久之后,这人再次找到禅师: “原来闭包只是穷人的对象” 只见禅师轻轻一笑,点了点头。

闭包(closure)的概念,常出现在函数式编程的概念中。当今许多动态语言都包含了闭 包的概念,如 python、Javascrip、Lisp 等。甚至静态语言(如 rust)也开始支持。那 么这个神奇的闭包究竟是什么?又为什么会受到大家的热爱呢?本文将从闭包(closure)与对象(Object)的关系入手,通过实例来分析闭包背后的内涵。

Vim 最大化当前窗口

在编辑/查看文件时,时常遇到的一个需求是:临时最大化当前窗口(vim 术语中的 window,tmux 中的 pane)。Vim 原生并不支持该操作,但我们可以利用原生的标签页(tab page)来模拟这样的行为。

Test of Hexo

折腾许久的博客工具,反而没有实际写多少内容。遂决定“尽量”不折腾了,而是专心写些东西。最终用 Hexo 搭的博客,选 Maupassant 作主题,几乎没有额外的配置,准备就此开工。第一篇文章就用作测试 Hexo 的 Markdown 语法吧。