目录
重载(Overloading)和重写(Overriding)
TCP和UDP概念和区别
TCP和UDP都是互联网传输协议,但它们之间存在着许多区别。以下是一些主要的区别:
- 连接方式:TCP是一种面向连接的协议,需要在通信开始前建立连接,并在通信结束后断开连接。UDP则是一种无连接的协议,每次通信都是独立的。
- 数据可靠性:TCP提供了可靠的数据传输,通过三次握手等机制确保数据的完整性和可靠性。UDP则不保证数据的可靠性,因此在网络传输中容易出现数据丢失或重复等问题。
- 传输效率:由于TCP需要建立连接、确认数据、维护状态等过程,使得它的传输效率相对较低。UDP则是一种轻量级的协议,没有这些额外的过程,因此传输效率相对较高。
- 应用场景:TCP适用于需要可靠传输的应用场景,如Web浏览、电子邮件、文件传输等。UDP则适用于实时性要求较高的应用场景,如音频和视频流媒体、网络游戏等。
- 端口使用:TCP和UDP都使用端口进行通信,但它们使用的端口是不同的。TCP使用的端口是一个16位的整数,范围在0~65535之间。UDP使用的端口也是16位的整数,但它的范围是0~65535之间,其中0~1023被保留为系统端口。
使用浏览器访问一个网页时
dns解析-tcp连接-http请求发送-服务器处理并返回http报文-浏览器解析渲染-连接结束
流程可简化为:
(1)DNS域名解析
(2)与目的主机进行TCP连接(三次握手)
(3)发送与收取数据(浏览器发起http请求)
(4)与目的主机断开连接(四次挥手)
原文链接:https://blog.csdn.net/weixin_54535063/article/details/126996939
详解Python的装饰器
def debug(func):
def wrapper(*args, **kwargs): # 指定宇宙无敌参数
print "[DEBUG]: enter {}()".format(func.__name__)
print 'Prepare and say...',
return func(*args, **kwargs)
return wrapper # 返回
@debug
def say(something):
print "hello {}!".format(something)
【Git】分支管理--创建新分支、删除分支、恢复分支
1、查看所有分支
git branch -a
2、切换到将要复制的现有分支
git checkout [sourceBranch]
sourceBranch 为接下来要复制到新分支的现有分支名。创建的新分支依赖当前所在分支,且新分支一旦创建不能更改依赖,所以要提前切换到希望复制的分支
3、创建新分支
git branch [newBranch]
newBranch 为新分支名
4、push内容到新分支
git push origin [newBranch]
newBranch 为新分支名,将当前内容 push 到新分支
二、删除分支
2.1、删除分支的本地
2.1.1、切出其他分支
git checkout [otherBranch]
otherBranch 为其他分支名,从将要删除的分支切换到其他分支
2.1.2、删除分支的本地
git branch -d [deleteBranch]
deleteBranch 为要删除的分支名,在分支未合并到其他分支的情况下,参数 -d 无法删除分支,需要使用强制删除参数 -D ,如下
git branch -D [deleteBranch]
解析 HTTP 与 HTTPS 的区别
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
二、HTTP与HTTPS有什么区别?
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。
最常用的linux命令
20个linux常用命令
1. ls:列出文件list
2. cd:切换目录change directory
3. cp:复制copy
4. mv:移动move
5. rm:移除,删除remove
6. mkdir:创建文件夹make directory
7. rmdir:移除,删除文件夹remove directory
8. chown:更改所有者change owner
9. chmod:更改文件的权限模式change mode
10. find:查找
11. |:管道
12. grep:按行查找并匹配
13. tar:打包,压缩,解压
14. cat:打印文件内容
15. ps:查看进程process select
16. kill:杀死进程
17. passwd:修改密码password
18. pwd:显示工作目录print work directory
19. tee:显示并保存
20. reboot:重启
数据库SQL
模糊查询
select
*
from
tb_brand
where
name like '%林%';
顺序
书写顺序
SELECT 字段列表
FROM 表名
WHERE 记录筛选条件
GROUP BY 分组字段列表
HAVING 分组筛选条件
ORDER BY 排序字段列表
执行顺序
FROM->WHERE->GROUP BY->HAVING->SELECT->ORDER BY
具体的说:
FROM:组装来自不同数据源的记录
WHERE:根据指定的条件过滤上一步检索出的记录
GROUP BY:对上面过滤后的记录按指定条件分组
SUM/AVG/COUNT:使用聚合函数进行计算
HAVING:对所有分组根据指定条件进行过滤
SELECT:从上一步过滤后的各个分组记录中提取指定查询的字段列表(包括聚合字段、计算字段、表达式字段等)
ORDER BY:对上一步查询得到的结果集按照排序字段列表进行排序,并输出排序结果
SELECT
spu.`name`,spu.`caption`
FROM
tb_spu spu
WHERE
spu.name LIKE '华为%' OR spu.name LIKE '摩托%';
联合查询 union
select * from class
union
select * from person;
插入数据
INSERT INTO 表名称 VALUES (值1, 值2,....) //全字段
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....) //指定字段
INSERT INTO <表名> [ <列名1> [ , … <列名n>] ] VALUES (值1) [… , (值n) ];
删除数据
DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]
DELETE FROM 表名称 WHERE 列名称 = 值
数据库中delete、truncate和drop的区别
不同点:
1. 从删除内容上区分:
truncate和 delete只删除数据不删除表的结构(定义)
drop语句将删除表的结构、被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态.
2.从语句类型上来区分:
delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发.
truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger.
3.从对表空间的影响来区分:
delete语句不影响表所占用的extent, 高水线(high watermark)保持原位置不动
drop语句将表所占用的空间全部释放
truncate 语句缺省情况下将空间释放到 minextents个extent,除非使用reuse storage;而且truncate会将高水线复位(回到最开始).
4.从速度的区别:
一般来说: drop> truncate > delete
索引
建立主键或唯一约束时,自动创建索引。
小的数据表不应当使用索引;
需要频繁进行大批量的更新或者插入操作的表;
如果列中包含大数或者 NULL 值,不宜创建索引;
频繁操作的列不宜创建索引。
建立单列索引,可不写列,或写多个列用‘,’分隔
CREATE INDEX index_name ON table_name(column_name);
建立唯一索引
CREATE UNIQUE INDEX index_name
on table_name (column_name);
取消索引
ALTER TABLE table_name DROP INDEX index_name
进程和线程
进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值。
进程有哪些特征?
- 进程依赖于程序运行而存在,进程是动态的,程序是静态的;
- 进程是操作系统进行资源分配和调度的一个独立单位(CPU除外,线程是处理器任务调度和执行的基本单位);
- 每个进程拥有独立的地址空间,地址空间包括代码区、数据区和堆栈区,进程之间的地址空间是隔离的,互不影响。
进程与线程的区别总结:
本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
影响关系:一个进程崩溃后,在保护模式下其他进程不会被影响,但是一个线程崩溃可能导致整个进程被操作系统杀掉,所以多进程要比多线程健壮。
java基础,equals和==的区别
1、equals():用来检测两个对象是否相等,即两个对象的内容是否相等。是判断两个变量或实例所指向的内存空间的值是不是相同。
2、 ==:用于比较引用和比较基本数据类型时具有不同的功能。
- 如果是基本数据类型,==判断的是值
- 如果是对象类型,==判断的是对象的地址
- 对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是内存中的存放位置的地址值,跟双等号(==)的结果相同;如果被复写,按照复写的要求来。
- 但在一些类库中已经重写了这个方法(一般都是用来比较对象的成员变量值是否相同),比如:String,Integer,Date 等类中
重载(Overloading)和重写(Overriding)
重载(Overloading)和重写(Overriding)是面向对象编程中的两个重要概念,它们的主要区别在于发生的位置和方法签名的要求。
重载(Overloading):
- 重载发生在同一个类中。
- 当两个或多个方法在同一类中具有相同的名称,但参数列表不同时,这些方法被认为是重载的。
- 参数列表的不同可以是因为参数的数量、类型或顺序不同。
- 返回类型可以不同,但仅返回类型的不同不足以构成重载。
- 重载的方法可以有不同的访问修饰符和抛出的异常。
- 重载是Java多态性的一种表现形式,主要用于提供同一个方法的不同版本。
重写(Overriding):
- 重写发生在有继承关系的两个类之间,即子类中。
- 当子类有一个方法的名称、返回类型和参数列表与父类中的某个方法相同时,子类的这个方法被认为是重写了父类的方法。
- 方法签名必须完全相同,即名称和参数列表。
- 返回类型必须相同,或者是子类类型(协变返回类型)。
- 访问级别不能更低,子类方法不能拥有比父类方法更严格的访问级别。
- 只能重写非静态方法,静态方法不能被重写,它们只能被隐藏。
- 必须保持一致的或更宽松的异常声明。
- 重写是用于实现继承关系中的多态性,允许子类改变或扩展父类的行为。
final关键字
`final` 关键字在多种编程语言中都有使用,其含义是“不可变的”或“最终的”。在 Java 中,`final` 是一个关键字,它可以用来修饰局部变量、成员变量、方法和类。1
- 当 `final` 用于修饰变量时,该变量的值一旦被赋值后就不能改变。对于基本数据类型的变量,`final` 保证的是数值不可变;对于引用类型的变量,`final` 保证的是引用不可变,即指向的地址值不可变,但指向的对象内容可以改变。
- 当 `final` 用于修饰方法时,该方法不能在子类中被重写。这可以防止子类修改父类的实现方式。
- 当 `final` 用于修饰类时,该类不能被继承,即不能有子类。这确保了类的实现不会被修改。
在 C++11 中,`final` 是一个说明符,而不是关键字。它可以用来阻止派生类覆盖特定的虚方法,或者阻止一个类成为基类。例如,如果一个类的某个虚函数被声明为 `final`,则派生类不能重写这个函数。同样,如果一个类被声明为 `final`,则不能从这个类派生出新的类。
数组和链表的区别以及各自的优缺点
1.数组和链表的区别:
(1)数组的元素个数是固定的,而链表的结点个数可按需要增减。
(2) 数组元素的存储单元在定义时分配,链表节点的存储单元在执行时动态向系统申请。
(3)数组的元素顺序关系由元素在数组中的位置(即下标)确定,链表中的节点关系由节点所包含的指针来体现。
(4)对于不是固定长度的列表,用可能最大长度的数组来描述,会浪费许多的存储空间。
(5)对于元素的插入、删除操作非常频繁的列表处理场合,用数组表示列表也不是不合适。若用链表实现,会使程序结构清晰,处理的方法也比较简便。
2.数组的特点
(1)在内存中,数组是一块连续的区域。
(2)数组需要预留空间,在使用前要先申请内存的大小,可能会浪费内存空间。
(3)插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中要向后移。
(4)随机读取率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给的地址数据。
(5)并不利于扩展,数组定义的空间不够时要重新定义数组。
3.链表的特点
(1)在内存中可以存在如何地方,不要求连续。
(2)每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。
(3)增删数据很容易。
(4)查找数据时效率低,因为不具有随机访问性。
(5)不指定大小,扩展方便。链表大小不用定义,数据随意增删。
4.数组的优点
(1)随机访问性强。
(2)查找速度快。
5.数据的缺点
(1)插入和删除效率低。
(2)可能会浪费空间。
(3) 内存空间要求高,必须有足够的连续内存空间。
(4)数组大小固定,不能动态拓展。
6.链表的优点
(1)插入删除速度快。
(2)内存利用率高,不会浪费内存。
(3)大小没有固定,拓展很灵活。
7.链表的缺点
不能随机查找,必须从第一个开始遍历,查找效率低。
面向对象和面向过程的区别
面向过程就是分析出解决问题需要的步骤,然后用函数把步骤实现,使用时依次调用;
面向对象就是把整个问题分成多个对象,然后提供对象在解决整个问题的步骤中所需要的功能;
面向过程:
不需要实例化,性能较高,但是不易维护,复用扩展;
面向对象:
需要实例化,降低代码直接的耦合,使系统更加灵活、易于维护、易于扩展。
死锁问题
死锁定义:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
产生死锁需要四个条件:
1)互斥条件:一个资源只能被一个进程使用;
2)请求与保持条件:一个进程因为请求资源而阻塞时,对已获取资源保持不放;
3)不可抢占条件:进程已获取的资源,不能强行剥夺,只能自己释放;
4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
.避免死锁的方法:
(1)破坏“互斥”条件:就是在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。但一般“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他三个必要条件,而不去涉及破坏“互斥”条件。
(2)破坏“请求和保持”条件:在系统中不允许进程在已获得某种资源的情况下,申请其他资源。即要想出一个办法,阻止进程在持有资源的同时申请其他资源。
方法一:所有进程在运行之前,必须一次性地申请在整个运行过程中所需的全部资源。这样,该进程在整个运行期间,便不会再提出资源请求,从而破坏了“请求”条件。系统在分配资源时,只要有一种资源不能满足进程的要求,即使其它所需的各资源都空闲也不分配给该进程,而让该进程等待。由于该进程在等待期间未占有任何资源,于是破坏了“保持”条件。
该方法优点:简单、易行且安全。
缺点:a.资源被严重浪费,严重恶化了资源的利用率。b.使进程经常会发生饥饿现象。
方法二:要求每个进程提出新的资源申请前,释放它所占有的资源。这样,一个进程在需要资源S时,须先把它先前占有的资源R释放掉,然后才能提出对S的申请,即使它可能很快又要用到资源R。
(3)破坏“不可抢占”条件:允许对资源实行抢夺。
方法一:如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源。
方法二:如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。只有在任意两个进程的优先级都不相同的条件下,该方法才能预防死锁。(4)破坏“循环等待”条件:将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出。这样做就能保证系统不出现死锁。
GET和POST的区别
a.get请求一般是去取获取数据;post请求一般是去提交数据。
b.get因参数会放在url中,所以隐私性,安全性较差,请求的数据长度是有限制的,不同的浏览器和服务器不同,一般限制在 2~8K 之间,更常见的是 1k 以内;post请求是没有的长度限制,请求数据是放在body中,安全性较好;
c.get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。
d.get请求可以被缓存,post请求不会被缓存。
e.get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就是url中,但post不能,它的参数不在url中
乐观锁和悲观锁区别
乐观锁和悲观锁是两种常见的并发控制机制,用来处理多线程或多进程环境下的并发问题。二者的主要区别在于对并发修改数据时锁的策略不同。
悲观锁
悲观锁假设每次数据访问都会发生冲突,因此在访问数据之前,必须先获取锁,读取或修改完成后再释放锁。这种方式对于对数据的修改频率较高、并发性较强的情况下,会造成比较大的性能损失。在实现过程中,通常是通过数据库的锁机制或者操作系统的文件锁实现。悲观锁总结为以下几点:
假设同一时间会有其他线程修改数据;
在访问数据之前必须先获得锁;
保证数据的互斥访问,但效率低下。
乐观锁
乐观锁更加优化,在读和写数据操作时,先不加锁进行操作,同时记录下数据版本号。当需要对数据进行修改时,先比较当前数据版本号与修改前的数据版本号是否一致,如果一致则说明在进行修改操作期间数据没有被其他线程修改,可以进行更新,并将版本号增加;与此同时,如果版本号不一致,则说明在操作期间有其他线程对数据进行了修改,此时必须回滚整个事务,重新读取数据,再重复上述操作。这种方式适用于更多的写入操作并不频繁,而是以读操作为主的情况,如缓存维护等场景。在实现上,可以使用版本号、时间戳等方式来实现乐观锁。乐观锁总结为以下几点:
假设同一时间不会有其他线程修改数据;
在执行更新操作时,先比较版本号(或时间戳);
提高效率,但可能会导致数据不一致。
总之,乐观锁适用于写少读多的情况,悲观锁适用于写多读少的情况。在并发控制的实践过程中,可以根据具体业务场景的需求,选择相应的锁机制来进行数据的操作和控制。
排序
红黑树
红黑树具有以下特点
- <font color = blue>每个结点不是黑色就是红色
- <font color = blue>根结点必须是黑色的
- <font color = blue>红色结点的两个子结点必须都是黑色的,这保证了没有两个连续的红色节点相连
- <font color = blue> 每个叶子结点都是黑色的(此处的叶子结点指的是空结点,也被称为NIL节点)
- <font color = blue>任意结点到其每个叶子结点的简单路径上,黑色节点的数量相同:确保了树的黑平衡性,即红黑树中每条路径上黑色结点的数量一致。
进程调度
计算机网络模型
数据在应用层,表示层,会话层均是报文;
传输层:TCP/UDP端口+报文--------数据段
网络层:IP头部+数据段(TCP/UDP端口+报文)--------数据包
数据链路层:MAC头部+数据包(IP头部+TCP/UDP端口+报文)--------数据帧
物理层:比特流