今天做了设计模式的 观察者模式, 策略模式,
操作系统如何通过虚拟地址找到物理地址,通过分页,分段的方式
算法题刷了 树方面的知识,树的镜像,判断是否为二叉搜索树
打了蓝桥杯,两个大题错了, 其他还好,希望有省一
算法题:确定一颗二叉树,前缀和+哈希(a – k) = b的思想,atoi,to_string,
操作系统,还是不太清楚分页和多级分页有什么好处hhh
打算过一下stl源码
写了几道数的算法题,学了操作系统进程线程那块,发现难顶啊,怎么去调度,比页面置换要难理解
算法: 将答案记忆化,
操作系统: 还是进程,发现要去看看一些博主的文章,看着视频都有一定困
算法:
最近公共祖先,利用后序遍历来判断左右情况,
以及在二叉搜索树中寻找祖先的优化技巧
二叉树中寻找最大路径和, 也是利用后序,看选左还是右,或者左右一起
PyQt:
还没弄成功,今晚叫同学教一下,不过也发现,做这些,代码别人已经实现好了,只需要调用就可以了
今晚见个女孩子(说实话,人家还挺可爱,爱笑,话挺多,但感觉自己说不出什么话出来,嘴太笨了,没有进一步的情感暗示,md,千万不要做一些让女生反感的事情,提升自己的讲话的故事性)
算法: 一道回溯题,加上又撤销,以及栈
操作系统: 就一些进程之间的通信,共享资源类的,信号量,有点迷迷糊糊
发现有一些文件上链接有点问题,这就很迷,写的好好的,发到别人那去就运行不了,艹
算法: 也就一些简单的模拟+贪心
操作系统: 弄到了文件,先过一遍吧,实在迷
stl源码: 实现起来还是很庞大, 应该是自己水平还不太行
sql的round(val, 位), current_data(),
其实这两天学的都迷,就想着撩妹了,要找回节奏了
今天学了点qt,不过环境还没装上,难受,大致就是控件之间通过信号和槽来进行消息传递
通过视频也学到一个知识点: 成员函数指针,必须要在实例化后才可以调用,与全局函数的不同,因为全局函数会在程序一开始就有内存地址,而成员函数要实例化分配内存才可以调用。。
以及c++异常捕获的写法,抛出异常析构不执行,有点危险...
Qt: 环境搭好了, 也写了一些控件,现在基本感觉,有文档写就行,不过还没和c++代码结合起来,除了通过信号量去调用相关代码
其实说好到月底要把操作系统过一遍的也没搞好,这个月光想泡妞去了
每天写一个设计模式,发现什么情况都会有设计模式的出现
Qt: 学了一些事件, 系统自动调用,概念还不太清,回宿舍看几篇文章先
算法: 弄了个二分,迷迷糊糊的,不知道哪错了
Qt: 项目
算法: 左右指针,三个数的和最接近target
怎么又少了一天, 害
Qt:算是基本掌握里面的实现,都是通过信号连接彼此来达到联合的作用,明天试试用这个来把上次python的作用bim来写了
算法: 没啥,快速幂,偶数就双倍,奇数多乘一次自己
c++外挂: 就是通过找到汇编,因为高级语言都会转成汇编,通过修改内存指令去达到更改数据的效果,
Qt: 写完了bim,已发布,
c++:private继承: 就是说子类里面可以调用父类的东西,但是在外界不能访问其父类函数,public继承代表is a,
C++: 有关虚函数表地址共享的问题, 构造和拷贝构造函数在什么时候会生成默认,
- 不过有点疑问就说,成员函数地址是在 对象实例化后存在,还是,程序一运行它就存在?(编译就知道了,在构造函数之前就已经赋值了)
c++: 虚基类的学习, 继承的父类,虚父类和父类数据分开,
算法: 发现重载运算符有点问题,哈夫曼,
c++:
- 对于虚基类的虚函数有了更充分的认识,已经this指针偏移的作用,还有类中的函数都会自带一个this指针,所以类的函数是要实例化对象才存在,
蓝桥杯出成绩,省一, 希望没有疫情去趟北京!
5月份正式开始搞操作系统
C++:
- 算是过了一轮对象模型,明天休息,脑子过过虚函数的调用规则,争取写一篇完整的文章
下个星期开始走linux了, 环境已经搭好
C++:
- 已经把对象模型总结弄出来了, 虚函数虚基类,无非就是通过this指针的移动来调用的
Linux:
- 真的麻烦啊~~~ 真的烦!!, 什么东西都没有,百度也没用,真的烦!!
明天休息,调整。。
C++:
- 智能指针的运用, share_ptr, weak_ptr, uninque_ptr,
- 明天开始多线程, 和模板
- 感觉还是打好这里的基础
算法:
- 明天写一下 根据中序和层序创建二叉树
看了一下linux,唉,头痛这个, 。。。。
C++:
- 多线程, mutex, unique_lock, lock_guard, 原子atomic, 递归mutex, 异步的async,
C++:
- 就大概看了函数对象
Linux:
- 算是知道哪里出问题了,网络的问题,导致下载不了包,接下来的计划大概就是c++模板, 还有linux操作系统
操作系统:
- 知道了操作系统就是不断去调度进程,提高cpu处理效率,进程间就是通过pcb, 进程中又分用户级线程,内核级线程,通过tcb来控制,不同进程间的内存地址是不同的,是虚拟内存,有不同的映射表,明天回顾一下这里的线程和进程
c++:
- 友元成员函数要注意,前向声明,以及函数要在类外实现,因为你要知道这个函数到底在不在
- 模板:传进去的类型要对, 多写吧,比如变量模板,
操作系统:
- 内核级线程中内核也是通过换tcb来切到其他内核中的栈,内核中的栈再返回用户级的栈
明天把中序和层序构造树给写了,再刷一遍内核级线程的视频,争取下周五之前进到网络编程
操作系统:
- 进程的调度,信号量,临界区,死锁,内存分页,分段,明天了解一下内存这方面的东西,进程这块稀里糊涂,毕竟还没写过这些代码,不知道原理是什么,记概念没用
操作系统:
- 学了内存管理,段页, 有点小疑问,当两个进程访问一个*p的时候,一个进程改了这个数据,发现这两个数据怎么同步,或者说,会不会导致不一致
没有特别新鲜,帮别人做题,还要晚修。。。1000+
c++:
- 知道了萃取的原理,就是通过模板的泛化来实现,
- 万能引用
网络编程:
- 基本的函数使用,比如3次握手,4次挥手,
- socket, bind, listen,accept,read,write close
- socket, connect, read, write, close
网络编程:
- 写了一个server 和 client, 发现原理不太明白,不知道为什么这样就能连接,希望接下来可以回答这个问题
颓废了好几天,认识了一个女孩子,还不错,不过感觉还是不太适合自己,先慢慢接触吧
还是往网络编程方向去学习,发现都是在调用相关的api, 明天打算看看tcp/ip网络编程这本书
网络编程:
- learn函数: 就是设置监听队列, 让connect的函数进入
- accept: 产生套接字与客户端连接
- connect: 等到服务器接受连接才返回,并且产生ip地址以及端口号
- read write 都是往缓冲区读数据,写数据
又歇菜了两天~~, 很特别的几天,谢谢她
网络编程:
- udp实现服务器, 也可以通过connect函数绑定,这样就不用每次都产生一次地址,
- time_wait状态: 在fin包发出去后,如果对方未接收到,此时会重传,不然对端永远无法接收到
今天有一位兄弟通过我的文章找到了我,还是有点兴奋,但是不知道有没有帮到他哈哈哈
网络编程:
- 围绕在进程间的通信这块,了解了僵尸进程,就是父进程没有接受到子进程的返回值,所以就要想办法去传递返回值来销毁子进程,比如用wait, waitpid, 信号,
- fork出的子进程是执行fork后面的代码,但是复制了父进程的资源,
- 还有一个小问题,怎么通过一个服务端来和多个客户端进行通信,除了io复用和udp,进程线程;时间轮询我会出现错误,具体在csdn有发布,
被一个傻女孩弄的提前结束一天
网络编程:
select io复用实现服务器, 一开始就设定监听数,但是要注意,每次调用select是总数+1,因为是从0开始,其他的都没什么,就是被这个小bug拖了点时间,
FD_ZERO(), FD_SET(), SELECT(NUM+1, X.X.X.X), FD_ISSET(), FD_CLR();
今天发现彻底懵了, udp和tcp,都是建立在多个ip地址与其单个服务端进行通讯的
今天参加了一个项目起头,发现是我格局小了,同级的还是有很多强者的,不能自以为是了,还想抱着过去学一学的心态,人家都能做出来了,你没实力还过去凑热闹。。。
网络编程:
- 懵在了 到达accept是支持连接多个套接字?,怎么会有迭代?, 明天好好搞清楚,以及多线程是怎么实现服务器的
- 知道了多线程是怎么去操作的了,就是通过一些互斥量,信号量来控制一个线程的读写次序,我满足就执行,
- 更新了关于网络api的博客
- 今晚看看io模型有点迷异步和同步
明天端午,又要歇菜。。。
网络编程:
定时器?? 没怎么明白原理
发现游双这本linux高性能服务器编程看的没有tcp/ip网络编程那么好懂。。。
昨天就有开始恢复了,今天开始了老王的项目,学了几个函数,比如怎么读配置文件,指针的操作,地址的差值去覆盖,
老王的通讯架构: 配置文件的读写,日志打印
其实就是自己重新定义了一个类似printf的函数,知道了一下内存赋值的操控方法,
ui64 = (uint64_t)va_arg(args, u_int); 这个函数就nb,直接把类型直接转出来,
这里的实现其实都是通过字符串的处理,比如浮点数,是通过分开小数点前,小数点后去处理的。
字符指针的跳转是看什么时候有'\0'就结束,不是说跳它本身结构的长度,因为指针都是4个字节,像最后一个for循环,赋值是整个赋值,但是有'\0'
#include <iostream> #include <algorithm> using namespace std; int main() { const char* s[5] = { "1","22","333","4444","55555"}; int i; int g_environlen = 0; for (i = 0; i < 5; i++) { g_environlen += strlen(s[i]) + 1; //+1是因为末尾有\0,是占实际内存位置的,要算进来 } //end for //这里无需判断penvmen == NULL,有些编译器new会返回NULL,有些会报异常,但不管怎样,如果在重要的地方new失败了,你无法收场,让程序失控崩溃,助你发现问题为好; char *gp_envmem = new char[g_environlen]; memset(gp_envmem, 0, g_environlen); //内存要清空防止出现问题 char* ptmp = gp_envmem; //把原来的内存内容搬到新地方来 for (i = 0; s[i]; i++) { size_t size = strlen(s[i]) + 1; //不要拉下+1,否则内存全乱套了,因为strlen是不包括字符串末尾的\0的 strcpy(ptmp, s[i]); //把原环境变量内容拷贝到新地方【新内存】 s[i] = ptmp; //然后还要让新环境变量指向这段新内存 ptmp += size; } return 0; }
多调试代码,发现内存这东西,还挺有意思,不断跳转跳转
明天开信号,今晚看一下可变参数
看了可变参,就是通过函数调用不断取后面的地址
老王的体系通信架构:
- 子进程的创建
- 子进程的回收,通过信号,并且变成守护进程, 具体的流程明天再过一下,
一个项目还真复杂,不过后面就调用就可以了,
明天要早点来,没电是挺难受的
今天看了time_wait状态,就是在断开的时候,要保证可靠的全双工终止
阻塞: 就是卡在这个函数,等事件发生才往下走
非阻塞:就是调用的时候会立即返回,有时间发生时,会卡一段时间,因为要把数据从内核缓冲区复制到用户缓冲区
异步io: 指定一个接收数据的缓冲区,以及回调函数,其他事情交给操作系统,而且异步函数只需要调用一次,
同步io:没数据就卡着,有数据就返回,再调用其他函数去操作数据,
看看小林的tcp状态
老王:
- 不太清楚事件是按什么流程走进代码的,什么时候添加,实现,以及初始化,但是明白怎么去找剩余的连接池,缺少逻辑上的 思路,还要过一下代码流程 ,迟早要画一个思维导图
- 明天电路课可以看看小林的tcp状态以及群里讨论的单例模式
关闭一个链接的fd会同步关其他事件的socket?,不是的内存地址吗
粘包,缺包
- 知道了如何去收包,以及梳理了一下老王服务器的逻辑,子进程中调用epoll_wait, 事件中的触发回调函数通过线程池去处理其业务代码,还是相当庞大,过掉这轮,好好理解其中的细节,
- 疑问: 为什么要用连接池,而且为什么会导致使用相同的连接,
- 好的做法代码:
- 比如使用 int a[] = {}, int size = sizeof(a)/sizeof(int);
- 类中指针彼此指向,像6.14那天,就是这个,因为彼此指向同一个内存,改了fd也会改其指向区域的fd
老王那个准备收尾了,很多细节没弄好,比如线程直接的关系,还是要好好整理才行, 最近要期末了, 明天蓝桥杯,今天感觉啥也没干,。。。。郁闷的。。。
断更了好久好久, 1是为了期末, 2是本来要去老王的线下课, 就没怎么来这总结了
- 有了内核对象, 才可以跨进程访问(引用计数为0才销毁内存)
- vs调试技巧, 数据断点,条件断点
gdb调试:
调试正在运行的程序
1.查看该进程id = ps -ef | grep 程序名
- gdb 程序名 -p 进程号
调试多进程:
- set detach-on-fork on/off, on 其他进程继续运行, off 挂起
- info inferious 进程id
调试多线程:
- 查看当前程序的线程 ps -aL | grep 程序名
- 查看主线程和子线程的关系: pstree -p 主线程id
- 查看线程: info threads
- 切换线程:thread id
- 只运行当前线程: set scheduler-locking on
- 运行全部线程: set scheduler-locking off
- 指定某线程执行某gdb thread apply id 【cmd】
- 全部gdb thread apply all 【cmd】
今天被刺激到了, 女孩子只看重工作经济有能力的人, 共勉各位
- gdb调试子进程, 发现环境没弄好,线程开不了这么多
- 现在关键 要多写代码,调试代码, 在Windows的api 来写,写熟悉再回到linux
- 把王老师的代码, 线程的搭配进行了解
条件变量:1.虚假唤醒, 2. 为什么要绑定一个mutex
实现了一个htonl ,https://blog.csdn.net/weixin_52068490/article/details/125982313
c++11 的条件变量:
- wait :
c++ :
定位new , 就是初始化一块内存, 在这块内存上再去调用所要使用这块对象的构造函数
char buff = new char[1000]
A *t = new (buff) A;//定位new
//同步的、阻塞的: 简单 send(...); recv(...);
//同步的,非阻塞的 : 能够更快收到结果,作出反馈,比如登陆 while(退出标志) { send(...); }
//退出标志,计数、时间 //记录一下第一次调用时间
while (退出标志) { //记录一下当前时间,当前时间 - 第一次调用时间 >= 时间间隔(5秒),退出 recv(); }
//利用select、poll检测数据可读 recv(...);
C++
thread 绑定类成员函数, 第二个参数要该变量, 或者绑定静态成员函数, 也就是成员函数要跟着成员
ThreadItem t;
t.mythread = thread(&ThreadItem::fun, &t);
void fun( void * p, ...) { va_list args; //创建一个va_list类型变量 va_start(args,p); //使args指向起始的参数 printf("%d ", va_arg(args, int)); printf("%s", va_arg(args, char*)); va_end(args); //释放args } int main() { //ngx_log_stderr(0, "invalid option = %010d %s", 12, "asdf"); char* p = NULL; fun(p, 12, "hello _wordl"); }
又是新学期, 可不能新开始了, 毕竟时间很宝贵,再之前我们肯定有认真过,可能会懈怠,但是那股劲肯定时不时的刺激你。
其实我很羡慕比我大的人,感觉要是我出生在那时, 会不会没有那么焦虑, 现在又是疫情,又是打仗的,说来说去,心太浮躁了,又一切归于自己遇到困难了,又该去刺激一下自己继续学下去, 有句话说的好, 技术在身,不怕没饭吃。 已经是大三了, 争取寒假前, 好好包装自己, 规划一下。
- 一个月,把常用的设计模式啃下来 ,并且做博客记录
- MySQL的原理, 也搭配学一下
- STL源码剖析
- 把老王那个项目,以及看web服务器代码
短期计划就是这样, 沉着心来,
- 明天调试一下web代码
Web 服务器, 感觉1版本有点 内存重复利用的可能, 也许这就是老王那个项目中 用到连接池延迟回收的用处吧, 明天再看看2版本和1版本有什么不同
设计模式 , 组合模式, 明天加强一下这个
游双的 8-3 简单的解析http报文
webserver:
- writerv , 流程明白, 就差细节
- 服务器怎么把页面交给浏览器渲染的
- 刷新是重新发一个连接, 那之前的请求怎么处理
- 写一个多人聊天程序
- 代理模式:也就是一个代理类, 去包装要 保护的服务类的函数, 不让别人知道细节, 用户通过代理类来实现服务类的方法
webserver:
- 大致知道浏览器是怎么加载页面的了, 其实还是有格式的, 响应报文
- sendfile
- 把线程池又写了一遍,遇到一个 错误, 定义了析构函数, 但是没有实现,导致链接错误
把非阻塞和阻塞,熟悉一下
epoll_create(num)
epoll_event {
.data.fd
.data.ptr
events = EPOLLIN 。。。。
}
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event)
-- events -> epoll_event
epoll_wait(epollfd, events, num, -1)
sigpipe错误
html页面还是加载不出来,艹
webserver:
服务器要接受了请求报文, 也就是读了, 才可以去发送本地html文件给浏览器, 才可以加载出来
这么多天,终于明白了
io复用函数其实也是阻塞的, 只是它们可以监听多个io事件的能力来提高效率
明天尝试加上定时器这个功能,windos和linux的sleep函数不一样,win->2000, == linux-> 2
webserver:
- 不太清楚加定时器的作用? 是为了关掉客户端的socket和epoll_DEL?
重看老王的连接池
- 明天自己复现一个小demo
- 复现了一个连接池,感觉实现起来就类似生产者消费者
- 今晚看个stl视频吧, 或者设计模式,
- 明天试试看radius?webserver配置不了opencv,有点迷了,
- 对于网络,好像还是不太明白
写了个epoll实现的多人聊天室, 缺少一个客户端, 私发消息功能, 目前就是一个群发的功能
有机会学学连接mysql
Cmake: 学习
wang:
6/5章-> 加了写事件, 不太清楚epoll 的写读事件的触发机制, 重看一下视频5,6节,
- 知道了epoll读写触发机制, 就是说你的LT和ET的区别, 最好就像老王那样, 读完数据的时候, 增加写事件,写事件没有发送完,epoll会继续触发,看你选择什么触发机制,
- 7号之前实现小demo
- 加了个小demo业务:
- 线程池创建,监听端口,epoll创建事件,添加事件, .....
- 看几个面试题
- 加了收发函数, p1,pla, 发送消息队列,
- 明天连接池~, 再看看收发数据的细节
- list删除iteration不改变迭代器吗?
添加了连接池,【发现如果用条件变量,信号量来触发回收函数,但是没到达时间处理不掉, 后期怎么再来触发呢,
所以回收函数用了一个延时轮回不断去检测来处理】
明天实现一个借书业务,或者优化一下代码结构
删除了list的迭代器会让iter++, 并且end也会变化
vector :
reverse:
resize:
感觉这学期没有去图书馆, 摆烂了好多,心静不下来, 老想着其他东西,
最近在弄radius, 这个月内,把常见的设计模式复习一下,补补计算机网络,操作系统的知识
再学多一个项目
vs2019 来你今儿mysql
单例模式的 恶汉 (静态成员对象变量) 和 懒汉 (静态成员对象指针变量)
线程安全的懒汉
{
if(NULL == m_instance)
{
Lock();//借用其它类来实现,如boost
if(NULL == m_instance)
{
m_instance = new Singleton;
}
UnLock();
}
return m_instance;https://blog.csdn.net/zhanghuaichao/article/details/79459130
}
被隔离了, 最近在看多线程,发现线程退出一定要释放资源,比如解锁,不然会导致死锁
CSAPP:
- 链接重定位,还是不熟啊, 感觉只是浅看...
跳表
- 就是控制一个节点有n个指针,其实也就是,控制了一个n*n的列表,最好采用动态开辟的方式,n * k 个节点
csapp:
程序载入内存,先创建段表,页表,在把程序分段,重定位,这个时候就有了虚拟地址, 通过段基值+偏移量,找到页框,通过页框找到物理地址
父进程子进程,共享虚拟地址,只是在写入的时候,只有读权限,写的话,会重新开辟一个页表来记录此时的地址