Big Ben

一个半吊子的编码爱好者

0%

C++11的列表初始化

在C语言和C++98/03中,大括号可以用来初始化数组,例如:

1
2
int a[] = {1, 2, 3};
int b[4] = {1, 2, 3, 4}; // 如果个数不足的,用0初始化

C++11将这类大括号初始化,扩展到自定义类型,但需要满足一定的条件,否则会编译报错。

Read more »

什么是聚合类型

C++03定义
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

C++11定义
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

结合C++03和C++11标准定义,罗列一下聚合类型的特性:

  • 聚合类型可以有构造函数,但只能是编译器定义的默认构造函数,或者用=default定义的构造函数
  • 聚合类型不能有private,protected非static变量
  • 聚合类型可以有copy-assignment operator and/or destructor
  • 数组是聚合类型,即便数组成员是非聚合类型
  • 聚合类型的数组可以是非聚合类型
  • 聚合类型不能用brace-or-equal-initializers(即就地初始化)初始化非static成员。

聚合类型变量初始化

Read more »

在Linux中,一个进程拉起另一个进程的流程大致如下:

graph LR;
F[parent process] --> A[start]
A --fork--> B[child]
A --> C[wait]
B --exec--> D[new process]
D --> E[end]
C --> E

最常见的就是通过shell终端执行命令。此场景下,/bin/bash就是这个parent process,而要执行的那个命令就是new process。
Read more »

Intro

SID = Security Identifier (即Security ID)。其作用就是取代安全上下文,在权限匹配时,提升规则搜索速度,以及降低整个策略数据的空间复杂度,提升了整个SELinux特性的性能损耗。
例如一次权限匹配的函数调用原型如下:

1
2
int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
u32 requested, struct common_audit_data *auditdata)

其中ssid, tsid就代表了源(source)SID和目的(target)SID。在最终的av(access vector)计算中,SID被转化为context。

Read more »

links:


最近捣鼓群晖上的docker发现了一个很有意思的镜像diygod/rsshub - Docker Image | Docker Hub,提倡所谓的“万物皆可 RSS”。
接触RSS始于Google Reader,后来被Google弃坑后,一直用Feedly。现在国内能订阅的源越来越少了。各家巨头都想构建封闭的生态,用户进来了就别出去。通过RSS抓取全文更是不可能。我想RSS诞生的初衷本就应该是打破互联网的壁垒,构建定制化的阅读体验,减少到处充斥的垃圾信息污染,回归阅读的本质。还好我认识了RSS Hub这个项目。
本文会引用我在操作时参考的网络链接,并分享我踩过的坑,以节省诸君的时间,提供更好的构建服务的体验。

Synology + Docker

我今年升级了群晖NAS到新款DS220+,基于x86芯片,性能足够强大,运行docker也不是问题。这其实一下降低了NAS的折腾门槛。像之前手动装optware的工作完全没必要了,dockerhub中的资源很丰富,社区也很活跃。网上推荐NAS docker玩法的帖子很多,不过也大同小异。可以参考这篇:如何优雅的使用群晖NAS?我的套件和Docker镜像推荐!

Read more »

记得某一场合,一位领导说过,这次可信变革大概率会留下两样东西,一个是committer机制,另一个是代码白盒评价。而对于committer来说,code review就是其最重要的工作。

第一次接触code review还是在前公司。那时候,代码合入要请人点“ship it”。后来工具切换成了gerrit,不过code review基本上还是流于形式,和朋友圈点赞差不多。有一些比较较真的老外会给出不少意见,同事间还颇有不忿。
”连拼写错误也要提!“
”烦死了,他根本就不懂!“
国内的开发同学基本上是磨不开面子的,反正代码又不是我维护,就给你点个赞有啥关系。

真正第一次被评审代码是初入我司的时候。那时候与隔壁部门的同事一起参与一个操作系统项目。其中一位专家在评审代码的时候非常认真。每次提交MR,该专家在评审的时候都会提一堆问题。而且,这些问题点都或多或少确实存在问题,或者存在优化的可能。或修改,或解释,或补充注释。不过,最终我的MR也并没有合入,就切换到另外一个项目去了。经过这次刻骨铭心的合作,我也算是经历了一次真正的代码评审。后来,这位专家以及和他同组的小兄弟,在我司屡次的committer评选中,斩获了数次优秀committer的殊荣。很荣幸和他们能有过一段“不太愉快”的合作经历。在之后的项目里,我也被任命为committer,我希望把这份“不愉快”原汁原味地传递下去。

code review,又叫代码评审,是代码开发很必要的一环,也是代码合入的最后一环。我们通常说,问题发现得越早,修复问题花费的成本月底。code review通常就是靠看看代码,就能发现一些潜在的问题,成本是非常低的。试想代码合入之后再发现问题,会引入多少overloading——沟通,重现,定界,抓log……

code review既然这么好,那为什么总做不好呢?因为大家都是职场人,磨不开面儿。通常我们看到别人做的不好的地方,都不会当面戳破。关系好的,可能私底下会提醒一下,绝大多数情况就当作视而不见。所以committer课程通常第一句话都是教大家“要敢于说不”。话是不错,不过如果没有具体怎么做,就略显空洞,缺乏实操性。好在Google提供了一份详尽的code review指南(《google/eng-practices: Google’s Engineering Practices documentation》),从提交人和评审人的角度,给出了切实的做法,值得大家阅读。

Read more »

在最近的一些针对毕业生的面试中,我都会问一下他们对单元测试的理解。得到的答案无一例外都是不知道,不清楚,或是按字面意思的解释。其实,这也难怪。虽然我司可信变革对单元测试的要求越来越严苛,但真正能够理解并正确使用单元测试的同学也还是比较少的。至少在我周围是这样。

想想这也正常,记得曾经刚毕业时,我根本都不知道单元测试这个名词。直到后来,以前任职的公司专门外聘了专业的机构,做了相关的培训之后,我算是认识了这个词。但彼时的理解,有点像现在我司推行的Fuzz测试。也就是,代码写好后,通过工具生成各种各样的参数,调用待测代码,从而保证代码输出质量。现在可能很多同学还是这样的思路。回过头来再审视当时的观点,不免觉得过于片面了。单元测试最重要的作用其实并不是保证代码质量,对代码质量的改进可以说是它的一个副作用。

后来对于单元测试有了更深入的理解,是在阅读了下面三本书之后:

  • 《敏捷软件开发-原则模式与实践》 — Robert C. Martin
  • 《测试驱动开发》— Kent Beck
  • 《重构-改善既有代码的设计》— Martin Fowler

值得一提的是这三本书的作者都是敏捷软件开发宣言的发起者,也是极限编程(Extreme Programming)的践行者。书也都是高分经典著作,非常推荐给大家阅读。

Read more »

links:

  • [[hexo-renderer-marked]]

方法一

  1. 安装插件hexo-asset-image
  2. 修改_config.yml, post_asset_folder: false。将false改为true
  3. 在与md文件同目录下,创建一个同名文件夹,放入需要的图片文件
  4. 在md文件中,这样引用就好了![](file-name.png)
  5. Hexo在生成时

    1. 会自动处理这些图片标签,生成结果:/path_to_post/post_name/iamge-name。例如/2021/08/22/my-post/post123/my-img.png。source目录结果如下:
      |—source

       |--post123.md
       |--post123
           |--my-img.png
      
    2. Hexo的hexo-asset-image插件自动扫描目录,将md同目录下,与md文件同名的目录,拷贝到最终生成的index.html相同层级的目录下。
      |—public

       |--2021
           |--08
               |--22
                   |--post123
                       |--index.html
                       |--my-img.png
      

同时,md文件里通过![](my-img.png)一样也可以访问到。

Read more »

答案是否定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include <memory>

#include <iostream>

static void func(std::unique_ptr<int> a)

{}

int main()

{

auto a = std::make_unique<int>(1);

func(a);

return 0;

}

这段代码是不能编译的,因为uniqe_ptr没有拷贝构造函数。

1
2
3
4
5
6
7
8
9
10
11

ben@LUbuntu ~/t/unique_ptr> g++ -o test main.cpp -std=c++14

main.cpp: In function ‘int main()’:

main.cpp:10:11: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’

10 | func(a);

|

那为什么问这个问题?看下面这段代码

Read more »