画个图吧

Excalidraw

1
2
3
4
5
6
# install [nodejs](https://nodejs.org/en/download) and yarn
git clone https://github.com/excalidraw/excalidraw.git
cd excalidraw
yarn install
yarn start
# yarn build

Mermaid

1
2
3
4
git clone https://github.com/mermaid-js/mermaid-live-editor.git
cd mermaid-live-editor
pnpm install
pnpm dev -- --open

PlantUML

1
2
3
4
5
sudo apt install default-jre
# download [plantuml.jar](https://github.com/plantuml/plantuml/releases/download/v1.2026.1/plantuml-1.2026.1.jar)
java -jar plantuml.jar sample.puml
java -jar plantuml.jar -picoweb
java -jar plantuml.jar -gui
1
2
3
4
5
sudo apt install openjdk-17-jdk maven
git clone https://github.com/plantuml/plantuml-server.git
cd plantuml-server
mvn package
mvn jetty:run

Graphviz

1
2
sudo apt install graphviz
sudo apt install xdot

UML中的Signal是什么?

UML中的Signal是什么?

在UML中,信号是一种异步通信机制,表示一种事件消息,可以在对象之间传递。信号通常用于触发对象的行为,类似于消息,但它是异步的,不要求接收者立即响应。信号可以携带数据,常用于状态机图和活动图中,描述系统中的事件流和响应。

什么是事件,什么是消息。

事件(Event)是指系统中发生的某种动作或状态变化,通常用于描述系统的动态行为。例如,按钮被点击、定时器到期等都可以视为事件。

消息(Message)是对象之间传递的信息,用于请求某个操作或通知某种状态。消息通常包含操作名称和参数,是对象间通信的基本方式。

简单来说:

  • 事件:系统发生的动作或变化。
  • 消息:对象间传递的请求或通知。

Call和Invoke都有什么区别?

在编程和建模领域,callinvoke 都表示调用操作,但有细微区别:

  • call(调用):通常指直接调用某个方法或函数,执行其定义的操作。比如在代码中调用一个函数,属于同步操作,调用者会等待被调用者执行完毕。
  • invoke(触发/调用):更强调触发某个操作或行为,可能是间接的、异步的或通过反射机制。比如通过事件机制触发某个处理器,或者用反射动态调用方法。

简单来说:

  • call:直接、同步调用。
  • invoke:间接、可能异步或动态调用。

Bill:OOP中,调用对象的方法,就是向对象发消息;反过来也是。

什么是信号与槽?

信号与槽是一种事件驱动的通信机制,常用于Qt等框架中:

  • 信号(Signal):对象发出的通知,表示某个事件发生。
  • 槽(Slot):响应信号的函数或方法,处理事件。

当信号被触发时,所有连接到该信号的槽会自动执行。这样可以实现对象之间的解耦,便于异步和灵活的事件处理。

MFC是基于消息,事件驱动的

MFC(Microsoft Foundation Classes)确实是基于消息事件驱动机制的。它通过消息映射(Message Map)系统,将Windows消息(如鼠标点击、键盘输入等)与相应的成员函数关联,实现事件响应。这样,用户操作或系统事件会触发消息,MFC框架负责分发这些消息到对应的处理函数,实现对象间的通信和事件驱动编程。

什么是函数指针,什么是delegate?

函数指针和 delegate 都是用于间接调用函数或方法的机制,实现回调、事件处理等功能。

区别:

  • 函数指针是底层机制,类型安全性较弱,主要用于C/C++。
  • delegate 是高级语言的类型安全机制,支持多播和异步,主要用于C#等现代语言。

什么是回调,什么是事件。

回调事件都是编程中常用的机制,用于处理异步操作和响应系统变化。

回调(Callback) 是一种函数或方法,由其他代码在特定时机调用。通常用于异步操作或自定义行为。例如,传递一个函数指针或委托给某个API,当操作完成时自动调用该函数。回调实现了灵活的流程控制和解耦。

事件(Event) 是系统中发生的动作或状态变化,通常用于通知对象某些操作已发生。事件机制允许对象订阅并响应这些变化。例如,按钮被点击、数据加载完成等都可以视为事件。事件通常与回调结合使用,实现响应式编程。

区别:

  • 回调是具体的函数,事件是动作或变化的抽象。
  • 事件发生时,通常通过回调函数来处理和响应。

C++ - Type Erasure

Key points

继承中的多态:子类实现(implement)父类中定义的接口。

模板中的多态:不同的类遵守(conform to)相同的接口。

使用基于模板的多态的问题是caller也要是模板,即传染性。总的来说,有需要异质(heterogeneous)容器的需求;而一般的容器都要求元素是相同的类型(homogeneous)。

OO中的interface类比于template中的concept;OO中的interface和implement/instance类比于concept和model。

std::any是一个类(不是类模板),以type-safe的方式存is_copy_constructible类型的值。即只要类型conform to is_copy_constructible接口,它的值就能存在any对象里面。any擦除了任何is_copy_constructible类型的实际类型。

std::function是个类模板,它是一个function wrapper,可以存并调用任何CopyConstructibleCallable的target:function pointer,lambda expression,bind expression,function object/functor,pointer to member function(non-static/static,virtual/non-virtual),pointer to data member。function擦除了target的实际类型,而其模板参数表明了target应该conform to的函数原型。

尽管etl::delegate看上去和std::function很像,但是它没有使用类型擦除技术;是否有类型擦除,主要还是看它是存wrapper还是不是。

和CRTP的不同

Type Erasure实现了runtime polymorphism(但不依靠继承),CRTP(Curiously Recurring Template Pattern)实现了compile-time polymorphism(static dispatch或者policy-based design)。Type Erasure以性能换取弹性(trades performance for flexibility),CRTP以弹性换取性能(trades flexibility for performance),更强的type safety。

简单从表相上来看,Type Erasure是模板类继承自普通类,CRTP是普通类继承自模板类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Type Erasure

class Concept {
public:
virtual void interface() = 0;
};

template<typename Concrete>
class Model : public Concept {
Concrete* object; // hold the concrete object
public:
virtual void interface() override {
// dispatch to object->implementation()
}
};

class Concrete {
void implementation() {} // don't have to be virtual
};
1
2
3
4
5
6
7
8
9
10
// CRTP

template<typename Derived>
struct Base {
void interface() { static_cast<Derived*>(this)->implementation(); }
};

struct Derived : public Base<Derived> {
void implementation() {}
};

Examples

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
class SeeAndSay {
class AnimalConcept {
public:
virtual const char* see() const = 0;
virtual const char* say() const = 0;
};

template<typename T>
class AnimalModel : public AnimalConcept {
const T* m_animal;
public:
AnimalModel(const T* animal) : m_animal(animal) {}
const char* see() const { return m_animal->see(); }
const char* say() const { return m_animal->say(); }
};

vector<AnimalConcept*> m_animals;

public:
template<typename T>
void addAnimal(T* animal) {
m_animals.push_back(new AnimalModel(animal));
}

void pullTheString() {
for (auto animal : m_animals) {
cout << "The " << animal->see()
<< " says '" << animal->say()
<< "'!" << endl;
}
}
};

struct Cow {
const char* see() const { return "cow"; }
const char* say() const { return "moo"; }
};

struct Pig {
const char* see() const { return "pig"; }
const char* say() const { return "oink"; }
};

struct Dog {
const char* see() const { return "dog"; }
const char* say() const { return "woof"; }
};

int main() {
SeeAndSay seeAndSay;
seeAndSay.addAnimal(new Cow);
seeAndSay.addAnimal(new Pig);
seeAndSay.addAnimal(new Dog);
seeAndSay.pullTheString();

return 0;
}
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
class Object {
struct ObjectConcept {
virtual ~ObjectConcept() = default;
};

template<typename T>
struct ObjectModel : ObjectConcept {
ObjectModel(const T& t) : object(t) {}
virtual ~ObjectModel() = default;
private:
T object;
};

shared_ptr<ObjectConcept> object;

public:
template<typename T>
Object(const T& t) : object(make_shared<ObjectModel<T>>(t)) {}
};

struct Foo {};
struct Bar {};

int main() {
vector<Object> objects;

objects.push_back(Object(1));
objects.push_back(Object(Foo()));
objects.push_back(Object(Bar()));

return 0;
}
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
class Greeter {
public:
template<class T>
Greeter(T data) : self_(make_shared<Model<T>>(data)) {}

void greet(const string& name) const {
self_->greet(name);
}

private:
struct Concept {
virtual ~Concept() = default;
virtual void greet(const string&) const = 0;
};

template<class T>
class Model : public Concept {
public:
Model(T data) : data_(data) {}

virtual void greet(const string& name) const override {
data_.greet(name);
}

private:
T data_;
};

shared_ptr<const Concept> self_;
};

struct English {
void greet(const string& name) const {
cout << "Good day " << name << ". How are you?\n";
}
};

struct French {
void greet(const string& name) const {
cout << "Bonjour " << name << ". Comment ca va?\n";
}
};

void greet_tom(const Greeter& g) {
g.greet("Tom");
}

int main() {
greet_tom(English());
greet_tom(French());

return 0;
}

References

Technology Evolution

IT Evolution

  • Centralized Mainframe
  • Personal Computing
  • Client Server
  • Enterprise Computing
  • Cloud Computing

Software Development

  • Pioneering Days
  • High-level Languages
  • Personal Computer Revolution
  • Internet Age
  • Rise of Mobile and Apps
  • Cloud Computing and AI

ABCDE

  • AI
    • Machine Learning
    • Deep Learning
    • Generative model
    • Pre-trained model
  • Blockchain
  • Cloud Computing
    • Distributed System
    • Cluster Computing
    • Grid Computing
    • Virtualization
    • Web2
      • Service Orientation
        • IaaS
        • PaaS
        • SaaS
        • XaaS
      • Utility Computing
    • Cloud Native
      • Microservice
      • Container
      • Orchestration
  • Data
    • Database
    • SQL
    • Mining
    • Warehouse
    • Stream
    • In-memory
    • Big Data
    • NoSQL
  • Experience

Topics

  • OS
  • Web
  • Mobile OS and Internet
  • Cloud Service
  • IoT / Hardware
  • Embedded System
    • MCU
    • SoC

Windows激活本地admin

传统的组策略(group policy)

1
gpupdate /force

dsregcmd: diagnose and manage device registration with Microsoft Entra ID (formerly Azure AD)

PRT: Primary Refresh Token

1
2
3
dsregcmd /status

dsregcmd /refreshprttoken

检查账号信息

1
2
3
whoami /groups

whoami /priv

常规操作:重启;重新登录;重连网络;重启windows explorer。

What's difficult?

在中文里有几层意思

difficult

它表示事情不容易完成或者不知道怎么做。

hard

它表示需要很大努力。

复杂

complex表示结构性复杂;complicated表示难以理解或处理。More is different。

反义词

与“难”相对的就是easy或者simple

能量守恒

Effort守恒

  • No pain, no gain
  • Hard work pays off
  • No free lunch

问题守恒

  • Problems never disappear, they just change form.
  • Solving one problem often creates another.
  • There’s no end to problems, only transformations.

矛盾总是存在的,变化的。

生成容器镜像的几种方式

commit

commit可能是最简单直白的方法。

  1. 运行一个容器
1
2
3
4
5
6
7
8
$ docker run \
-it \
-u 1000 \
-h foo-host \
-v foo-tmp-volume:/workspaces/tmp \
-w /home/ubuntu \
--name foo-ubuntu \
myubuntu:latest
  1. commit从容器创建新镜像
1
2
3
4
5
6
$ docker commit \
-a "Bill Dong" \
-c "CMD [ \"/bin/bash\" ]" \
-c "LABEL foo=bar" \
-m "foo-ubuntu-image init" \
foo-ubuntu foo-ubuntu-image:latest

save / load

save将镜像保存至tarball,包括元数据;load将tarball装载成镜像。

export / import

export将容器的文件系统导出至tarball,不包括元数据;import将tarball导入成文件系统镜像。

注意:该操作可以将多层文件系统变成一层;导入时可能会丢失CMD之类的信息,使用-c选项设置。

build

build是推荐的方法。

  1. 写一个Dockerfile
1
2
# FROM scratch
FROM myubuntu:latest
  1. 构建镜像
1
$ docker build .

git:如何更新main分支

fetch - Download objects and refs from another repository

1
git fetch --prune --all
1
2
git switch main
git fetch [origin] [main]
1
git fetch origin main:main

pull - Fetch from and integrate with another repository or a local branch

1
2
3
git switch main
git pull [origin] [main]
git pull --rebase

merge - Join two or more development histories together

1
2
git switch main
git merge origin/main

rebase - Reapply commits on top of another base tip

1
2
git switch main
git rebase origin/main
1
git rebase origin/main main
1
2
3
git rebase --onto <newbase> <upstream> <branch>
# <newbase> default: <upstream>
# <branch> default: HEAD

branch - List, create, or delete branches

1
git branch main

switch - Switch branches

1
git switch -c main

restore - Restore working tree files

checkout - Switch branches or restore working tree files

1
git checkout main

reset - Reset current HEAD to the specified state

1
2
git switch main
git reset origin/main

Basic Settings for Linux

apt

  • apt-get update
  • git (config)
  • vim
  • tree
  • mlocate (updatedb)
1
2
sudo apt-get update
sudo apt-get install build-essential git vim tree plocate

bash

  • bashmy
  • bashrc
1
git clone https://github.com/forestdbin/code-snippet.git

vim

  • update-alternatives
  • vimrc
1
sudo update-alternatives --config editor

sudo

1
2
# visudo
%sudo ALL=(ALL:ALL) NOPASSWD:ALL

vmtools