0%

描述去世之人去世时的阳寿有「得年」、「享年」、「享寿」三种相对文雅的说法。其中

  • 得年用于过世之时较年轻之人;
  • 享年用于过世之时年龄适中之人;
  • 享寿用于过世之时年岁极长之人。

台湾所谓「教育部」之字典的「享寿」词条里提到用法:「習慣上稱卒年六十以上者為『享壽』,不滿六十者稱『享年』,三十以下者稱『得年』。」可为参考。

不过,随着现代人均寿命增加,私以为:卒年四十五以下称得年都不会突兀;卒年七十五以上恐怕称享寿才较为妥帖;若是卒年过百,恐怕得尊称一声「享高寿」了。

很早以前,在学习使用 Python 的 deque 容器时,我实现了一个玩具版的频率限制器。最近需要压测线上服务的性能,又不愿意总是在 QA 那边排队,于是需要自己写一个压测用的客户端。其中一个核心需求就是要实现 QPS 限制。

于是,终究逃不开要在 C++ 中实现一个线程安全的频率限制器。

阅读全文 »

在实际工作一个典型的机器学习任务中,我们在线上和线下都要对特征数据进行处理。线上处理的目的是为了推理预测,线下处理的目的则是为了准备训练数据。显然,因为处理区分线上线下,数据一致性就会成为非常关键的问题。

然而,数据一致性是挺烫手的山芋。因为,如果尝试在线上线下先后两次实现同样的功能,不论如何小心,都有出错的可能。更不用说,如果使用不同语言,那对于数据处理上的些微不同最终都可能破坏数据一致性。

因此,保证数据一致性最好的办法就是用一份代码在两个地方干同样的事情。我们线上服务是用 C++ 编写的,因此我们可以将特征 ETL 抽象成单独的模块,分别链接到线上服务以及离线特征处理程序中。这样,二者对于特征的 ETL 的行为就完全一致了。

剩下的问题就是:离线数据通过 Kafka 落在 Hive 表当中,我们需要在 Hive 处理数据的过程中,嵌入我们自己编写的特征处理程序。

阅读全文 »

Protobuf(全称 Protocal Buffer,简称 pb)是 Google 开源的序列化/反序列化工具,在工业界相当流行。pb3 相比 pb2 的一个显著变化,就是在 pb3 当中不再区分 requiredoptional 字段。与此同时,在 pb2 中针对 optional 基本类型字段设计的 [default = foobar] 的默认值功能和 has_xxx() 的接口也随之消失。这样引出来一个问题,即:

  • 在多数场景下,「未设置」和「取值为 0/0.0/""/false」等价;但是
  • 在某些场景下,「未设置」和上述取值不等价。

特别地,在序列化 - 反序列化之后,如果拿到一个零值,你无法得知这个值是确实为零值,还是说因为没有显示设置而得到的零值。本文在 C++ 场景下来解决这个问题。

阅读全文 »