0%

5.1 关联#

设计领域模型时, 确定每个领域对象之间的关联非常重要。

  • 双向关联:两者互相引用

  • 单项关联:谁持有谁。 例如“美国总统”包含了“华盛顿”、“奥巴马“。 一般是一对多的情况。

设计上没必要让奥巴马去指向美国,因为奥巴马只能是一个国家的总统, 我们不需要通过奥巴马的身份去获知它属于哪个国家的总统,

即我们一般有county.getPresident() 而不会有 president.getCountry()。 (当然并不是说不存在查询人的国家,只是对于当前这个总统系统来说,没必要,并不是全球人口普查系统)

  • 限定的关联:某个特定条件下的单向关联。 例如 1790年的美国总统是华盛顿, 这里国家+时间周期 ->总统

    对应代码就是 Person person = country.getPresident(period)

    书里的另一个例子: account.getInvestment(String stock) 股票系统里,每个股票对应一个投资。

假设大数据集群里有很多的节点组,节点组里有很多的节点

我们不需要给他们画双向箭头, 那应该都是单向的。

如果不存在指定关系,则不用加限定。

5.2 实体Entity(又称 ReferenceObject)#

一个对象并不是由它的属性定义的, 因为它的属性在生命周期中可能会变化。 而且不同对象的属性可能相同。

因此定义对象的核心是“标识”。

被标识定义的对象叫做Entity实体。

实体要满足的2个条件:

  1. 它在整个生命周期中具有连续性
  2. 它的区别并不是由哪些对用户非常重要的属性决定的。

并不是所有事物都需要标识。

比如2笔500元的银行流水, 他们的流水号代表了是不同的流水, 而500元这个金额则没必要加标识。

标识在设计中也要确认一下是否有用。

比如 演唱会如果指定位置,则座位就必须有一个座位号标识用于识别门票上的座位

但如果演唱会不指定位置,先到先得,那么座位就仅仅代表了一个位置, 不需要标识,也就不代表是一个实体。

5.2.1 entity建模#

在核心实体中,添加和核心实体强一一关联的属性或者行为。

即如果可以通过某1-x个属性,能直接关联到这个实体,那么这个核心属性可以放到实体中。

比如可以通过姓名加电话,唯一定位到一个人的画,那应该放在人实体里作为属性(这样可以后面用来getPeople(phone, name) 来获取一个唯一人)

但如果人有多个电话,而且给了不同的人留下了不同的电话, 那么电话要从人的属性里删去, 放到另一个新的实体“联系人”中, 联系人中记录了每个人对每个人的联系方式。

最常见的entity标识经常用UUID自动生成实现。 但有时候客户可能不想看到ID, 只想根据例如名字、地点确定某一个事物,则

如果多个系统间要共用某个实体,担心各自生成ID的话会有问题,可以借助第三方机构来生成。例如2个医院之间病人想互通,则一般用身份证号来作为实体核心,而不会用医院病历号来区分。

5.3 值对象ValueObject#

为所有的实体都加上唯一标识,会影响系统性能增加分析工作量,使模型变得混乱。

因此在系统里可以不需要标识的对象, 称之为 值对象(ValueObject)

我们只关心他们是什么, 不关心他们是谁。

比如节点规格就是一个值对象。

对于地址, 如果是邮寄系统, 地址仅仅是一个值对象。 但如果是电力系统,要根据地址单独收费,则地址是一个实体。

时间太久, 大致剧情有点忘记了, 但记得还是挺精彩的,中间的还原和推理都挺有难度, 北原千叶为了洗刷自己的罪名以及复仇, 付出了太多, 尤其是最后揭晓某个老头真实身份的时候还是挺震撼的。 可惜这一次之后我就好久没怎么玩了, 也不太懂地怎么和一起玩了2次的车友保持长久联系。

故事讲述了一个 天才数学青年 被 某个心理医生疗愈的过程。

我是抱着挺大的期待来到这个露天电影的地方来欣赏心理名作,结果全程无法带入任何一方。

1685284438277

剧中说男子有心理问题,害怕改变和暴露自己, 但他却能很好地撩妹当现充, 学习时间没有别人长的情况下却能有惊人的开挂天赋, 让人无法理解和同理。只感觉他是他,我是我, 他的烦恼独一无二,无法给我带来任何共鸣。

另外,剧中对男主的心理疗愈和突破也挺突兀。 好像转折点就是他的好友和他说要离开他了,不是一路人, 以及心理医生发生他的过去, 然后男主到医生怀里痛苦了一阵,医生反复说:“这不是你的错” 之后, 男主一下子就醒悟了?不瞎搞事情了,突然正能量了,开车去追求女孩子了。 我当时是满脑子问号, 愣是没看到心理医生任何有建设性、突破性的话语让他醒悟之类的场景。

可能我所期待的心灵捕手,是治愈所谓社恐、自卑等性格的故事,但显然这个故事并不一样,不知道过几年如果重看的话会不会有其他的感受

1685284448534

[toc]

使用PlantUml绘图#

我: 请将下面引号内的这段文字转成一个PlantUML流程图,将容器演进的6个阶段拼成一个历史发展图并体现各个阶段的特点,图中表达的特点要求不要太啰嗦提炼关键点

不是表格形式, 而是在流程图每个阶段的旁边加上类似标注的文字,显示这个阶段的特点

流程图里的字体能使用微软雅黑字体,并尽可能比默认字体稍微大一点

以下是需要转plantUml的文字内容:

“…”

GPT:

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

skinparam shadowing false
skinparam defaultFontName "微软雅黑"
skinparam defaultFontSize 14

title 容器演进历史发展

start
:隔离文件:chroot;
note right: 1979年unix提供,进程根目录被锁定在指定参数位置,实现基础的文件隔离
:隔离访问:名称空间;
note right: 2022年引入linux名称空间,进程在独立的名称空间中享有独立的资源
:隔离资源:cgroups;
note right: cgroups用于隔离或分配进程可使用的资源,如处理器、内存、磁盘IO速度等
:封装系统:LXC;
note right: LXC是系统级虚拟化功能,封装整个系统,但修改系统组件需要重写配置
:封装应用:Docker;
note right: Docker基于LXC,使用libcontainer避免对LXC的依赖,支持跨机器绿色部署、以应用为中心的封装、自动构建等
:封装集群:Kubernetes;
note right: Kubernetes是容器编排框架,虚拟化集群环境,实现跨数据中心的绿色部署和自动扩缩
stop

@enduml

plantUml用法:

使用简单的文字描述画UML图的开源工具。 (plantuml.com)

IDEA里安装插件进行绘图

1684799441667

1684799451369

也有在线版的转换,但是在线版对中文的显示有点问题

PlantUML Web Server

[toc]

[toc]

儿童自我状态:

  • 自然型儿童

    自然型儿童具有几种基本情感:

    快乐、愤怒、悲伤、恐惧

    无论人多大年纪,都可能会切换成自然型儿童状态

  • 适应型儿童

​ 当孩子无法离开父母,应对父母的喜怒无常时, 通常会选择去适应,调整自己的行为并形成一套“生存策略”、

顺从行为可能导致有些人学会了把依赖当成生活方式,没有真正长达承认

不恰当地表达愤怒,会对自己和他人造成伤害。 怄气、生闷气也是一种愤怒

“父母自我状态”,指从父母那边学习到了挑剔、指责别人的自我状态, 并一直复用到生活中对其他人的态度上。

另外不指责他人的自卑者不代表就没有“父母自我状态” ,他们的父母自我状态所指责、挑剔的对象很可能就是自己

只有在成人自我状态下,人才能学习到关于自我的新的知识。

当我们处于父母状态或者儿童状态的时候,是从来不会去思考的,都是像条件反射一样的去行事。

我们不再被父母过去的声音所驱使,也不会被童年的情绪所困扰,我们能够基于现实去思考当下来怎么做。

成人自我状态指我们用理性而不是情绪化的方式来行事,它能让我们能应对此时此地正在发生的现实状况。

当我们为了自己的不快乐去怪罪到别人的时候,我们要考虑一个选择,就是我们要为自己的不快乐去责怪别人多久到什么时候,我们要在原地停留到什么时候。

就像有人愤怒,有人生气发火,这些都是他们基于父母状态或者儿童状态所进行的一种表演。他们自己选择了愤怒,没有任何人能够逼迫对方去产生什么情绪,产生情绪的主体永远是自己,而自己会产生情绪主要是因为自己正在扮演父母或者儿童的角色,然后条件反射的形式。

[toc]

说服过程: 拒绝->肯听你说话->考虑你的话->愿意照做->真的去做->开心的做

讲了一个自杀者的例子, 谈判专家将对方心里想说的话给说出来,获取对方的认同, 关键在于告诉对方对方自己究竟在想什么

正确的措辞有强大的治愈力量

人的大脑有三个层级: 爬虫级(下意识)、 哺乳动物级(情感)、 人级(理性)

如果人陷入杏仁核劫持状态,会导致人级思考区域关闭, 一直处于下意识逃避或者抗拒的状态以保护自身的安全。

镜像神经元: 也叫同理心神经元, 能够在别人有情绪时,自己也同样感受到类似的情绪或者感觉。

镜像神经元接受匮乏: 当自己表达了情绪时, 对方的镜像神经元似乎从来没有成功接收过,每次都没有感受到自己的情绪。

理解他人的渴望,并作出回应,相当于能改善对方的镜像神经元匮乏现状,变得更愿意接触你,开放他的理性大脑。

[toc]

2023-05-23#

1090. 受标签影响的最大值 - 力扣(Leetcode)

题意没搞清,白搞半小时

搞清题意后其实很简单,先按values大小排序,再从最大处逐个取,如果对应标签数量已经满足阈值就跳过,其实就是用到了排序和哈希而已。

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
class Solution {
public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {
Map<Integer, Integer> lableCountMap = new HashMap<>();
Map<Integer, Integer> indexToLableMap = new HashMap<>();
List<Integer> indexs = new ArrayList<>();
for(int i = 0; i < labels.length;i++) {
indexToLableMap.put(i, labels[i]);
indexs.add(i);
lableCountMap.put(labels[i], 0);
}
Collections.sort(indexs, (a,b)->values[b] - values[a]);

List<Integer> res = new ArrayList<>();
for (int index : indexs) {
if (res.size() >= numWanted) {
break;
}
int label = indexToLableMap.get(index);
if (lableCountMap.get(label) >= useLimit) {
continue;
}
lableCountMap.put(label, lableCountMap.get(label) + 1);
res.add(values[index]);
}

return res.stream().mapToInt(Integer::intValue).sum();
}
}

2023-05-22#

1080. 根到叶路径上的不足节点 - 力扣(Leetcode)

树的后序遍历应用题目

不管咋做,反正只要知道后序遍历,后面就都好办。

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
class Solution {
public TreeNode sufficientSubset(TreeNode root, int limit) {
// 后序遍历
long res = postDfs(root, 0, null, limit);
if (res < limit) {
return null;
} else {
return root;
}
}

long postDfs(TreeNode node, long parentVal, TreeNode parent, int limit) {
// 用于下面的非叶子节点计算,可能会走到这个null
if (node == null) {
return Integer.MIN_VALUE;
}
long sonValMax;
// 叶子节点提前判断一下
if (node.left == null && node.right == null) {
sonValMax = 0;
} else {
// 非叶子节点计算
long leftMaxVal = postDfs(node.left, parentVal + node.val, node, limit);
long rightMaxVal = postDfs(node.right, parentVal + node.val,node, limit);
sonValMax = Math.max(leftMaxVal, rightMaxVal);
}

// 判断自己是否要被删除
if (parent != null && parentVal + sonValMax + node.val < limit) {
if (parent.left == node) {
parent.left = null;
} else {
parent.right = null;
}
}
return sonValMax + node.val;
}
}

2023-05-21#

LCP 33. 蓄水 - 力扣(Leetcode)

这题说是简单题,但是好难,没仔细看条件数量仅有100个桶,而且是一起倒水,水缸没上限

那么可以做枚举,枚举出倒水次数,然后再倒推出每个桶需要增加多少水,即可得到这一次枚举后的总操作数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int storeWater(int[] bucket, int[] vat) {
int res = Integer.MAX_VALUE;

if (Arrays.stream(vat).allMatch(v->v==0)) {
return 0;
}

for (int pushCount = 1; pushCount <=10000; pushCount++) {
int bChangeCount = 0;
for (int i = 0; i < bucket.length;i++) {
int b = bucket[i];
int v = vat[i];
int newB = v / pushCount + (v%pushCount == 0 ? 0 : 1);
int needB = Math.max(newB - b, 0);
bChangeCount += needB;
}
res = Math.min(bChangeCount + pushCount, res);
}
return res;
}
}

改进点:

pushCount的边界条件, 可以是

1
pushCount <=maxv && pushCount < res

核心是<res时, 可以提前退出了

[toc]

容器间网络#

此章节主要介绍容器之间的网络究竟是如何模拟和通信的

1 linux网络虚拟化#

1.1 网络协议栈#

网络设备->driver->Device->IP->TCP/UDP->Socket->File->接收端
反过来同理

1.2 linux干预网络通信的方式#

linux中有一个netfilter框架, 可以在网络的五个阶段埋入钩子进行函数回调

  • PREROUTING: 数据包进入协议栈码上触发
  • INPUT:经过IP路由后,如果确定是发往本机的,将会触发钩子
  • FORWARD: 不是发往本机的,只是中间路由,触发钩子
  • OUTPUT:发出时经过路由前触发
  • POSTTROUGIN: 发出时触发,用于NAT

对netfilter应用的一个经典命令是iptalbes命令,里面内置的五个iptables规则表和filter钩子存在对应关系。

k8s的kube-proxy也是依赖iptables完成从clusterIp到Pod的通信。

1.3 虚拟网络设备#

1.虚拟网卡:tun/tap、veth#

tun可以模拟网络层设备操作ip数据包
tap可以模拟一位网设备操作链路层数据包

具体原理是 在网络协议栈 和 下一层物理网卡之间, 嵌入了tun或者tap,他们可以把数据转发给对接的应用程序,处理完成后再重新放进协议栈流动
vpn就是这样处理的。

缺点是要经过2次网络协议栈, 因此另一种网卡实现方案是veth。
veth是一对设备也叫veth pair, 假设有2个网络命名空间, 有2个协议栈,则各自空间中都有一个vethx, 可以让数据从设备的另一端原样不动的流出, 可以模拟网卡直连从解决容器间的通信问题

缺点:veth pair的转发是要写死目的地址的, 如果有多个容器间要交互就需要很多pair,因此需要后面的虚拟交换机

2. 虚拟交换机linux Bridge#

容器自身的veth虚拟网卡迟早得接入到物理网卡, 1台宿主机上有多个容器但物理网卡有限,物理网卡怎么知道对应关系呢?
这时候就可以用linux bridge,当有二层数据包(链路层以太帧)从网卡进入linuxBridge时,将根据数据包的类型和目标MAC地址, 选择广播或者单播或者发给自身。

可以理解为在物理网卡和容器虚拟网卡之间,加了一层下图所示的br0进行地址切换或者映射转发。

image.png

3. 虚拟网络VXLAN#

很早就有虚拟局域网VLAN, 可以进行同一个物理区域范围内的广播域划分,通过在以太帧里加入VLAN tag。
但是VLAN的缺陷在于tag设置的位数太小,导致不够用。
于是后来EFTF定义了VXLA能规范, 做了报文封装支持扩展, 需要有VTEP设置对VXLAN协议做封包和解包。

通过VXLAN可以实现 容器间网络的虚拟划分。

4. 副本网卡MACLAN#

如果希望在同一个物理网卡上, 针对不同的VLAN绑定不同的IP地址, 可以使用子接口, 而MACVLAN就是借用了VLAN子接口的思路, 支持为同一个网卡设置多个IP地址以及多个MAC地址。

用MACLAN虚拟出来的副本网卡,和真实网卡在功能上基本对等

真实网卡收到数据报,根据目标MAC地址判断包应该转发给哪块副本网卡处理, 副本网卡处于同一个VLAN中可以直接在链路层通信无需转发给外部网络由路由跳转。,
image.png

1.4 容器间通信#

docker有三种网络模式:

  • 桥接模式(–network=bridge):为容器分配独立的名称空间,加入网桥的容器可以直接依靠链路层层网络通信
  • 主机模式(–network=host):直接使用宿主机上的网络设置和名称空间,性能高但是容易端口号冲突,没有网络隔离
  • 空置模式(–network=none):只能看到一个换回地址,无网络设备
    还支持自行创建的网络模式
  • 容器模式(–network=container:容器名称)
    新创建的容器会加入指定的容器网络名称空间,只共享网络资源
  • MACVLAN模式(docker network create -d macvlan)
    为容器创建副本网卡, 通过副本网卡的MAC地址来使用宿主机上的物理设备,性能很好
  • Overlay模式(docker network create -d overlay)
    就是VXLAN,很少使用。

2 容器网络生态#

这里主要讲了 docker定义的CNM(container network model) 和 k8s定义的CNI(container network interface)的历史, 两个容器网络模型最终是CNI胜出,CNI支持多种网络插件可以介入不同的网络。
CNI有以下三种经典跨主机网络模式,各有一些代表CNI插件

  • overlay模式
    虚拟化的上层逻辑网络
    Flannel 、 Calico、weave等插件
  • 路由模式
    跨主机通信由路由来转发
  • Underlay模式
    让容器和宿主机处于同一个网络,二者拥有相同地位,容器网络能直接与底层网络进行通信。 包含MACVTAP插件。

性能上MACVLAN和SR-IOV这样的underlay网络插件性能最高,但是通用性和灵活性会有折扣

宇宙探索编辑部,看电影介绍以为是一部科幻电影,却用非常朴实接地气的镜头,呈现了一个近乎偏执的民科杂志编辑部长探索人生存在意义的故事。

在旁人眼中,唐志军只是一个没长大的中二病,追求着不切实际的东西。

但老年的他为什么如此偏执,我理解是还是受他抑郁症女儿的影响,他的女儿提问到“我们人类存在的意义是什么”。他发现自己无法回答这个问题,非常痛苦,于是把所有希望寄托在外星人的身上。

这也是为什么最后在山洞里,他希望孙一通能帮忙回答这个问题。

最后孙一桶在吟诗的过程中化作被麻雀包围的球体飞走, 这个场景过于魔幻,可以有很多个解读,比如幻觉说、真实外星人说。 但最关键的是, 孙志军从最后这个场景中,究竟感受到了什么,才在之后愿意参加外甥的婚礼,愿意解散杂志社去抑郁症的公益活动、

我是经常会思考,我工作的意义是什么, 我生活的意义又是什么。 有时候发现无法解答时,会把答案希望寄托在未来一个不可能的时刻。

就像我现在写这篇文章之前,也会质问自己,我写这文章有什么意义呢?会有人看吗?能给大家带来什么价值?

其实关于意义的问题,经典的回答就是“存在的本身就是意义”。 但是这个回答也很残酷,因为这种答案没办法让人有一种解脱或者拯救的感觉。他们希望的是一个能够让自己持续奋斗到生命终结的意义的答案。

那么,究竟是什么点醒了唐志军?

我不明白,于是给chatGpt讲述了这个故事,人工智能给出了它的回答:

唐志军的转变可以被理解为他在经历一系列的事件和思考后逐渐接受了现实,并放下了对外星人存在的追求,开始重新审视和珍惜自己的生活。

在他女儿离世前给他留下的问题中,她表达了对人类存在意义的困惑,这是一个深刻的哲学问题,没有简单的答案。唐志军希望外星人能够回答这个问题,可能是因为他相信外星人拥有更高级别的智慧和洞察力,能给予他答案。

然而,当他遇到能感应外星人的少年时,少年提出了一个反问,即外星人是否也对这个问题感到困惑。这个问题启发了唐志军思考,意识到人类自身对于存在的意义并没有明确的答案,无论是人类还是外星人都可能面临这个困惑。

接着,唐志军目睹少年被麻雀覆盖并飞走,这一经历可能是他对追求外星人真相的象征性结束。少年告别时说:“老唐,我就到这了”,意味着唐志军不再需要继续追寻外星人,他已经完成了自己的使命。

这些经历和反思引起了唐志军内心的转变。他回归到现实生活中,参加外甥的婚礼,解散了外星人杂志社,参与公益活动,这些行为显示了他开始重新关注并投入到真实的人际关系和社会活动中。

当他在公益活动中念诗并哭泣时,这表明他通过对生活的思考和体验,对自己与女儿之间的关系以及对生命的意义有了更深刻的认识。这可能意味着他找到了自己在人类存在中的意义,即通过爱与关怀他人来感受和传递人类存在的美好。

虽然故事没有明确表达出"人类存在的意义"的具体答案,但唐志军的转变展示了一个人在面对困境和追求过程中如何逐渐找到内心的平静和意义。他逐渐接受了现实,并从追求外星人的梦想中解脱出来,重新投入到与人类和社会的联系中。这种转变强调了在人类之间建立关系、关怀他人以及感受和传递爱的重要性,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
一望无际的梦里
用碗里的米垒墙
乌云写满咒语
遮住众生疲惫的骨头

狐狸在山坡念念有词
灶台上的年兽反复冬眠
晨昏线割开大地的指纹
水草缠住风 冻结梦境的递归

胸口的鸟群
绕过十万个太阳
带走被浇灭的闪电
带走云层潮汐
带走神明的悄悄话
带走落地生根的锚
带走氧化的情歌 带走山野恩仇
带走金银财宝 带走痴心妄想
带走梦游的脚印
带走飞蛾扑不灭的火
带走所有人的名字
带走彩虹的化石