Personal Cmake cheating sheet
IOC vs DI vs DIP
先说结论
DI < IOC $\approx$ DIP
DIP 依赖反转原则 IOC 控制反转
图1高层对象A依赖于底层对象B的实现;图2中,把高层对象A对底层对象的需求抽象为一个接口A,底层对象B实现了接口A,这就是依赖反转
1 | class shape { |
Java 里interface 可以用interface key word 或者abstract class key word来实现, 两者的区别在于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
26
27
28
29
30
31
32
33
34
35
36
37interface shape{
public double get_area();
}
class Rectangle implements shape{
double h;
double w;
public double get_area(){
return h * w;
}
}
class Disk implements shape{
double r;
public double get_area(){
return 3.1415926 * r * r;
}
}
class Viewer {
public void show_area(shape sp){
System.out.println(sp.get_area());
}
}
public class testPackage {
public static void main(String[] args) {
Viewer view = new Viewer();
Disk disk = new Disk();
Rectangle rect = new Rectangle();
rect.h = 1;
rect.w = 2;
disk.r = 3;
view.show_area(rect);
view.show_area(disk);
}
}
控制反转与依赖反转本身是十分相似的,但是IOC更进一步要解决Viewer class 直接私有一个shape 对象的例子.
Answering only the first part. What is it?
Inversion of Control (IoC) means to create instances of dependencies first and latter instance of a class (optionally injecting them through constructor), instead of creating an instance of the class first and then the class instance creating instances of dependencies. Thus, inversion of control inverts the flow of control of the program. Instead of the callee controlling the flow of control (while creating dependencies), the caller controls the flow of control of the program.
what is REST?
REST means representation state transfer
It is architectural style for distributed hypermedia systems and was first presented by Roy Fielding in 2000 in his famous dissertation.
REST defines 6 architectural constraints which make any web service – a true RESTful API.
- Uniform interface
- Client–server
- Stateless
- Cacheable
- Layered system
- Code on demand (optional)
C++/Linux 面试小抄
Linux 面试
C++ 面试
new features
C++11
1 | Core language features |
语法
new vs malloc
1 | class A{...} |
STL 非官方实现
实现一个unique_ptr
1 | template<typename T> |
实现一个shared_ptr
这件事情主要在于实现一个带有引用计数的指针, 并支持父类子类的转换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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124template <typename T>
class mySmartPtr
{
public:
// 构造函数 默认为空
mySmartPtr(): pointer(0), counter(0)
{
}
// 形参为指针的构造函数
mySmartPtr(T* p): pointer(0), counter(0){
*this = p;
}
// 复制构造函数
mySmartPtr(const mySmartPtr<T> &p):
pointer(p.pointer), counter(p.counter){
Increase();
}
~mySmartPtr(){
Decrease();
}
// 指针的赋值操作符,类型不同,不是自赋值
mySmartPtr operator=(T* p){
Decrease();
if (p){
pointer = p;
counter = new int(1);
}
else {
pointer = 0;
counter = 0;
}
return *this;
}
// 智能指针赋值操作符
mySmartPtr operator=(mySmartPtr<T> &p){
// 处理自赋值
if (this != &p){
Decrease();
pointer = p.pointer;
counter = p.counter;
Increase();
}
return *this;
}
operator bool() const{
return counter != 0;
}
// ×操作符重载
T* operator*() const{
return this;
}
// ->操作符重载
T* operator->() const{
return pointer;
}
// 返回底层指针
int getPtrPointer() const{
return *pointer;
}
// 返回引用计数
int getPtrCounter() const{
return *counter;
}
// 处理父类子类的情况, ptr<derived>不能访问 ptr<based>的内部对象
template<typename C> friend class mySmartPtr;
template<typename C>
mySmartPtr(const mySmartPtr<C> &p):
pointer(p.pointer), counter(p.counter){
Increase();
}
template<typename C>
mySmartPtr<T> & operator=(const mySmartPtr<C> &p){
Decrease();
pointer = p.pointer;
counter = p.counter;
Increase();
return *this;
}
// 处理内部使用 dynamic_cast做判断的转换,失败则空指针
template<typename C>
mySmartPtr<C> Cast() const{
C* converted = dynamic_cast<C*>(pointer);
mySmartPtr<C> result;
if (converted){
result.pointer = converted;
result.counter = counter;
result.Increase();
}
return result;
}
private:
T* pointer;
int* counter;
void Increase(){
if (counter)
++*counter;
}
void Decrease(){
if (counter && --*counter == 0){
delete pointer;
delete counter;
counter = 0;
pointer = 0;
}
}
};
C style 多态
内存池和alloc 实现
1 | #ifndef _MEMORY_POOL_H_ |
Run and make daemon
Assume you have a binary or jar in some directory and you want to run it as daemon (which will not be killed as long as the os is runing)
Nginx config
Nginx is a powerful web proxy server. Recently, I used it to deploy my GoReactChatApp on VPS. The remaining applies to a ubuntu 18 server
Install1
2sudo apt update
sudo apt install nginx
HPC config
Recently, I have had a chance to build and test one of my largest project on HPC cluster. It took me sometime to correctly build and run it.
build
1 | module purge |
Tutte embedding and how to draw a graph
Definitions
Tutte embedding is method to generate drawing of 3-(vertex)-connected graphs. With the following definitions.
Definition A graph $G$ is called $k$-vertex-connected if removing any $k$ vertices from $G$ would let $G$ remain connected.
Definition A drawing $z$ of graph $G$ is a embedding of $G\rightarrow \mathbb{R}^2$. $G$ is called planar if such a drawing exists.
Definition A Tutte embedding of planar graph $G$ is a drawing $z$ of $G$ such that
- There is a face $F$ of $G$ such that $z$ maps the vertices of $F$ to the corners of a strictly convex polygon so that every edge of the face joins consecutive corners of the polygon
- Every vertex not in $F$ lies at the barycenter of its neighbors.
- Each edge is represented as a straight line.
By definition Tutte embedding is free from self-intersections because it is a drawing.