- 博客(50)
- 收藏
- 关注
原创 机器语言的作用和Inter处理器的发展历程
编译器基于编程语言的规则、目标机器的语言指令集和操作系统遵循的惯例,经过一系列过程生成机器代码。GCCC语言编译器以汇编代码形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令。然后,GCC调用汇编器和链接器,根据汇编代码生成可执行的机器代码。在本章中我们近距离的观察机器代码,以及人类可读的表示——汇编语言。 现在我们只需要用高级语言来编程,比如C语言,JAVA语言,而不...
2020-02-29 21:18:48
627
原创 超详细的IEEE标准下的浮点数规则,附实例和规则总结
浮点数的历史浮点数表示的有理数进行编码。它对执行涉及非常大的数字,非常接近0的数字,以及作为实数运算的近似值的计算,都有着非常大的作用。直到20世纪80年代,每个计算机的制造商都制造出了自己的浮点数规则,以及对浮点数执行运算的细节。另外,他们常常不会关注于浮点数计算的准确性,而把实现的快速和简便看得比精确性更重要。大约在1985年,这些情况随着IEEE标准754的推出而改变了,这是一个...
2020-02-27 15:36:34
6026
1
原创 整数运算
整数运算目录无符号加法 补码加法 补码的非 无符号乘法 补码乘法无符号加法例如:x=9,y=12的位表示分别是[1001]和[1100]。他们的和是21,5位的表示是[10101],如果丢弃最高位,那么我们得到[0101]。也就是说,十进制值的是5。这和值21mod16=5是一致的。我们可以将操作描述为:原理:无符号数的加法对于满足0<=x,y<的x和...
2020-02-24 23:35:28
2058
原创 整数表示,无符号数和有符号数的相互转换,扩大,截断位表示
接上面的博客,继续介绍数字表示第二节整数表示在本节中,我们会介绍两种不同的整数表示方式:一种只能表示非负数,另一种既能表示正数,还能表示负数和0。后面我们会发现它们在数学属性和机器级实现方面的密切相关。我们还会研究扩展或者收缩一个已编码整数以适应不同长度表示的效果。 我们首先引入一些数学术语,用于精确定义和描述计算机如何编码和操作整数。在后面我们会使用这些数学术语,在这里列出让读...
2020-02-16 11:17:21
2141
1
原创 寻址和字节顺序,字符串编码以及位级,逻辑,移位运算
这篇博客借鉴于深入理解计算机系统的第二章,也算是我看完书后的总结。 我们一般研究三种重要的数字表示,第一种是无符号编码,它是基于传统的二进制表示法,一般表示的是大于或等于的零的数字。第二种是补码编码,它是有符号整数最为常见的表达方式,有符号整数是可以为正或可以为负的整数,第三种是浮点数的编码,是以2位基数的实数的科学计数法的表示...
2020-02-12 21:41:00
474
原创 关于C++11 智能指针 的详细说明以及使用
由于C++没有像java那样的内存回收机制,我们在new一个资源的同时需要考虑其的delete,但是由于种种原因,忘记delete,程序异常退出没有执行到delete的代码等,都会导致内存泄漏,因此,我们引入了智能指针这种机制,它可以自动的为我们管理内存,无需我们考虑内存的释放问题。原理 智能指针实际上是栈上的一个对象,而非一个堆上的指针对象,在智能指针生命周期即将结束的时候,析构函...
2019-12-27 11:56:42
1139
1
原创 关于C++11 thread 的超详细介绍和使用
在windows上面启线程时,用的是windows的API,前辈说可以去学一下C++11 提供的线程库,比较方便灵活。下面就介绍一下thread的用法。std::thread::thread thread()noexcept; (1) (C++11 起) thread(thread&&other)noexcept; ...
2019-12-21 11:16:02
4072
原创 C语言复习第一节
复习难点1.float类型在内存中的存储方式 指数位的计算方法,找到化为二进制数后的浮点数中第一个1的位置,如数12.25中应该将小数点左移3位,移到浮点数中第一个1的位置,再比如数0.25,化为二进制为0.01,移到第一个1的位置,应该是向右移2位,那么,得到移动位数后,我们应该怎样计算指数位的值呢? 首先,我们应该明确指数位起步就有值,大小是127,如果我们得到应该左移三位,...
2019-01-10 00:10:46
302
原创 野指针和无效指针
无效指针的野指针区别无效指针:它曾经指向一个有效地址,但是现在不再指向有效地址,就是原来的那块地址不能通过这个指针区访问了。这通常是因为指针所指的内存单元被释放了并且不再有效了。无效指针存在并没有什么问题,除非你尝试通过这个指针访问指向的地址空间。不遗留任何无效指针总是最好的实践方式。野指针:它没有被正确的初始化,于是指向一个随机的内存地址。存在野指针是一个严重的错误。...
2018-12-11 23:36:33
2438
原创 I/O复用——LT & ET
LT和ET模式 epoll对文件描述符的操作有两种形式:LT(Level Trigger,电平触发)和ET(Edge Trigger,边沿触发)模式。LT模式是默认的工作模式,这种模式下epoll相当于一个效率较高的poll。当往epoll内核事件表中注册一个文件描述符上的EPOLLIN事件时,epoll将以ET模式来操作该文件描述符,ET模式是epoll的高效工作模式。 对于采用...
2018-12-08 16:42:45
366
原创 三种I/O复用的比较
三种I/O复用的比较 系统调用 select poll epoll 事件集合 用户通过3个参数分别传入感兴趣的可读、可写及异常等事件,内核通过对这些参数的在线修改来反馈其中的就绪事件。这使得用户每次调用select都要重置这3个参数 统一处理所有的...
2018-12-08 15:59:44
386
原创 I/O复用——epoll
内核事件表epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll有很大差异。首先,epoll使用一组函数来完成任务,而不是一个函数。其次,epoll吧用户关心的文件描述符上的事件放在内核里的一个时间表中,从而无需像select和poll那样每次调用都要重复传入文件描述符或事件集。但epoll需要使用一个额外的文件描述符;来唯一标识内核中的这个事件表。这个文件描述符...
2018-12-08 13:16:43
160
原创 I/O复用——poll
I/O复用中poll的系统调用#include<poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);(1)fds参数是一个pollfd结构类型的数组,它指定所有我们感兴趣的文件描述符上发生的可读、可写和异常事件。pollfd的结构体定义如下:struct pollfd{ ...
2018-12-08 13:10:54
978
原创 并行和并发,同步和异步的区别
老是忘记并发和并行,同步和异步之间的区别,今天写篇博客,加深印象。并发 & 并行 并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。这种方式我们称之为并发(Concurrent)。并行:当系统有一个以上CPU时...
2018-12-08 01:17:17
5621
原创 string中的find函数
今天看代码,发现对STL中find函数掌握还是有点少,现在总结一下find函数的用法。 在非string类型的容器里,可以直接找出所对应的元素。find函数需要几个参数:迭代器、下标志、所要找的元素。 例如: vector<int> a; find(a.begin(),a.end(),1); 这句话就表示从a的头开始一直到尾,找到第一个值为1的...
2018-12-07 00:10:38
22028
4
原创 多进程编程——共享内存
进程间通讯有四种方式:信号量、管道、消息队列、共享内存我们之前已着重介绍过信号量、管道。现着重介绍一下共享内存。共享内存 共享内存是最高效的IPC机制,因为它不涉及进程之间任何的数据传输。这种高效率带来的问题是,我们必须用其他辅助手段来同步进程对共享内存的访问,否则就会产生竞态条件。因此,共享内存通过和其他进程间通信方式一起使用。 Linux共享内存的A...
2018-12-05 11:21:40
1928
原创 八大排序——选择排序
选择排序 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。一、算法流程二、复杂度 选择排序的时间复杂度的平均是O(n^2),是选择排序的最差时间复杂度是O(n^2),空间复杂度是O(1)三、稳...
2018-12-04 16:08:35
256
原创 多进程编程——管道
进程间通讯有四种方式:信号量、管道、消息队列、共享内存 我们以前已经介绍过了信号量,今天我们着重介绍一下管道。 管道可以分为有名管道和无名管道。有名管道 有名管道利用管道文件实现进程间通讯,管道文件仅仅是磁盘上的一个文件标识,其真实数据存储在内存上。1.命令:mkfifo filename2.函数:int mkfifo();对于管道文件的打开操作,必须是有...
2018-12-03 23:54:19
639
原创 I/O复用——select的实现
I/O复用I/O复用是指一个进程或一个线程能够同时对多对文件描述符(sockfd)提供服务。那么服务器上的进程或线程如何对多个文件描述符统一监听,当任意一个文件描述符上有事件发生,其都能及时处理?有三种方法,今天我着重介绍一下第一种1.select2.poll3.epollselectint select(int nfds,fd_set *readfds,fd_s...
2018-12-01 16:39:04
198
原创 网络编程——UDP编程
#include<sys/types.h>#include<sys/socket.h>ssize_t recvfrom(int sockfd,void *buf,size_t len,int flags,struct sockaddr* src_addr,socklen_t *addrlen);ssize_t sendto(...
2018-11-30 00:08:30
162
原创 Linux复习(系统编程4)
父子进程1.父子进程之间数据(.data\ .bss\ .stack\ .heap),都是不共享的 父子进程任意一个进程对数据的修改并不会影响另一个进程的数据2.写时拷贝技术 —— .heap段 fork之后,父子进程共享所有的数据区域,但是内核将这些区域设置为只读,父子进程中任意一个进程试图修改数据,内核会将要修改的数据所在的页拷贝一份。 作用:提高f...
2018-11-29 23:08:01
152
原创 网络编程——TCP编程
TCP协议:面向连接,可靠的,字节流服务服务器:socket bind listen accept recv/send close客户端:socket connect send/recv close#include<sys/types.h>#include<sys/socket.h>int ...
2018-11-29 22:23:50
222
原创 八大排序——冒泡排序
冒泡排序 冒泡排序图示:这是一次冒泡排序的过程,详细来说冒泡排序的过程为:1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。3.针对所有的元素重复以上的步骤,除了最后一个。4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。代码:...
2018-11-29 21:07:07
209
原创 TCP,UDP的报头详解
本博客借鉴谢希仁第六版《计算机网络》的第九章TCP报头(1)源端口和目的端口各占2个字节,分别写入源端口号和目的端口号,TCP的分用功能是通过端口实现的。(2)序号占4个字节。序号范围是[0,2^32-1],共2^32(即4282967296)个序号,序号增加到2^32-1后,下一个序号就回到0,也就是说序号使用mod 2^32运算。TCP是面向字节流的。在一个TCP连接中传...
2018-11-29 20:21:54
16103
3
原创 网络编程——TCP与UDP的区别,TCP的连接过程
TCP/IP协议模型位于传输层,只要有TCP,UDP协议组成TCP:面向连接的,可靠的,字节流服务,TCP服务器必须给每个连接分配资源UDP:无连接,不可靠的,数据报服务,UDP不需要给每个连接分配资源面向连接面向连接:在真正通讯之前,必须先建立一条通讯线路,必须先完成连接TCP完成连接的过程: 建立连接:三次握手 断开连接:四次挥手(这里借鉴谢希仁第五...
2018-11-28 23:46:53
603
原创 Linux高性能服务器编程
Linux高性能服务器编程就是在Linux网络编程的基础上,将服务器与客户端建立面向连接时,只能一台服务器与一台客户机通信,改变为一台服务器可以与多台客户端通信。 这里,我们怎样能做到一台服务器与多台客户机通信呢?我们可以通过多进程通信和多线程通信来完成这个功能。 多进程通信是通过fork()函数,由父进程通过fork,生成子进程,实现多进程,使一台服务器可以与多台客户端进行通信。...
2018-11-28 11:06:02
268
原创 线程池的实现
线程池的实现 大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的。在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由该线程执行任务,任务执行完毕之后,线程就退出。这就是"即时创建,即时销毁"的策略。尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较...
2018-11-28 10:52:43
153
原创 Linux复习(系统编程3)
系统调用函数:系统提供的用于上层使用的系统资源的接口。在用户态调用,在内核态执行,由操作系统内核实现。 windows API接口库函数:第三方库 C---->libc C++----->libc++ mudo库 ...
2018-11-18 00:48:16
165
原创 牛客网刷题(五) 寻找回文串(马拉车算法)
题目:设计一个算法,寻找字符串中的最长回文子串。输入一行:一个字符串输出两行:最长回文子串的长度(无则输出0)最长回文子串(无则输出空行)思路:一个回文串它的对称中心可能是某个字符(aba),也可能是某两个字符之间(aa),理论上我们应该分类讨论?但实际上我们这样操作,我们把字符串变成这样(#a#b#)(#a#b#a#)这样一来,无论是什么字符串,它的长度都是奇数,只...
2018-11-17 21:09:20
188
原创 牛客网刷题(四) 2^n(n>=512)
题目:写一个算法实现2的n次方(n>=512)。 输入:一个数字n 输出:2的n次方思路:想要求2^n的值我们首先可能会想到的办法,就是直接计算,但是由于2^n(n>=512)的值过大,没有办法用平常的类型进行存储,所以编译器会直接显示值为0,导致结果错误,那么此时,我们就该思考,应该用什么来存储这个过大的值,我们首先可能会考虑到数组...
2018-11-17 16:18:12
453
原创 牛客网刷题(三)找出数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。 思路:要找到第一个重复的数字,我们可以借鉴哈希的思路,将数组中的值存储到与之下标相同的数组中,比如说a[1]=2,则将...
2018-11-15 19:56:51
501
原创 Linux复习(系统编程2)
文件操作1.Linux平台下的文件操作fopen fread fwrite fclose fseek fgets 库函数open read write close lseek 系统调用函数系统调用函数是系统内核提供给用户访问系统管理的底层硬件接口。系统调用函数用户层只是一个接口...
2018-11-13 21:30:13
150
原创 Linux复习(系统编程1)
main函数的参数int main(int argc, char *argv[], char *envp[])argc代表传递给参数的个数,argv[]表示参数列表,envp[]代表环境变量argc >=1 参数列表中至少有一个参数缓冲区刷新的条件1.遇见\n2.fflush函数3.缓冲区满10244.进程结束exit函数1.进程用_...
2018-11-13 17:01:16
127
原创 C++复习(面向对象1)
构造函数1.没有返回值2.构造函数可以重载3.调用没有参数的构造函数的时候,后面不可以加括号4.对象的生成绝对需要调用构造函数5.没有实现构造函数,编译器会生成一个空的构造函数6.一旦自己实现构造函数,编译器就不会再自己生成构造函数7.构造函数不允许手动调用class CStudent{private: char _name[20]; int _num;...
2018-11-04 14:56:16
156
原创 牛客网刷题(二) 旋转数组的最小值
题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。class Solution {public: int minNumberInRotateA...
2018-10-30 15:04:07
154
原创 线程
线程是进程内部的一条执行序列(执行流),一个进程至少有一个线程,main函数所代表的执行流。通过线程库创建新的线程,称之为函数线程。同一个进程的线程是并发执行的。实现方式1.用户级线程(用户管控线程) 缺点:内核只通过进程PCB管控进程,故无法管控线程,导致线程的实现只能由用户来完成。 当线程阻塞时,内核也无法调控,所以实现复杂度很高 优点:调控...
2018-10-28 23:31:45
134
原创 牛客网刷题(一) 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。class Solution {public: vector<int> printListFromTailToHead(ListNode* head) { stack<int> stack; vector<int> vector; ...
2018-10-24 21:42:15
136
原创 多进程编程——信号量
一、为什么会引进信号量 在这里,我们先说明几个概念。 1.同步:同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而等待。传递信息所产生制约关系。进程的直接制约关系就是源于它们之间的相互合作。2.互斥:互斥亦成为间接制约资源。当一个进程进入临界区使用临界资源时,另一个进程必须等待,当临界资源的进程退出临界区后,另一个进程才...
2018-10-24 21:40:45
1479
原创 C++复习(C和C++的区别2)
空结构体C语言中,空结构体的大小为0;C++中,空结构体的大小为1new和delete #include<iostream>using namespace std;#include<assert.h>int main(){ int *q = new int(10); //指针q和指针p1是等价的 int *p1 = new ...
2018-10-24 20:20:19
162
原创 C++复习(C和C++的区别1)
函数的默认值参数C语言中没有带默认值的函数,C++支持带默认值的函数1.默认值的传入过程 在函数调用点,如果没有传递全部的实参,则会默认传递默认值作为实参。2.默认值的赋值 必须从右向左,依次赋值。 默认值只在本文件有效。 参数默认值在同一作用域下只允许赋值一次,给多次相同的默认值也不可以#include<iostream>using nam...
2018-10-23 22:35:03
572
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人