微前端概要
微前端是什么?微前端是一种前端开发的架构风格,它将一个完整的前端应用拆分成多个小型的、独立的功能模块,这些模块被称为微前端。每个微前端都可以有自己的代码库、依赖包、自动化测试套件以及Devops流程。它们中的每一个极有可能由一个单独的前端团队负责,并且与其他功能模块相互独立地进行开发、测试和部署,从而提高了开发流程的效率。微前端在平台产品中应用尤为广泛。例如云计算平台中的各个服务可以通过微前端的方式嵌入到云平台前端控制台中。
微前端的优缺点优点:
独立开发和部署:每个微前端可以由不同的团队负责,团队可以自主决定开发进度和发布时间,无需与其他团队过度协调。比如一个专门负责用户个人中心微前端的团队,可以独立进行功能迭代和发布。
技术栈灵活:不同的微前端可以根据自身需求选择不同的技术栈。例如,一个微前端可以使用 React 框架,另一个可以使用 Vue 框架,这样可以充分利用各种技术的优势。
可扩展性强:能够根据业务需求,方便地添加、删除或更新微前端模块。当业务需要增加新功能时,只需要开发新的微前端并集成到系统中即可。
缺点:
微前端架构本身比单体架构复杂得多。需要设计合理的集成 ...
Kubernetes复习笔记
Kubernetes要解决什么问题?手动部署容器难以维护,使用容器编排技术可以解决如下问题:
容器崩溃的时候可以自动部署新的容器来代替
可以自动增加或者减少容器的数量来满足高可用和自动伸缩的需求
可以使用负载均衡来将流量分配到不同的容器中
不依赖于云服务提供商的通用配置
Kubernetes核心概念及架构Kubernetes架构图
Work node架构图
Master node架构图
Pod: kubernetes管理的主要对象,可以由一个或者共享资源的一组容器组成kubelet: 管理worker node和master node之间的通信kube-proxy: 运行在work node上,用于管理Node和Pod的网络通信API Server: 提供API服务Scheduler: 选择worker node运行PodController: 监控Pod数量,控制worker nodeWorker node: 运行Pod的机器或者虚拟机Master node: 运行Control Plane的机器或者虚拟机
Kubernetes核心对象
Pod: Kubernetes管理的最小单 ...
Python中常用的数据结构
用deque实现队列主要特点和优势:
高效的两端插入和删除操作:与列表相比,在队列的两端进行添加或删除元素的操作效率更高。时间复杂度为O(1),而在列表的开头进行插入或删除操作的时间复杂度通常为O(n),其中是列表的长度。
支持线程安全的追加和弹出:在多线程环境中,可以使用 deque 的 append 和 pop 方法,并且它们是线程安全的(需要适当的同步机制确保整体操作的线程安全)。
可设置最大长度:可以创建一个具有固定最大长度的 deque,当添加新元素超过最大长度时,会自动从另一端删除旧元素。
常用方法:
初始化:12d = collections.deque() # 创建一个空的双向队列。d = collections.deque([1, 2, 3]) # 用初始元素创建双向队列。
添加元素:12d.append(item) # 在队列右端添加一个元素。d.appendleft(item) # 在队列左端添加一个元素。
删除元素:12d.pop() # 删除并返回队列右端的元素。d.popleft() # 删除并返回队列左端的元素。
扩展队列:12d.ext ...
算法-动态规划
动态规划是一种解决多阶段决策过程最优化问题的数学方法。通常需要保存决策路径的问题用回溯法,而只是求最优解的时候选择动态规划。
基本概念
定义:动态规划通过把原问题分解为相对简单的子问题,并保存子问题的解,避免重复计算,从而高效地求解复杂问题。它通常适用于具有最优子结构和子问题重叠性质的问题。
最优子结构:一个问题具有最优子结构意味着问题的最优解可以由子问题的最优解组合而成。例如,在求解最短路径问题中,从起点到终点的最短路径可以由从起点到中间点的最短路径和从中间点到终点的最短路径组成。
子问题重叠:子问题重叠是指在求解问题的过程中,会多次重复地求解相同的子问题。动态规划通过保存子问题的解,避免了重复计算这些子问题,从而提高了算法的效率。
解题步骤
确定问题的状态:状态是描述问题在不同阶段的特征。选择合适的状态表示是动态规划的关键。例如,在背包问题中,可以用背包的剩余容量和已选物品的集合来表示状态。
定义状态转移方程:状态转移方程描述了如何从一个状态转移到另一个状态。它通常是根据问题的最优子结构性质推导出来的。例如,在背包问题中,状态转移方程可以表示为:dp[i][j] = max(dp ...
Python中的位图
在 Python 中,位图(Bitmap)是一种用于表示二进制数据的数据结构。它可以高效地存储和操作大量的布尔值(True/False)。
位图的基本概念位图通常由一个字节数组或位序列组成,其中每个位表示一个特定的状态或属性。例如,可以使用位图来表示一组整数是否存在于某个集合中,或者表示某个图形中的像素是否被选中。
Python 中实现位图的方法
使用内置的bytearray类型
bytearray是一个可变的字节序列,可以用来存储位图数据。每个字节可以表示 8 个位,通过位操作可以设置、清除和检查特定的位。例如:
12345bitmap = bytearray(10) # 创建一个可以存储 80 个位的位图# 设置第 5 个位为 1bitmap[5 // 8] |= 1 << (5 % 8)# 检查第 5 个位是否为 1is_set = (bitmap[5 // 8] & (1 << (5 % 8)))!= 0
使用第三方库bitarray库提供了一个更方便的位序列数据结构,可以高效地进行位操作。安装:pip install bitarray例 ...
Python中的collections
在 Python 中,collections是一个非常有用的内置模块,它提供了一些高性能的数据类型,可以帮助你更高效地处理数据。
namedtuple命名元组是一种可以为元组中的每个元素指定名称的数据类型。这使得代码更加可读,并且可以像访问对象属性一样访问元组的元素。
12345from collections import namedtuplePoint = namedtuple('Point', ['x', 'y'])p = Point(1, 2)print(p.x, p.y)
deque双端队列是一种可以在两端进行高效插入和删除操作的数据结构。它比列表更适合用于实现队列和栈。
123456from collections import dequedq = deque([1, 2, 3])dq.append(4)dq.appendleft(0)print(dq)
Counter计数器是一种用于统计可哈希对象出现次数的数据类型。它可以方便地统计列表、字符串等数据中的元素出现次数。
1234from collections ...
用环形缓冲区实现循环日志
环形缓冲区在数据结构中是一种特殊的线性数据结构,具有以下特点和优势:
结构特点
固定大小:环形缓冲区通常具有固定的容量,一旦创建,其大小就不能改变。这使得在内存使用方面更加可控,避免了动态分配内存带来的开销和不确定性。
循环利用空间:正因为其环形的特性,当写指针到达缓冲区的末尾时,会自动回绕到开头继续写入数据;读指针在读取完数据后也会相应地移动,实现空间的循环利用。
操作方式
写入操作:当向环形缓冲区写入数据时,首先检查缓冲区是否已满。如果未满,则将数据写入写指针所指的位置,然后写指针向前移动一位。如果写指针移动到缓冲区的末尾,它会回绕到开头。
读取操作:从环形缓冲区读取数据时,先检查缓冲区是否为空。如果不为空,则读取读指针所指位置的数据,然后读指针向前移动一位。同样,当读指针到达缓冲区的末尾时,会回绕到开头。
应用场景
实时数据处理:在需要对连续产生的实时数据进行处理的场景中,环形缓冲区可以作为数据的暂存区域。例如,音频和视频流的处理,数据采集系统等。
多生产者 - 多消费者模型:环形缓冲区可以方便地在多个生产者和多个消费者之间共享数据。生产者将数据写入缓冲区,消费者从缓冲区读取 ...
数据结构-链表
链表(Linked List)的基本概念链表是一种常见的数据结构,它由一系列节点(Node)组成。每个节点包含两部分:数据部分和指向下一个节点的指针(Pointer)。链表通过这些指针将节点按顺序连接在一起。
链表的类型
单链表(Singly Linked List):每个节点只有一个指针,指向下一个节点。
双链表(Doubly Linked List):每个节点有两个指针,一个指向前一个节点,一个指向下一个节点。
循环链表(Circular Linked List):单链表或双链表的最后一个节点的指针又指向了链表的头节点,形成一个环形结构。
链表的基本操作
创建链表:首先创建头节点(Head Node),然后逐个添加后续节点。
插入节点
在头部插入:创建新节点,将新节点的指针指向原头节点,然后更新头节点为新节点。
在中间插入:找到要插入位置的前一个节点,创建新节点,将新节点的指针指向插入位置的节点,然后将前一个节点的指针指向新节点。
在尾部插入:找到链表的尾节点,创建新节点,将尾节点的指针指向新节点,并将新节点的指针设为 None。
删除节点
删除头节点:将头节点指向下一个节 ...
数据结构-哈希表
哈希表(Hash Table)的基本概念哈希表是一种数据结构,它可以在平均情况下提供非常快速的插入、删除和查找操作。其基本思想是通过一个哈希函数将键(key)映射到一个特定的索引(index),然后将对应的值(value)存储在该索引位置。
哈希函数(Hash Function)
哈希函数是哈希表的核心,它将输入的键转换为数组的索引。例如,对于一个简单的整数键的哈希函数可以是hash(key) = key % array_size,这里array_size是存储数据的数组的大小。
一个好的哈希函数应该尽量减少冲突(Collision),即不同的键被映射到相同的索引位置。常见的哈希函数构造方法包括直接定址法、除留余数法、数字分析法、平方取中法、折叠法、随机数法等。
处理冲突(Collision Resolution)
链地址法(Chaining):当发生冲突时,在该索引位置创建一个链表,将新元素添加到链表中。这种方法简单且易于实现,但在最坏情况下,查找时间可能会退化到O(n),其中n是链表的长度。
开放定址法(Open Addressing):当发生冲突时,按照某种规则在哈希表中寻找下 ...
数据结构-栈
栈(Stack)的基本概念栈是一种重要的数据结构,它具有后进先出(Last In First Out,LIFO)的特点。可以把栈想象成一叠盘子,最后放上去的盘子会最先被拿走。
栈的基本操作
入栈(Push):将元素添加到栈的顶部。
出栈(Pop):从栈的顶部移除一个元素。
查看栈顶元素(Peek 或 Top):获取栈顶元素的值,但不移除它。
判断栈是否为空(IsEmpty):检查栈中是否有元素。
栈的应用场景
表达式求值:在算术表达式求值中,栈可以用于处理运算符的优先级和括号的匹配。例如,将中缀表达式转换为后缀表达式,然后利用栈进行求值。
函数调用栈:在程序执行过程中,当一个函数调用另一个函数时,当前函数的执行状态会被保存到一个栈中(函数调用栈)。当被调用函数执行完毕后,从栈中恢复上一个函数的执行状态继续执行。
括号匹配:在编译器和文本编辑器中,栈可以用于检查括号是否匹配。例如,在检查一段代码或者一个数学表达式中的括号是否成对出现且匹配正确时。
撤销(Undo)操作:在许多软件应用中,撤销操作可以通过栈来实现。每次执行一个操作,该操作的信息被压入栈中。当需要撤销时,从栈中弹出最近的 ...