越努力 越幸运

【读书笔记】The Art of Readable Code

一、前言

第一章、代码应当易于理解

众所周知,这段代码:

for (Node* node = list->head; node != NULL; node = node->next)
    Print(node->data);

要比如下代码更好(尽管行为完全相同):

Node* node = list->head;
if (node == NULL) return;
while (node->next != NULL) {
    Print(node->data);
    node = node->next;
}
if (node != NULL) Print(node->data);

但大多时候这个选择很难把握,如这段代码:

return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent);

它会比如下代码更好还是更差呢?

if (exponent >= 0) {
    return mantissa * (1 << exponent);
} else {
    return mantissa / (1 << -exponent);
}

前一版更紧凑而后一版更简单直接。哪个标准更重要?在实践中又是如何选择的呢?

Github 上给开源项目提交 PR 前如何清理无关的提交信息

一、背景

最近在学习 gRPC 的过程中尝试给项目提一些代码,但是得到项目组的两位大牛回复说提交代码时应该把无关的提交历史给删除,具体回复是这样的:

@murgatroid99 这么回复的

Can you please send this PR without all of the irrelevant commits? All of the changes for this PR are in the second-to-last commit.

@ctiller 这么回复的

I’m not sure we want this to be blanket turned on for all platforms.

Also, it’d be good to clean up some of the spurious unrelated commits here.

我能看懂他们说的是什么,就是说我提交代码时有太多的无关的提交历史应该清理了再提交,像这样的:

【面试题】判断字符串列表是否能构造成首尾相连的循环列表

一、问题描述

给定一系列单词,如:

grep, pip, echo, open, net, tag, pre

然后判断这些单词是否能构造成这样的循环列表:

grep -> pip -> pre -> echo -> open -> net -> tag -> grep

前一个单词的尾字符是后一个单词的首字符

问题就是:给定单词列表,判断是否能够构成这样的列表。

二、解决问题

思路1:根据深度遍历或广度遍历判断

1. 从某个单词开始
2. 然后在剩下的单词中寻找以该单词尾字符开始的单词
   2.1 如果没找到而列表又没有遍历完,那就不能构造成循环列表了
   2.2 如果找到一个,则重复步骤2
   2.3 如果找到多个,则随机选择一个,重复步骤2
       2.3.1 如果某个能走通整个流程,则能构成循环列表
       2.3.1 如果某个不能走通,则返回步骤2.3使用剩下的单词的某一个,重复步骤2

整个思路就是深度遍历广度遍历

从开源项目中悟到了什么?

最近业余时间都在学习 grpc 相关的东西,由于本身对 RPC 的了解还很浅显,所以本文不谈 grpc 相关的东西,聊聊从中体会到的个人感受

1. 如何参与到开源项目中来?

要参与进来首先得保持一定的兴趣,兴趣是最好的老师嘛,虽然我是刚刚参与并且没有任何有质量的 Pull Request 被接受,但还是总结下个人的做法:

  • 学习项目的架构,通常都有详细的文档
    • 如果没有详细的文档,这里其实就可以做些事情,弄懂后写份文档,项目是英文就用英文写,这也是很大的能力提供。
  • 学会项目的使用,通常都有 example 代码
    • 同样,没有的话,就可以编写,然后提交
  • 读代码,然后提 Pull Request
    • 通常从简单的、依赖少的代码开始
    • 如果有 TODO 的话,可以尝试完成,测试通过后提交
  • 反复读代码,读懂代码
    • 在这基础上,记录自己的思考,并提 issue 跟别人沟通
    • 如果想法有用,尝试实现并提交
    • 沟通别人提的 issue 并尝试解决

个人觉得能按这种步骤来的话,还是对个人成长有帮助的。

RPC 原理初尝

一、背景

在很早以前就了解过点 RPC 相关的概念,就仅此而已,写的那点网络示例程序也都是本机调用的,直到最近学习 gRPC 才发现还有好多知识需要学习,或许部分原因也是由于以前的工作内容主要是客户端的吧。

现在接触的是服务端相关的东西,所以有必要好好学习下 RPC 等相关知识,公司系统涉及很多服务且都部署在不同的地域不同的机器上,维护也是由不同的团队维护的。

所以就需要学习如何编写、部署、搭建新的服务?如何依赖、调用其他服务?如何发布新服务给其他团队使用?等等。

二、RPC 介绍

1. RPC 简介

  • RPC 是 Remote Procedure Call 的缩写, 即远程过程/函数调用
  • RPC 用于进程间或跨网络通讯
  • RPC 具有很好的横向扩展能力, 更适合网络/分布式环境通讯

2. RPC 原理

RPC 主要涉及到的角色有: