目录
网络编程并发知识
网络编程知识
网络编程
网络编程大的方面说就是对信息的发送到接收,中间传输为物理线路的作用。百度解析网络编程最主要的工作就是再发送端把消息通过规定好的协议进行组装包,在接收端按照规定好的协议将包解析,从而提取出对应的信息,达到通信的目的。
简单说就是:基于网络编写代码,能够实现数据的远程交互
网络代码分类:静态代码(HTML、JAVASCRIPT、CSS)和动态代码(PHP、JSP、ASP)
学习网络编程的目的:能够开发CS架构的软件
网络编程的必备条件:实现数据的远程交互
计算机之间要想实现数据交互必须要有物理连接介质
软件开发架构
1.C/S架构
C >> Client >>> 客户端
S >> Server >>> 服务端
客户端和服务端一般都需要互联网
服务端的必备条件:
1.24个小时不间断提供服务
2.有固定的地址
3.能够服务多个客人(高并发的情况)
2.B/S架构
B >> Browser >>> 浏览器
S >> Server >>> 服务器/端
浏览器可以充当所有服务器的客户端
B/S架构本质还是C/S架构
3.两者的差异
C/S 架构 优势是不同的公司的客户端由不同的公司独立开发,可以高度定制化客户端功能,缺点是使用之前需要下载
B/S 架构 优势是不用下载就可以直接访问,劣势无法高度定制化,并且需要遵守很多规则
计算机网络的相关专业名词
计算机之间要想实现数据交互必须要连接到一起
1.交换机
2.广播
3.单播
4.广播风暴
5.局域网
6.广域网
7.互联网
8.路由器
OSI七层协议
OSI七层协议包含了应用层、表示层、会话层、传输层、网络层、数据链路层和物理连接层
物理连接层
主要用于计算机之间的物理连接介质,接收数据byte类型(二进制)
数据链路层
1.规定了电信号的分组方式
2.以太网
规定了计算机在出厂的时候都必须有一块网卡,网卡上有一串数字
该数字相当于是计算机的身份证号码是独一无二的
该数字的特征:12位16进制数据
前六位是产商编号 后6位流水线号
该数字也称:以太网地址/MAC地址
注意:以太网地址只能在局域网里面
网络层
IP协议:规定了网络地址的协议,它定义的地址称为IP地址,网络地址是由32位2进制表示
IP地址:规定了所有接入互联网的计算机都必须要有一个IP地址,而IP地址是动态分配的,不同的场所IP是不一样的
IP地址有两种:IPV4 和IPV6
IPV4:点分十进制,ip地址一般写成四段十进制 eg:172.168.1.1
IPV6:能够给地球上的每一粒沙分一个IP地址,IP地址可以跨局域网传输
IP协议的作用
1.为每一台计算机分配IP地址
2.是确定哪些地址在同一个自网络
IP地址可以用来标识全世界独一无二的一台计算机。ARP协议:能够根据IP地址动态解析到一个MAC地址,如:谁在使用某个IP地址,我们就可以根据IP地址动态解析到使用者的MAC地址
MAC地址
1.MAC地址
是电脑的物理地址,是由12位16进制数数字组成,电脑在出厂就固定了,而且每块网络适配器的mac地址是唯一的,一般是不会手动去修改mac地址的。
2.获取mac地址
windows+r >>>输入cmd >>> ipconfig -all
传输层
PORT协议(端口协议)
端口是用来表示一台计算机上面的某一应用软件,范围是0-65535,特征是动态分配。
端口号默认情况:
0-1024:是系统默认使用的端口号
1024-8000:常见软件的端口号
>8000:我们开发软件建议可以使用的端口号,
注意:如果我们使用8000之前的端口号,启动很多个软件,计算机随机分配的端口号会撞号,
URL协议:统一资源定位符
网址本质由IP和PORT组成的 IP+PORT,能够定位全世界独一无二的一台计算机上面的某一个应用程序 。域名解析将就是网址解析成IP+PORT
URL协议:114.55.205.139:80 与端口建议使用冒号连接
实际上,是为了方便阅读,我们才将IP:PORT与字符网址对应起来,我们通过DNS服务就可以将域名转换为IP:PORT的格式,从而访问到网络那一端的程序。
TCP协议
TCP和UDP都是用来与应用程序之间的通信。
一台拥有IP地址的主机可以提供很多服务:Web服务、FTP服务、SMTP服务等,可以通过1IP地址来实现;IP地址与网络服务的关系是一对多的关系,实际上是通过‘IP地址+端口号’来区分不同的服务的
1.TCP协议
当应用程序想要通过TCP与另外一个应用程序通信时,她会发送一个通信请求,这个请求必须被送到一个准确的地址,在对方’握手‘之后,TCP会将在两个应用程序之间建立一个全双工(full_duplex),这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或者双方关闭为止。
1.TCP协议也称可靠协议
2.洪水攻击
3.服务端可以和客户端建立连接的请求(IP)
2.三次握手
TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接。[1]
TCP三次握手的过程如下:
客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
四次来回,中间是可以并为三次的
3.四次挥手
四次不能合并为三次
因为中间需要确认消息是否发完(time_wait)
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。
1.某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
2.接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
3.一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
4.接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
注意:
(1) “通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。
(2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。
(3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。
无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭
UDP协议
UDP协议:称为数据报协议,不可靠协议
TCP与UDP对比
TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
应用层
应用层相当于是程序员自己写的应用程序,里面的协议非常的多 常见的有:HTTP、HTTPS、FTP
socket模块
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
从自己的角度看,socket就是一个模块,通过调用模块可以建立两个进程之间的连接和通信。也有人将socket模块看成IP+PORT,通过IP可以找到一台主机的位置,而通过端口PORT可以找到电脑上的一个应用程序,并通过socket模块实现网络通信,达到跨主机通信
socket模块,也称套接字
socket模块的基本使用
socket.socket() 产生一个socket对象
bind() 绑定地址
listen() 侦听客户请求(半连接池)
connect() 连接服务器
accept() 等待客户端链接
send() 发送消息
recv() 接收消息
半连接池的概念
server.listen(5)
当有多个客户端来连接的情况下,我们可以是设置等待数量(不考虑并发问题)
注意:半连接池就是为了缓解服务端和客户端建立链接的压力
黏包现象
当客户端连续给服务端发送多次消息(数据很小),客户端通过tcp发送消息,将存放缓冲区的消息一次性发送给服务端,首先数据存放在服务端的缓冲区,服务端根据每次recv()接收的长度去缓冲区拿数据,recv() 一次拿不完的,第二次接收数据基于第一次拿的最后一个字节开始拿。
黏包产生的原因:
黏包现象只发生在TCP协议中:
1.从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。
2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的 。
为了解决黏包问题,我们引入了struct 模块。
struct模块
这个模块可以把要发送的非固定数据长度转为固定的数据长度4,语法结构为:strct.pack('i',len(数据变量名)) ,i是固定的参数,这个打包的过程称为‘报头’
import struct
info = b'hello world'
print(len(info)) # 11
# 将数据打包固定的长度
res = struct.pack('i',len(info))
# 打包之后的长度称为报头 是二进制
print(len(res))
# 解析真实的长度
real_len = struct.unpack('i',res)
print(real_len)
解决黏包现象的方法
利用字典制作固定的报头,效果会更好,下面例子请看
客户端
1.制作真实数据的信息字典
2.将字典序列化并编码统计长度
4.利用struct 模块制作字典的报头
5.发送固定长度的报头
5.发送字典数据
6.发送真实的数据
服务端
1.接收固定长度的字典报头
2,利用struct模块反向解析出字典的长度并接收
3.通过字典获取真实数据并处理成字典
4.接收真实数据长度
例子
并发编程理论
进程理论
操作系统的发展史:穿孔卡片阶段>>联机批处理系统>>>脱机批处理系统
多道技术:单道技术和多道技术
单道技术:所有的程序排队执行,过程中不能重合
多道技术:利用空闲时间提前准备其他数据,最大化提升CPU利用率
多道技术有两种状态:切换(io操作,程序长时间占用CPU)和保存
进程理论
程序是指令和数据的有序集合,进程是程序在处理机上的一次执行的过程,是一个动态的概念。简单的理解:程序就是一堆死代码(没有允许起来) 进程就是正在运行的程序。
想要多个进程交替运行,操作系统必须对这些进程进行调度,引入了调度算法。
调度算法
1.FCFS(先来先服务)调度算法
适合长作业
2.短作业优点调度算法
对短作业/进程优先调度的算法
3.时间片轮转法
时间片轮转(Round Robin,RR)法的基本思路是让每个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。
4.多级反馈队列
而多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。
- 应设置多个就绪队列,并为各个队列赋予不同的优先级。
2)当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。
- 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。
进程的并行与并发
并行:多个进程同时执行 ,必须要有多个CPU参与 单个CPU无法实现并行,
并发:并发是指资源有限的情况下,两者(多者)替轮流使用资源。多个进程看上去像同行执行
高并发:评论程序同时服务客户端数量的能力
进程三状态:就绪态,运行态、阻塞态
同步与异步:用来表达任务的提交方式
阻塞与非阻塞:用来表达任务的执行状态
线程理论
协程理论
数据库知识
数据库的基本知识
存取数据的演变史
1.文本文件
2.软件开发目录规范
3.数据库服务
数据库软件的应用史
1.单机游戏
2.联机游戏
3.集群
数据库服务集群的目的史:提高数据的安全性
数据库的本质
数据库本质其实就是一款CS架构的软件,意味着所有的程序员其实都有资格编写一款数据库软件。通过之前所学的TCP客户端和服务器,可以做基本的交流操作。
-
站在底层原理的角度 数据库指的是操作数据的进程(一堆代码)
-
站在实际应用的角度:数据库指的是可视化操作界面(一些应用软件)
数据库的分类
1.关系型数据库:具有固定的表结构,并且表与表之间可以通过外键建立关系
关系型数据库有:MySQL、MariaDB、Oracle、PostgreSQL、sqlserver、sqlite、db2、access等
-
1 MySQL
主要用于大型门户,例如搜狗、新浪等,它主要的优势就是开放源代码、使用最广以及性价比高。 因为开放源代码这个数据库是免费的,他现在是甲骨文公司的产品。
-
1 Oracle
这个数据库是收费的,虽然维护成本高但是安全性也最高。大型公司可能会使用,主要用于银行、铁路、飞机场等,该数据库功能强大,软件费用高,也是甲骨文公司的产品。
-
1 MariaDB
SUN被甲骨文收购后,MySQL 的原创人员有拉出另外一个分支,命名MariaDB 。该数据库被维基百科,Facebook 甚至 Google 等技术巨头使用。 MariaDB 是一种可为 MySQL 提供插件替换功能的数据库服务器。开发人员的首要关注点是安全性,在每个版本发布时,开发人员还会合并所有 MySQL 的安全修补程序,并在需要时对其进行增强。(开源免费)
-
1 PostgreSQL
开源免费,支持二次开发,兼容性极高。
-
1 sqlserver
微软公司的产品,主要应用于大中型企业,如联想、方正等。
-
1 sqlite
小型数据库,主要用于本地测试
2.非关系型数据库:没有固定的表结构,数据存储采用K:V键值对的形式;数据之间无法建立数据库层面的关系
非关系型数据库有:redis、mongoDB、memcache
-
1 redis 目前最火的缓存数据库 具有很多数据结构 功能强大(多用来作为缓存),虽然缓存数据库史基于内存做数据库存取,但是具有持久化功能,有日志记录,不易丢失
-
1 mongoDB
文档型数据库,最像关系型数据库的非关系型数据库,用在大数据和爬虫(可用来作为后端数据库管理软件)
-
1 memcache
已经被redis淘汰(多用来作为缓存)
注意:数据库软件很多,但是操作方式几乎差不多,其中以MySQL最为典型。
MySQL知识
MySQL是一个关系型数据管理系统。本质就是有一个基于socket编写的C/S架构的软件,MySQL是一个开放源代码的数据库,可以跨平台的操作系统运行。
1.版本问题
8.0 :最新版>>>苹果电脑推荐最新版
5.7 :使用频率最高
5.6 :学习推荐使用
2.下载与使用
官网下载>>选版本>>存路径要简单>>配置环境变量
MySQL基本数据类型
在cmd端打开MySQL,要管理员身份进入
要是没有配置环境,要手动切换到存储路径下的bin目录,输入mysqld 打开了服务端,窗口不用关,再重新启动客户端(输入mysql)的bin目录下,
mysql -uroot -p 以管理员的身份
mysql -u用户名 -p密码 用户身份进入
mysql的基本使用
1.查看库 show databeses;
2.查看表 show tales;
4.取消之前的命令 \c或者直接运行报错
5.退出客户端 exit;
要把mysql 添加到系统服务
1.直接电脑任务管理器中选择服务,找到mysql ,选中鼠标右键启动
2.在cmd命令端执行
以管理员身份打开cmd
mysqld --install
首次启动可能需要手动启动或者net start mysql
3.卸载重装
net stop mysql
mysql --remove
4.计算计算机运行程序数
services.mac
5.修改密码
1.mysqladmin -u用户名 -p原密码 password 新密码
2.直接修改存储用户数据的表
3.set password=password('新密码')
6.忘记密码
1.卸载重装
2.把data目录删除,拷贝同桌的目录
3.小把戏
关掉服务端net stop mysql,以跳过授权表的方式重启服务端(不校验密码)mysql --skip-grant-table
重新打开一个cmd,以mysql -uroot -p直接登录修改密码
update mysql.user set password=password('123') where host='localhost' and user='root'
关掉服务器,然后重新启动net start mysql
SQL语句
SQL语句:就是操作数据库软件的命令
SQL
操作关系型数据库的语言。有时SQL也称关系型数据库。
NoSQL
操作非关系型数据库的语言。有时NoSQL也称非关系型数据库。
常见的sql语句
基于库的增删改查
create database 库名;
show databases; show create database 库名;
alter database 库名 charset='utf8';
drop database 库名;
基于表的增删改查
use 库名
create table;
show tables; show create table 表名;desc 表名
alter table 表名 rename 新表名;
drop table 表
基于记录的增删改查
Insert into 表名 values(数据值1,数据值2);
select * from 表名;
update 表名 set 字段名=新数据 where 筛选条件;
delete from 表名;delete from 表名 where id=2;
MySQL的字符编码和配置文件
1.查看MySQL相关信息 \s
2.想要永久修改编码配置,需要操作配置文件。配置完成需要重启服务器
数据库存储引擎
存储引擎:数据库针对数据才去的存取方式
1.查看常见存储引擎的方式
show engines;
2.基本的存储引擎
1.MyISAM
MySQL5.5之前的存储引擎,存取数据的速度快,但是功能性少,安全性较低
2.InnoDB
MySQL5.5之后的存储引擎,因为支持事物、行锁、外键等操作,存取速度没有MySQL快,但是安全性更高
3.Memory
基于内存存取数据 仅限临时表数据存取
4.BlackHole
任何写入进去的数据都会立刻丢失
创建表的完整语法
create table 表名(
字段名 字段类型(数字) 约束条件,
字段名 字段类型(数字) 约束条件,
字段名 字段类型(数字) 约束条件
);
MySQL基本数据类型
整型
tinyint smallint int bigint
严格模式
show variable liki '%mode%'
1.临时修改
set session sql_mode = 'strict_trans_tables' # 在当前客户端
set global sql_mode ='strict_trans_tables' # 在当前服务器有效
2.永久修改
直接修改配置文件
浮点型
float
double
decimal
精确度排名:float <double < decimal
字符串
char 定长 最多存储四个字符,超出就会报错,不够四个空格就填充至四个
varchar 变成 最多存储四个字符,超出就会报错,不够则有几个就存几个
枚举及集合
1.枚举
gender enum('male','female','others')
当表中有枚举,我们在添加表记录的时候只能从里面条件选择一个条件添加,不然会报错
2.集合
hobbies set('basketabll','football','doublecolorball')
当表中有集合,表示我们添加表记录的时候可以选一个或者多个条件添加数据
日期类型
datetime
date
time
year
字段之约束条件
无符号、零填充
unsigned:取消正负号
create table t1(id tinyint unsigned );
zerofill:j=控制展示的长度,一般以五位
create table t2(id int(5) zerofill)
非空
所有字段类型不加约束条件的情况下默认都为空,加约束条件not null (不为空)表格显示不为null
name varchar(32) not null
默认值
创建表格的时候,给字段类型添加默认值,添加字段值的时候,如果没有指定的值表格里面显示的是默认值。
name varchar(32) default '默认'
唯一值
create table t3(
id int unique;
age int unique
)
1.单例唯一:提前给字段添加了unique,那么添加的字段类型只能有一个字段值,添加过了再添加同样的字段值就会报错,有且只有一个唯一值,如果没有添加unique,说明可以添加重复的字段值。
2.联合唯一:提前 为ip和端口添加了联合唯一,即unique(ip,port),那么表示:添加的一条记录里面有添加过的端口和ip出现,就会报错;如果只有端口或者ip重复,是不会报错的
主键
1.单例主键(热门)
id int primary key
2.联合主键
sid int,
uid int,
primary key(sid,uid)
主键不能为空,且要有唯一的值(非空且唯一
InnoDB存储引擎规定所有的表必须有且只有一个主键
1.当表中没有主键也没有其他非空且唯一的字段的情况下,innoDB会采用隐藏的字段作为表的主键,隐藏意味着无法使用,基于该表的数据查询只能一行行查找,速度很慢
2. 当表中没有主键,但是有其他非且唯一的字段,那么会从上面往下将第一个该字段自动升级为主键
create table t4(
id int,
name varchar(32) not null unique,
phone bigint not null unique,
user_id int not null unique,
height float not null unique
);
主键就是name
自增
主要是配合主键一起使用
id int primary key auto_increment;
自增不会因为数据的删除而回退,永远基于被删除最后一个数字号(如45)自增往前;如果自己手动添加了200号,那之后就基于200号往前自增;如果想重置某张表的主键值,可以使用 truncate t10;>>>清空表数据并重置主键
外键
一对多
1.创建表的收一定要先创建被关联表
2.录入表数据的时候一定要先录入被关联表
3.修改数据 的时候外键字段无法修改和删除
简化操作>>>: 级联更新级联删除
create table employee(
id int primary key auto_increment,
name varchar(32),
age int,
department_id int,
foreign key(department_id) references department(id)
);
create table department(
id int primary key auto_increment,
department_name varchar(32),
department_desc varchar(64)
);
多对多
外键是从两个表中抽出来,单独写的,如下
create table book(
id int primary key auto_increment,
title varchar(32),
price float(5,2)
);
create table author(
id int primary key auto_increment,
name varchar(32),
phone bigint
);
create table book2author(
id int primary key auto_increment,
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);
一对一
一对一跟一对多有类型,但是就是在一个表中加入唯一性,跟一对多区分开来
create table user(
id int primary key auto_increment,
name varchar(32),
detail_id int unique, # 添加了unique
foreign key(detail_id) references userdetail(id)
on update cascade
on delete cascade
);
create table userdetail(
id int primary key auto_increment,
phone bigint,
personal varchar(64),
spacecolor varchar(128)
);
SQL语句查询关键字
select
select * ;
select name;
select char_length(name);
from
from mysql.user;
where
查询 id大于等于3,小于等于6的数据
select * from emp where id >=3 and id <= 6
模糊查询:like
select * from emp where name like '%o%';
group by
分组我们通常和聚合函数一起使用(max/min/sum/count)
having
having和where的本质都是对数据做筛选的,where是分组之前首次筛选,只不过having是在where分组之后做二次筛选
1.统计各部门年龄在30岁以上的员工平均工资 并且保留大于10000的数据
select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;
distinct
select distinct age,post from emp;
关键字是针对的多个字段组合的结果
order by
1.单个字段
select * from emp order by age; # 默认升序
select * from emp order by age asc; # asc 升序
select * from emp order by age desc; # desc 降序
2.多个字段
select * from emp order by age,salary desc;
先按照年龄升序排列,相同的年龄再按照薪资降序排序
limit
select * from emp limit 5; # 直接限制展示的条数
select * from emp limit 5,5; # 从第5开始往后读取5条
regexp
SQL语句的模糊匹配如果用不习惯 也可以自己写正则批量查询
select * from emp where name regexp '^j.*?(n|y)$';
标签:int,数据库,编程,TCP,MySQL,数据,id
From: https://www.cnblogs.com/zhanglanhua/p/16930954.html