Intelligence without ambition is a bird without wings.

2016-05-12
backtrace()

阅读此文

2016-05-11
addr2line

用途

将程序地址转换为文件名和行号,结合call stack,可以在崩溃时,打印相应信息!

实例

addr2line -e a.out 0x5061ad
阅读此文

2016-05-08
程序设计-鸭子类型

定义

“一个走起来像鸭子,游起来像鸭子,叫起来也像鸭子,那么就可认为它是一只鸭子!”

要点

  • 鸭子类型是一种动态类型风格

  • 一个对象有效的语义(方法或属性),不是由继承自特定的类或实现特定的接口,而是由它本身所具有的方法和属性的集合来决定

  • 在一个具体的上下文中(函数),只关心该对象是否具有相应的语义(方法或属性),而不关心其真实类型

  • 属于一种多态,且不需要继承,灵活性更强!

  • 若该对象在鸭子测试中(函数使用该对象的方法或属性),不能通过,则抛出异常(类型错误)

  • 通过良好的文档,清晰的代码,完备的测试,来保证类型类型正常工作

实例

python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")

class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")

def in_the_forest(duck):
duck.quack()
duck.feathers()

def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)

game()

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

template <typename T>
struct Caller {
const T callee_;
Caller(const T callee) : callee_(callee) {}
void go() { callee_.call(); }
};

struct Foo {
void call() const { std::cout << "Foo"; }
};

struct Bar {
void call() const { std::cout << "Bar"; }
};

int main() {
Caller<Foo> foo{Foo()};
Caller<Bar> bar{Bar()};
foo.go();
bar.go();
std::cout << std::endl;
return 0;
}

参考

  1. https://en.wikipedia.org/wiki/Duck_test
  2. https://en.wikipedia.org/wiki/Duck_typing
  3. http://nullprogram.com/blog/2014/04/01/
阅读此文

2016-05-08
C++-template

优势

  • 减少重复代码编写

  • 接口统一

劣势

  • 因为编译器实例化,需要template实现,而实现包含了所有必须的头文件,这样增加了编译时间

  • 实例化错误不宜阅读和定位解决

阅读此文

2016-05-08
C++11-lambda

要点

  • lambda表达式实质上,是一种快速定义函数对象的语法(编译器实现)

    1
    auto cpp_bigger = [](int a, int b){ return a > b; };

    <=>

    1
    2
    3
    4
    5
    6
    class _CompilerInventedName
    {
    public:
    bool operator() (int a, int b) const { return a > b; }
    };
    _CompilerInventedName cpp_bigger;
阅读此文

2016-05-07
C++-异常

不足

  • 抛出异常时,除了ErrorMsg之外,不带文件名,行号,callstack等信息,不利于定位问题和分析问题

优势

  • 相比错误代码,不需要每个调用都逐个比较,也不需要手动向上传递
阅读此文

2016-05-07
C++11-override

好处

  • 显式说明该方法是重写虚函数,提供编译器更强的的检查,防止因为sinature不同,重新定义函数,而不是重写!

列子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Parent {
public:
virtual void f(short) {std::cout << "B::f" << std::endl;}
};

class Child : public Parent {
public:
virtual void f(int) override {std::cout << "D::f" << std::endl;}
};

int main()
{

return 0;
}
阅读此文

2016-05-07
C++-泛型编程

要点

  • 模板类在实例化时,必须显式指定类型,而模板函数可以不用(隐式推断)
阅读此文

2016-05-07
C++11-using

好处

  1. 相比typedef可读性更强
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>


using namespace std;

using PrintFunc = void(*)(std::string);

void Print(std::string s)
{

cout << s << endl;
}

int main(int argc, char* argv[])
{

PrintFunc f = Print;

f("Hello world");

return 0;
}
  1. 可以支持template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <memory>


using namespace std;

template<typename T>
using deleted_unique_ptr = std::unique_ptr<T, std::function<void(T *)>>;

int main(int argc, char *argv[])
{

deleted_unique_ptr<FILE> file(fopen("test", "w"),
[](FILE * f) {
cout << __PRETTY_FUNCTION__ << endl;
fclose(f);
});
fputs("Hello world", file.get());

return 0;
}

参考

  1. http://stackoverflow.com/questions/10747810/what-is-the-difference-between-typedef-and-using-in-c11
  2. http://stackoverflow.com/questions/19053351/how-do-i-use-a-custom-deleter-with-a-stdunique-ptr-member
阅读此文

2016-05-06
mysql-int(n)

作用

  • 若不指定显示宽度,则默认为该类型的最大位数(int=>11)

  • 作用相同于printf宽度控制,当数值位数小于指定值时,默认填充空格,大于指定值时,也不会截断!

  • 该显示宽度是可通过结果集(Result Set)中的元数据(Metadata)获取,具体采不采用取决于应用程序!

  • 宽度和zerofill对数据存储(存储形式,占用空间)没有任何影响

  • 当列定义指定zerofill时,若该值小于指定宽度,select查询输出会填充相应个数的0

测试

  • 指定宽度和zerofill
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
create table t(num int(5) zerofill);

MariaDB [test]> desc t;
+-------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------------------+------+-----+---------+-------+
| num | int(5) unsigned zerofill | YES | | NULL | |
+-------+--------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)

MariaDB [test]> insert into t values(1);
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> select * from t;
+-------+
| num |
+-------+
| 00001 |
+-------+
  • 不指定zerofill
1
2
3
4
5
6
7
8
9
10
11
12
13
MariaDB [test]> create table t1(num int(5));
Query OK, 0 rows affected (0.02 sec)

MariaDB [test]> insert into t1 values(1);
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> select * from t1;
+------+
| num |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
  • 不指定宽度,指定zerofill
1
2
3
4
5
6
7
8
9
10
11
12
13
MariaDB [test]> create table t2(num int zerofill);
Query OK, 0 rows affected (0.02 sec)

MariaDB [test]> insert into t2 values(1);
Query OK, 1 row affected (0.02 sec)

MariaDB [test]> select * from t2;
+------------+
| num |
+------------+
| 0000000001 |
+------------+
1 row in set (0.00 sec)

细节

  • 对于int来说,取值范围-2^(32-1) to 0 to 2^(32-1)-1 = -2147483648 to 0 to 2147483647,最大显示宽度为11

  • 对于unsigned int,0~4294967295,最大显示宽度为10

  • 当指定zerofill时,mysql会自动追加unsigned属性,!

1
2
3
4
5
+-------+---------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| num | int(10) unsigned zerofill | YES | | NULL | |
+-------+---------------------------+------+-----+---------+-------+

参考

  1. http://dev.mysql.com/doc/refman/5.7/en/numeric-type-attributes.html
  2. http://stackoverflow.com/questions/5634104/what-is-the-size-of-column-of-int11-in-mysql-in-bytes
  3. http://stackoverflow.com/questions/5256469/what-is-the-benefit-of-zerofill-in-mysql
  4. http://dev.mysql.com/doc/refman/5.7/en/integer-types.html
阅读此文