Antkillerfarm Hacking V7.0

小众语言集中营, boost, C++ Test framework

2016-10-25

小众语言集中营

前言

自从John Warner Backus创立计算机语义学以来,人们发明的计算机语言已不下千种。基本上没有人能够对所有的语言都精通,实际上也没有这个必要。

但我同样不赞成只会一种语言的工程师。因为每种语言之所以存在,必然有其合理之处,只会一种语言会严重局限程序员的眼界。

比如说这篇文章中提到的:

https://www.cnblogs.com/rosee-1224/p/5167878.html

程序员思考、学习新技术的原则和方式

“他的单位有一位写Ruby的老员工,一个庞大的工程,代码里面居然只有一个上帝类,就搞定了所有的问题。”

上面这句话,在文中被作者引用来作为不会设计的典范。但是看看作者的知识背景就会发现,这个作者的眼界实际上局限在了面向对象的笼子里,他以为所有的东西都要组成对象才是合理的,反而忽视了设计的目的。

我对这件事的解读是:如果那个老员工的代码能够只用一个类搞定所有的问题,且代码运行、功能扩展都没有大问题的话,那这个老员工就是一个优秀的设计者。即使他的设计思想不是面向对象的。

Linus Torvalds在批评C++的时候,曾说过“好的设计才是第一位的,糟糕的设计用什么语言写出来都是垃圾。”

反过来理解这句话,那就是:语言和设计思想都只是设计的外皮,而不是灵魂。

面向过程的语言

1.编译型

首推C语言,没有之一。其次可以学学Pascal。其他的诸如Basic、Fortran、COBOL,基本上已经成为了历史,如果没有工作上的需要,就不要理会了。

2.解释型

一般用的比较多的是bash、Tcl、perl。随便学一个即可,这三个的使用都挺广泛的。

面向对象的语言

1.编译型

首推C++。C++支持的编程泛型非常多,从某种意义上说,不是个纯粹的面向对象的语言。如果需要开发Mac和iPhone程序的,可以学学Objective-C。

2.虚拟机型

C#和Java,随便学一个。VB.NET、Groovy、Scala都属备选,各有各的好处,尤其后两者属于现在的热点,学学没准就用上了。

3.解释性

Python、Ruby,随便学一个。

科学计算

首推Matlab。这是一种面向矩阵的语言,它的所有数据类型都被理解为矩阵,而不是对象。

函数式语言

1.Haskell

这种语言认为所有的数据类型都是函数。

2.Lisp

这种语言认为所有的数据和函数都是列表,也就是“数据结构”课程上所说的广义表。

标记语言

1.Tex

这是《The Art of Computer Programming》一书的作者Donald Knuth的杰作。从中可以看到后来的HTML、JavaScript、CSS等的影子。MS Office中的格式刷也是参考了Tex的设计。

Tex最为称道的是数学公式的排版。MS Office直到2007版本才有了类似的效果。

Tex广泛应用于欧美国家科学论文的排版领域,成为顶级科学期刊事实上的格式标准,可说是科研狗的必备技能。

2.数据描述类

INI和Json。这两个比较简单,也非常好用,不多说了。备选有BSON、YAML、

3.网页类

XML、HTML、JavaScript必修。PHP、ASP、JSP,选修其中之一。Nodejs近来比较流行,值得投资。

嵌入式语言

首推Lua。它首先在游戏领域得到广泛使用,现在在其他领域用的也比较多了。我一直在想,如果Lua早发明30年,Emacs会不会使用Lua,而不是Lisp做为内置语言呢?

形式语言

并非所有的编程语言都具有实用性,有些语言的创制,另有其目的。

比如Brainfuck语言。这个语言以出名难用著称,在网上,一般被归为奇技淫巧类语言。然而从语义学的角度,这个语言证明了在冯·诺依曼模型上,最多使用8个符号,就可以构建一个图灵完备语言。

更多这类语言的知识参见:

http://www.15yan.com/story/5Y8BZqIGwjg/

那些奇奇怪怪的编程语言

类型系统(type system)

https://zhuanlan.zhihu.com/p/34679052

一个讲述编程语言类型系统的专栏

Lambda Calculus

Lambda calculus我们一般称为λ演算,最早是由邱奇(Alonzo Church,图灵的博导)在20世纪30年代引入,当时的背景是解决函数可计算的本质性问题,初期λ演算成功的解决了在可计算理论中的判定性问题,后来根据Church–Turing thesis,证明了λ演算与图灵机是等价的。

参考:

https://liujiacai.net/blog/2014/10/12/lambda-calculus-introduction/

编程语言的基石——Lambda calculus

https://zhuanlan.zhihu.com/p/34679052

Lambda calculus

https://blog.csdn.net/universsky2015/article/details/100933589

函数式编程的基石——Lambda Calculus(Functional Programming)

https://mp.weixin.qq.com/s/XTXnTPAbK1ipaHIsUD2kBQ

深入理解函数式编程(上)

https://mp.weixin.qq.com/s/2a2PZkGq0eKd7ee7HnHpoQ

深入理解函数式编程(下)

boost

安装&编译

boost直接安装:

sudo apt install libboost-all-dev

编译:

./bootstrap.sh
./b2 install link=static cxxflags=-fPIC --with-test --prefix=</path/to/install>

boost的组件有很多,这里只编译了test组件。

注意:指定生成目录的时候,stage使用stagedir选项,而install使用prefix选项。

boost::format

cout << boost::format("%1%"
    "%1t 十进制 = [%2$d]\n"
    "%1t 格式化的十进制 = [%2$5d]\n"
    "%1t 格式化十进制,前补'0' = [%2$05d]\n"
    "%1t 十六进制 = [%2$x]\n"
    "%1t 八进制 = [%2$o]\n"
    "%1t 浮点 = [%3$f]\n"
    "%1t 格式化的浮点 = [%3$3.3f]\n"
    "%1t 科学计数 = [%3$e]\n"
    ) % "example :\n" % 15 % 15.01 << endl;

参考:

https://www.cnblogs.com/WuErPIng/archive/2005/04/21/142308.html

浅尝boost之format

Boost.Parameter

该库可以支持命名参数,然而实现太复杂。期待新标准直接支持。

Boost.MPL

元编程(Metaprogramming)是指某类计算机程序的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。很多情况下与手工编写全部代码相比工作效率更高。编写元程序的语言称之为元语言,被操作的语言称之为目标语言。一门语言同时也是自身的元语言的能力称之为反射。

MPL可以看成是STL的编译期版本,或者说元编程版本。它同样也提供了各种容器,只不过容纳的对象不是数据,而是类型。

所以作为通用的、泛型的模板,不可能在动态库、静态库中就提供好二进制——怎么可能为成千上万种类型都提前生成好二进制呢?甚至还有还没有写出来的类型,怎么可能提前生成呢?

这也是为什么模板又叫模板元编程。“元编程”的意思就是用代码生成代码。

参考:

https://www.cppblog.com/jack-wang/archive/2010/10/04/128589.html

模板元编程—用MPL解决实际问题

https://mp.weixin.qq.com/s/5ireHbuWFrVY6T9qnvs3rQ

浅谈C++元编程

Other

Boost.Hana:元编程库,提供异构容器和算法,用于类型和值的计算。

Boost.Reflection:提供一种运行时反射机制。

BGL

Boost Graph Library是boost提供的一个和图论相关的工具库,集成了常见的图操作(如BFS和DFS)和图算法(最短路径、拓朴排序)。

官网:

https://www.boost.org/doc/libs/1_73_0/libs/graph/doc/

参考:

https://www.ibm.com/developerworks/cn/aix/library/au-aix-boost-graph/

探索Boost Graph Library

示例:

https://github.com/antkillerfarm/antkillerfarm_crazy/blob/master/cpp/boost/graph/main.cpp

test1:base。

test2:批量添加边+拓扑排序。

test3:顶点改为字符串数据类型,使用BGL API。

test4:顶点改为字符串数据类型,不使用BGL API。

folly

folly是facebook出品的另一个知名的标准库扩展。

代码:

https://github.com/facebook/folly

abseil

造轮子的事情,Google也有份。

代码:

https://github.com/abseil/abseil-cpp

而且还有一个给python用的基础库:

https://github.com/abseil/abseil-py

abseil不光提供代码,还有一个编程的技巧:

https://abseil.io/tips/

ACE

Douglas C. Schmidt写的一个C++的网络库。历史非常悠久了(1993年),其中的很多部分都有很高的参考价值。

官网:

http://www.dre.vanderbilt.edu/~schmidt/ACE.html

POCO

POCO也是一个C++的网络库。(2004年)

官网:

https://pocoproject.org/

C++ Test framework

boost.test

boost.test是一个C++的单元测试框架。

代码示例:

https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/cpp/boost_test

要点:

  • 测试代码无须main函数。

  • 编译:-DBOOST_TEST_DYN_LINK

  • 链接:-lboost_unit_test_framework

打印所有的log:

unit_test --log_level=all

参考:

https://www.ibm.com/developerworks/cn/aix/library/au-ctools1_boost/

了解Boost单元测试框架

https://www.ibm.com/developerworks/cn/aix/library/au-ctools2_cppunit/index.html

了解CppUnit

https://www.ibm.com/developerworks/cn/aix/library/au-ctools3_ccptest/

了解CppTest。上面这3篇算是比较权威的C++单元测试工具的教程了,作者都是Arpan Sen。

https://my.oschina.net/vaero/blog/227528

C++单元测试:boost.test

https://remonstrate.wordpress.com/2011/07/06/boost-%e7%9a%84-unit-test/

boost的unit test

googletest

安装:

sudo apt install libgtest-dev

代码:

https://github.com/google/googletest

gtest_filter是一个很有用的选项。

示例:

./foo_test --gtest_filter=FooTest*.*-FooTest.Bar:FooTest2.Bar

运行所有“测试案例名称(testcase_name)”为FooTest的案例,但是除了FooTest.Bar和FooTest2.Bar。

-表示去除,:表示并列。

TEST(FooTest, DISABLED_DoesAbc) { ... }

去除测试用例。

参考:

https://www.ibm.com/developerworks/cn/aix/library/au-googletestingframework.html

Google C++ Testing Framework简介

https://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html

玩转Google开源C++单元测试框架Google Test系列(gtest)

gmock

gmock是google公司推出的一款开源的白盒测试工具。

测试一个模块的时候,可能涉及到和其他模块交互,可以将模块之间的接口mock起来,模拟交互过程。

比如要测试A模块,必过A模块需要调用B模块的函数。如果B模块还没有实现,此时,就可以用gmock将B模块的某些接口打桩。这样就可以让A模块的测试继续进行下去。

gmock目前是googletest的一部分,一般也与后者配合使用。

https://zhuanlan.zhihu.com/p/101906555

googletest-gmock使用示例

CTest

CTest是CMake集成的一个测试工具。

参考:

https://www.cnblogs.com/457220157-FTD/p/4139149.html

CTest

doctest

官网:

https://github.com/onqtam/doctest

Fork me on GitHub