- 博客(57)
- 收藏
- 关注
原创 设计模式(4)行为模式
行为模式1. Chain of Responsibility Pattern(责任链模式)2.Command Pattern(命令模式)3.Interpreter Pattern(解释器模式)▲4.Iterator(迭代器模式)5.Mediator(中介者模式)6. Memento(备忘录模式)7.Observer Pattern(观察者模式)8. State Pattern(状态模式)9. Strategy Pattern(策略模式)10.Template Method Pattern(模板方法模式)11
2025-01-17 14:49:37
1100
原创 设计模式(3)结构型模式
现在有一个简单的字符文档编辑器,面向对象的做法通常是使用对象来表示嵌入的成分,因此我们首先想到的是用对象来表示文档中的每个字符,这会极大的提高程序的灵活性(例如当字符有不同字体,或者颜色时)。抽象类定义抽象接口,而具体的子类给出不同的实现。定义了包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复杂的组合对象,而这个对象又可以被组合,这样不断的递归下去。通俗点来说就是,定义包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,并且可以这样不断递归。
2024-08-21 15:44:53
1223
原创 设计模式(2)创造型设计模式
创建型模式工厂模式简单工厂模式//下面两个个类继承Pizza ,也就说披萨工厂一共生产两种pizzaclass CheesePizza;class GreekPizza;class Pizza;//asbtract/* * 通过工厂类创建(实例化)两种pizza* 缺陷:如果需要增加新的种类的披萨,需要修改工厂类,增加一种条件判断,违反了闭合原则(对扩展是开放的,对修改是关闭的)*/class SimplePizzaFactor{public: Pizza* createPi
2024-05-06 15:37:53
1021
2
原创 UNIX环境编程-文件纪要
例如,当程序文件的所有者是超级用户时,设置文件的该权限位后,当程序文件被一个进程执行时,该进程具有超级用户的权限。有一个值为O_SYNC的文件状态(可以跳过缓存,一般数据库程序就会用到),使得每次write文件时,都需要等待数据实际写到磁盘上才返回(未设置该状态的情况下write采用的是延时写策略)。当文件设置的偏移量超过文件的大小,并写入一些数据后,就会造成文件空洞(文件空洞要结合文件在磁盘上存放在不连续的块中来理解)。表示获取或设置文件状态(文件表项中的文件状态标志,包括只读、只写、读写、异步等等)。
2024-01-12 09:34:53
928
2
原创 UNIX环境编程-进程纪要
伪终端,指的是对一个应用程序而言,它看上去像一个终端,但事实上它并不是一个真正的终端。IO复用配合非阻塞IO可以在一定程度上提升效率,但是会大大增加编码的难度(需要充分考虑接受数据时缓冲区的问题),使用IO复用配合多线程更好(视情况而定)。信号排队:在信号屏蔽期间,如果信号多次被递送到进程,则对于不支持排队的信号来说,只会对信号处理一次;并且在函数返回时恢复之前的信号屏蔽字(mask临时设置信号屏蔽字)。由于第3步和第4步不是原子的,则有可能在3、4步之间发生信号的丢失,第4步将永久等待下去。
2024-01-12 09:34:29
1006
原创 UNIX网络编程-纪要
stdio库带有缓冲区,例如,文件有数据可读时(select准备就绪),使用stdio读取数据,文件中有2条数据,2条数据都已经读到了stdio的缓冲区,但是使用时只用到了第一条数据,用完之后继续使用select去等待数据可读,这时select不会管缓冲区中是不是还有数据,而是继续去等待数据可读(因为之前数据都读出来了放在缓冲区了,这里可能会一直阻塞)。),客户端使用ipv4数据报(因为是双协议栈主机,所以主机也有ipv4地址),服务端会将数据报中的ipv4地址映射为ipv6地址(下图虚线)。
2024-01-12 09:33:46
970
原创 算法刷题之路
做树相关题目,首先想到的应该是是否可以通过遍历解决,如果遍历能够解决,又分两种:1.是否通过DFS解决,如果是,采用递归的方式;根据递归顺序,又需分三种情况,先序、中序、后序。2.是否通过BFS解决,如果是,采用队列来处理,一层一层来。深度优先:递归(栈),一直往里走,走到底返回,例如,二叉树的递归遍历。广度优先:队列,一排一排的走,例如,一层一层的遍历树。注意:理解树的遍历和回溯法中深度优先遍历的联系,从宏观的角度去看待两者的联系;最终还是理解递归的本质。
2023-08-04 17:15:34
635
原创 模块高可用性部署概述
主服务器会回复自身的信息以及自身从服务器的信息,Sentinel通过主服务器的回复信息来更新主服务器的实例。如果从服务器的信息不存在主服务器的实例中,则初始化主服务器的从服务器信息实例信息,并建立Sentinel到从服务器的连接(同主服务器一样使用两条网络连接,并且使用INFO命令来获取)。尽量做到业务和部署分离。一个节点成为某个主节点的从节点,会通过消息发给集群中其他节点,最终集群中所有的节点都会知道,并且他们会更新clusterState结构中保存了该主节点的信息(更新主节点结构中的从节点名单)。
2023-08-04 16:53:22
331
原创 linux内核之时钟管理
但是高节拍率也意味着系统的负担增重,因为处理器必须花更多的时间来处理时钟中断处理程序,这样会引起处理器处理其他工作的时间更少,频繁打乱处理器高速缓存以及增加耗电等问题。系统定时器是一种可编程硬件芯片,它能以固定的频率产生中断(即定时器中断),它所对应的中断处理程序(时钟中断)负责更新系统时间,以及负责执行需要周期性运行的任务。相对于事件驱动而言,内核中有大量的函数都是基于时间事件驱动的,例如周期性执行的函数,或者延时执行的函数。(3)统计系统资源消耗统计值(进程消耗的系统时间和用户时间)
2023-03-28 15:48:51
552
原创 linux内核之进程管理
进程管理进程理解进程(最小分配资源的单位)理解线程(最小执行资源的单位)进程描述符及结构进程描述符的存放进程的状态进程上下文进程家族树进程的创建线程在linux中的实现内核线程进程的退出进程的调度多任务调度策略进程优先级时间时间片Linux调度算法CFS(完全公平调度)实时调度策略抢占和上下文切换进程理解进程(最小分配资源的单位)进程就是处于执行期的程序(目标码存放在某种介质上)。但进程并不仅仅局限于一段可执行程序代码,通常还包含其他资源,像打开的文件、挂起的信号、内核内部数据、处理器的状态等、一个或
2023-03-28 15:47:41
871
原创 linux内核之中断
中断中断异常中断处理程序上半部和下半部重入和中断处理程序中断上下文中断处理机制的实现中断控制下半部和推后执行工作不同的下半部方法中断任何操作系统内核的核心任务,都包含了对连接到计算机上的硬件设备进行有效管理,如硬盘、鼠标、键盘等。而想管理这设备,首先要能和它们互相通信才行。众所周知,处理器的速度跟外围硬件设备的速度往往不是一个数量级的,因此如果让处理器在发出一个请求后,专门等待响应,显然是不合理的。为了协同和这些外围设备的工作而又不降低机器的整体性能,使用了中断机制:让硬件在需要的时候再向内核发送信号。
2023-03-28 15:46:42
1250
原创 linux内核之内核同步
当处理多处理器之间或硬件设备之间的同步问题时,有时需要在程序中以指定的顺序发出读内存和写内存的指令(指令的指令要按照特定的顺序)。但是为了提高效率,编译器或处理器可能会对程序指令重新排序(例如,处理器在执行指令期间,会在取指令和分派时,把表面上看上去无关的指令按照自认为最好的方式排序)。在读取数据前后,序列值都会被读取,如果读取的序列值相同,则说明读操作过程中没有新的数据写入。如果在中断处理程序中使用了自旋锁,那么,在其他地方获取锁之前(例如,可以被中断的进程上下文中),需要先禁止本地中断。
2023-03-23 17:44:54
711
原创 linux内核之基础
算法内容:设置多个就绪队列,优先级从高到低,时间片从小到大;新进程进入队列时,先在第一级队列,按FCFS分时间片,按照分配的时间片,若进程没有执行完,则将剩余任务移到二级、三级队列;算法内容:按照进程达到就绪队列的顺序,轮流分配一个时间片去执行,时间用完就剥夺执行权。算法内容:结合FCFS和SJF,综合考虑等待时间和服务时间计算响应比,高的优先调度。- 公平、响应快,适用于分时系统,进程在一定时间内都能得到响应。- 长作业等待时间越久,响应比越高,越容易获得执行权。算法内容:优先级高的作业/进程优先进程。
2023-03-23 17:38:56
591
原创 linux内核之系统调用
API定义了一组应用程序使用的编程接口,它们的实现可以使用一个或多个系统调用,甚至是完全不使用任何系统调用也没有问题。用户空间的程序无法直接执行内核代码,所以应用程序应该以某种方式通知内核,告诉内核自己需要执行一个系统调用,希望内核切换到内核态,这样内核就可以代表应用程序在内核空间执行系统调用了。通过这样一个独一无二的号,进程在执行系统调用时就无须提及系统调用的名称。从纯技术的角度看,POSIX是由IEEE组成的一套标准,其目标是提供一套大体上基于Unix的可移植操作系统标准。两者就是密不可分,互相使用。
2023-03-23 17:37:47
224
原创 linux内核之内存管理
虽然处理器的最小可寻址单位是字,但是内存管理单元(MMU,将虚拟地址转为物理地址的硬件)通常以页为单位进行处理(一般为32位系统为4k,64位系统为8k,如果页为4k,物理内存为1G,则物理内存会被划分为1G/4k=262144个页,这些页信息通过page结构体全部保存在内存中)。按照如上直接映射的方式,会发现内核只能访问1G的内存,但我们的物理内存实际上会达到8G、16G,甚至更高,所以必须要有一种灵活的方式来让内核访问到全部的物理内存,因此linux高端内存十分必要。这也是用户空间分配方式。
2023-03-23 17:30:16
1035
原创 Nginx内存池
Nginx内存池内存池的优点内存对齐事件处理worker如何竞争连接请求内存池内存池的优点使用系统自带函数的缺陷:系统自带的ptmalloc内存管理分配器,在分配和回收内存时虽然都有自己的策略,但是直接使用malloc/free仍然性能比较底下。频繁的使用malloc分配内存会产生内存碎片,不容易让系统回收。容易产生内存泄漏(管理麻烦)。内存池的优点:管理方便,分配一块大内存,回收的时候只需要直接回收整块大内存即可;提高效率,不需要每次都调用malloc/free系统调用;内存对
2023-03-23 17:27:38
495
原创 linux内核之块IO层
使用缓冲区头作为IO操作单元有两个弊端:缓冲区头是一个很大且不受控制的结构体(上面的是已经缩减过的),而且缓冲区头对数据的操作既不方便也不清晰,对内核来说,它更倾向操作页面(内存章节中讲到分配内存时按页分配),页面比缓冲区大,效率更高,同时更为简单;块是文件系统最小逻辑可寻址单元(物理磁盘的最小单位是扇区,但是内核执行的所有磁盘操作都是基于块来进行的),对于块单位的要求是:数倍于扇区,2的整数倍,并且要小于页面大小,所以通常块的大小为512、2k、4k。该调度程序就是最轻量级的调度,只提供指向合并的功能。
2023-03-22 11:21:21
662
原创 linux内核之虚拟文件系统
所以在VFS和内核的其他部分来看,所有文件系统都是相同的(比如说,它们都支持文件和目录的概念,都有打开、读取、关闭的操作)。理解:VFS采用的是面向对象的思想,实际文件系统的类型可能不同,但是都需要实现VFS提供的回调的接口来满足VFS需要实现的目的。文件的相关信息,例如访问权限、大小、创建时间等,被称为文件的元数据,被存储在单独的数据结构中,该结构被称为索引节点(inode)。在Unix中,目录也属于普通文件,它列出了包含在其中的所有文件,可以对目录执行和文件相同的操作。
2023-03-22 11:20:00
643
原创 linux内核之进程地址空间
这里的每个内存区域指的的单个进程中不同的内存区域,例如,代码区、全局变量区等,具体见上面的地址空间。内存寻址缓冲器,TLB作为一个将虚拟地址映射到物理地址的硬件缓存,当请求访问一个虚拟地址时,处理器将首先检查TLB中是否缓存了该虚拟地址到物理地址的映射,如果在缓存直接命中,物理地址立即返回,否则,就需要再通过页表搜索需要的物理地址。在多数体系结构中,搜索页表的工作是由硬件完成的,虽然通常操作中,很多使用页表的工作都可以通过硬件来执行,但是只有在内核正确设置页表的前提下,硬件才能方便地操作它们。
2023-03-22 11:16:10
641
原创 页高速缓存
在页高速缓存中的页可能包含了多个不连续的物理磁盘块,也正是由于页面中映射的磁盘块不一定连续,所以在页面高速缓存中检查特定数据是否已经被缓存颇为困难,因为不能用设备名称和块号来做页高速缓存中的索引。当我们发起一个对操作时(例如,进程调用read),它首先会检查需要的数据是否在页缓存中,如果在,则放弃访问磁盘,直接从内存中读取。(3)回写,linux采用的策略,程序执行写操作直接写到缓存中,后端存储不会立刻更新,而是将缓存页更新为脏页,并将其加入到脏页链表中,然后由一个进程周期性的将脏页写回磁盘。
2023-03-22 11:14:21
552
原创 GDB程序调试
GDB(GNU Debugger)是GCC的调试工具。其功能强大,现描述如下:启动程序,可以按照你的自定义的要求随心所欲的运行程序。可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)当程序被停住时,可以检查此时你的程序中所发生的事。动态的改变你程序的执行环境。一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。
2023-03-22 11:11:41
841
原创 网络编程示例程序
由于客户端不需要固定的端口号,因此不必调用bind(),客户端的端口号由内核自动分配。注意,客户端不是不允许调用bind(),只是没有必要调用bind()固定一个端口号,服务器也不是必须调用bind(),但如果服务器不调用bind(),内核会自动给服务器分配监听端口,每次启动服务器时端口号都不一样,客户端要连接服务器就会遇到麻烦。
2023-03-22 11:10:08
420
原创 Linux系统编程
任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。(1)调用进程不能是进程组组长(否则创建会话函数会出错),该进程变成新会话首进程(session header),并且该进程成为一个新进程组的组长进程(组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程)。
2023-03-22 11:09:15
121
原创 linux基础知识
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段 —> 环境变量LD_LIBRARY_PATH —> /etc/ld.so.cache文件列表 —> /lib/, /usr/lib目录找到库文件后将其载入内存。(2)定时任务的环境变量是单独配置,如果你的可执行程序依赖环境变量(例如环境变量设置了动态库路径)或者是你的脚本依赖环境配置,此时需要在定时任务前单独配置下,一般加在任务脚本中;0代表标准输入,1代表标准输出,2标准错误,都是文件描述符;
2023-03-22 11:07:55
682
原创 字符串匹配处理
sed是一种流编辑器,它是文本处理中非常好的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件,可以将数据行进行替换、删除、新增、选取等特定工作,简化对文件的反复操作,编写转换程序等。
2023-03-22 11:07:05
1992
原创 linux网络编程
而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。在数据传输过程中,ACK和确认序号是非常重要的,应用程序交给TCP协议发送的数据会暂存在TCP层的发送缓冲区中,发出数据包给对方之后,只有收到对方应答的ACK段才知道该数据包确实发到了对方,可以从发送缓冲区中释放掉了,如果因为网络故障丢失了数据包或者丢失了对方发回的ACK段,经过等待超时后TCP协议自动将发送缓冲区中的数据包重发。因此一般使用下面这行代码循环读数据。
2023-03-22 11:06:45
1350
原创 数据库成长之路
Mysql插入数据插入数据mysql插入x万级数据方案:(1)存储过程导入数据(存储过程是一组可编程函数,是为了满足特定功能的SQL语句集)[sql](2)load data可以将文件中的数据导入到sql表中,默认一行为sql中一条数据[sql](3)insert语句时单语句插入多条值(mysql只需要对单语句进行语法分析)或使用批量插入(事务)[编程语言]注:在采用单语句插入多条时,对索引的负载也更小,单语句时索引只有在所有数据都处理完后才刷新...
2023-02-28 16:21:30
201
原创 使用backtrace追踪程序的异常退出
输出程序的堆栈backtrace函数在linux系统中,我们可以通过如下三个库函数来获取程序的调用堆栈,可以通过man 3 backtrace查看。它们由GUN C Library提供。#include <execinfo.h> /* Store up to SIZE return address of the current program state in ARRAY and return the exact number of values stored. */int
2022-04-12 16:22:29
519
原创 linux内核之内存寻址
内存地址理解内存地址1.内存地址的分类逻辑地址线性地址(虚拟地址)物理地址2.三种内存地址之间的转换内存控制单元(MMU)通过一种称为分段单元的硬件电路将一个逻辑地址转换为线性地址;紧接着通过第二个分页单元把线性地址转换为物理地址。硬件分段Intel微处理器以两种不同的地址模式运行,分别是实模式和保护模式,实模式一般是为了兼容早期的模型,现在我们从保护模式来看硬件中的分段问题。1.一个逻辑地址由两部分组成段标识符段标识符又称段选择符,是一个16位的字段,如下图:段内
2022-03-17 11:00:21
2027
1
原创 设计模式(1)设计模式分类
设计模式的六大原则单一职责原则(类)不要存在多于一个导致类变更的原因,也就是说一个类只需要实现单一的职责,如若不然,就应该把类拆分。如:类A分别负责职责P1和职责P2,当职责P1发生变动需要修改类时,会引起原来正常工作的P2发生故障,类A即违反了单一原则。里氏替换原则(继承)里氏替换原则是面向对象设计的基本原则之一。里氏替换原则是继承复用的基石,指任何基类可以出现的地方,子类一定可以出现。只有子类可以替换掉基类,而业务功能不受影响时,基类才能真正被复用。(注意继承和多态是两种概念)在里氏替换
2022-03-08 19:50:04
125
原创 Linux运维工具
linux运维Linux系统运维工具sar(System Activity Reporter)sar参数sar例子CPU资源监控inode、文件和其他内核监控内存和交换空间监控内存分页监控I/O和传送速率监控进程队列长度和平均负载状态监控系统交换活动信息监控设备使用情况瓶颈问题iostat(I/O statistics,输入输出统计)iostat命令iostat例子显示所有信息显示磁盘详细信息iostat数据来源iostat的缺陷vmstatvmstat参数vmstat使用显示所有信息pidstatpids
2021-12-17 17:07:05
1060
原创 Linux Socket发送/接受类函数
write函数和read函数writev函数和readv函数send函数和recv函数sendto函数和recvfrom函数sendmsg函数和recvmsg函数
2021-10-26 17:28:03
1223
原创 linux线程同步
互斥锁/** 互斥锁有四种属性:* PTHREAD_MUTEX_TIMED_NP,缺省值,普通锁;* PTHREAD_MUTEX_RECURSIVE_NP,可重入锁,允许同一个线程对同一个锁获取多次,并通过多次unlock解锁,可递归;* PTHREAD_MUTEX_ERRORCHECK_NP,如果同一个线程请求同一个锁多次,会返回EDEADLK,可规避死锁;* PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,在多核情况下,首先自旋获取锁,若超过了自旋次数的最大值则会阻塞挂起;*/
2021-10-25 16:19:55
85
原创 linux/macos获取路由信息
netlink什么是netlink?netlink是linux提供的用于内核和用户进程之间的通信方式。虽然Netlink主要用于用户空间和内核空间的通信,但是也能用于用户空间的两个进程通信。一般来说,用户进程和内核空间通信的方式有三种:/proc、ioctl、netlink;前两种是单向的,netlink可以实现双工通信。每个netlink协议,通常与一个或一组内核服务/组件相关联,如NETLINK_ROUTE用于获取和设置路由与链路信息、NETLINK_KOBJECT_UEVENT用于内核向用户空
2021-10-20 16:32:58
1405
原创 算法代码题
面试代码题数据结构<树>1.重建二叉树2.二叉树的下一个节点数据结构<树>1.重建二叉树根据前序遍历和后续遍历的集合,构建二叉树。思路:采用递归的方式 core(preS, preE, inoS, inoE)递归的终止条件 :前序集合只有一个变量,中序集合只有一个变量,且两个集合的变量相等。//伪代码BinaryTree* ConstructCore( int *preSta, int *preEnd, int* inordSta, int *inordEnd)
2021-09-02 10:20:57
192
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人