加油加油
文章目录
1. TCP与UDP的区别
TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)都是互联网协议,但它们在很多方面有所不同。
连接方式:TCP是一种基于连接的协议,而UDP则是一种无连接的协议。这意味着对于使用TCP的应用程序,必须先建立一条连接才能进行通信,而UDP则直接发送数据包。
可靠性:TCP是一种可靠的传输协议,保证数据的完整性和正确性,因为它会对每个数据包进行确认和重传,确保数据的送达和顺序性。而UDP则没有这些机制,因此发送的数据包可能会丢失或乱序。
速度:由于TCP的可靠性机制,其传输速度比UDP慢,因为TCP需要等待确认,而UDP则可以快速地发送数据包,因此UDP传输速度更快。
带宽利用率:TCP的传输控制机制会根据网络情况动态调整传输速率,以充分利用带宽,而UDP则不具备这种机制,其传输速率固定,没有自适应性。
应用场景:由于TCP的可靠性和完整性,它常用于需要可靠传输的应用程序,如文件传输、电子邮件和 Web 浏览器。而UDP则常用于实时应用程序,如视频流、语音通话和在线游戏,因为这些应用程序需要快速响应,并且可以容忍一定的数据包丢失或乱序。
2. TCP为什么是四次挥手机制
TCP断开连接需要进行四次挥手的原因是为了确保数据的可靠传输和避免孤立的数据包。
首先,当一方想要关闭连接时,它会发送一个FIN(finish)分节给另一方,表示它已经没有数据要发送了,并请求关闭连接。这是第一次挥手。
接着,收到FIN的另一方会发送一个ACK(acknowledgment)分节作为确认,表示它已经收到了关闭请求,并且同意关闭连接,这是第二次挥手。
但是,此时另一方还可能有数据要发送给发送关闭请求的一方,所以它不会立即关闭连接,而是继续发送数据,直到所有数据都发送完毕。然后它才会发送一个FIN分节给发送关闭请求的一方,表示它也已经没有数据要发送了。这是第三次
收到FIN的一方会发送一个ACK分节作为确认,表示它也同意关闭连接,并且这个ACK分节也可以携带一些最后的数据。这是第四次挥手。
最后,发送关闭请求的一方先不要急于断开连接,会在发送ACK后等待2MSL,由于这个ACK有可能发送不成功,那么接收方未收到ACK,会进行超时重传,所用的时间就为2MSL,若未发现超时重传,则代表可以正式断开连接。
通过这种方式,TCP断开连接的过程可以保证数据的可靠传输和避免孤立的数据包。
3. HTTP与HTTPS的区别
HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是两种不同的网络协议,它们在以下方面有所区别:
安全性:HTTP是一种不加密的明文协议,数据可以被第三方窃听和篡改;而HTTPS通过使用在HTTP的基础上, 采用SSL或TLS协议加密传输数据,确保数据在传输过程中不会被窃听和篡改。
数据传输速度:由于HTTPS需要进行加密解密操作,导致其传输速度比HTTP要慢一些。
端口号:默认情况下,HTTP使用80端口,HTTPS使用443端口。
证书:为了使用HTTPS,网站需要购买数字证书并安装到服务器上,以保障通信的安全性。而HTTP不需要证书。
认证方式:通过HTTPS连接访问的网站,在建立连接时会进行双向认证,即浏览器验证服务器证书的真实性,同时服务器也会验证浏览器的身份。而HTTP没有认证机制。
综上所述,HTTP和HTTPS在数据传输的安全性、速度、端口号、证书和认证方式等方面存在显著的差异。为了保护用户的隐私和网站的安全,使用HTTPS成为越来越普遍的选择。
4. HTTPS加密机制
HTTPS的加密机制基于公钥加密和对称密钥加密相结合的方式来保障数据传输的安全性。具体流程如下:
客户端向服务器发起HTTPS请求。
服务器将自己的数字证书发送给客户端,证书中包含了服务器公钥以及一些相关信息(比如证书颁发机构、有效期等)。
客户端收到证书后,会验证其真实性。如果证书有效且可信,则生成一个用于对称加密的密钥(也就是会话密钥),并使用服务器公钥对该密钥进行加密,然后发送给服务器。
服务器收到客户端发送的加密后的会话密钥后,使用自己的私钥进行解密,并得到原始的会话密钥。
客户端和服务器之间的通信会使用这个会话密钥进行对称加密和解密。由于对称加密速度快,因此通过交换加密后的会话密钥,可以在保证数据安全的同时,避免繁琐的公钥加密过程。
通过以上步骤,HTTPS能够确保通信过程中的数据不会被窃听、篡改或伪造。同时,在HTTPS连接建立过程中,双方可以进行身份验证,从而进一步确保通信的安全性。
总结一下就是
客户端点击网站,获取证书及证书中的公钥及认证信息。
客户端验证后,生成对称密钥,使用公钥进行加密传输
服务器私用私钥进行解密,得到对称密钥。
客户端与服务器,使用这个对称密钥进行加密解密。
5. 简要介绍SSL/TSL协议
TSL (Transport Layer Security) 协议是一种用于保障网络通信安全的协议,与其前身 SSL (Secure Sockets Layer) 协议类似。TSL 协议通过使用加密和认证机制来确保客户端和服务器之间的通信不被第三方窃听、篡改或伪装。
TSL 协议在传输层提供了安全的数据传输服务,它使用公钥加密技术(如 RSA)和对称加密技术(如 AES)对通信过程进行加密,并使用数字证书验证服务器的身份。TSL 还支持双向认证机制,即客户端和服务器都需要进行身份验证。
6. GET与POST的区别
GET 和 POST 是两种常见的 HTTP 请求方法,它们在以下几个方面有所不同:
数据传输方式:GET 方法通过 URL 传递请求参数,而 POST 方法通过请求体传递参数。
数据传输安全性:由于 GET 方法将请求参数明文传输到 URL 中,因此数据安全性较低,容易被拦截和篡改。而 POST 方法将请求参数包含在请求体中,数据安全性较高。
缓存机制:由于 GET 方法具有幂等性,即多次发送相同请求得到的结果相同,因此浏览器可以对 GET 请求进行缓存,以提高响应速度。而 POST 方法没有幂等性,在大多数情况下不能被缓存。
参数长度限制:由于 URL 长度的限制,GET 方法的请求参数长度通常较小,一般不能超过2048个字符。而 POST 方法则没有长度限制,可以传输任意大小的数据。
安全问题:由于 GET 方法使用明文传输,因此容易受到 XSS(跨站脚本)攻击、CSRF(跨站请求伪造)攻击等安全问题的影响。而 POST 方法相对安全,但也需要防范这些攻击。
总之,GET 和 POST 有各自的优缺点,应根据具体情况选择合适的方法。一般来说,GET 方法适用于请求数据,而 POST 方法适用于提交数据或修改数据。在数据安全性要求较高的情况下,建议使用 POST 方法。
7. cookie与session的区别
Cookie 和 Session 都是用于在 Web 应用程序中跟踪用户状态的机制,它们之间的联系和区别如下:
存储位置:Cookie 把数据保存在客户端浏览器中,而 Session 把数据保存在服务器端内存或硬盘等永久性存储介质中。
传输方式:Cookie 通过 HTTP 协议在客户端和服务器之间传输,而 Session 是通过在客户端存储一个 Session ID,在客户端和服务器之间传递该 Session ID 的方式来实现数据共享的。
数据安全性:因为 Cookie 存储在客户端,所以可以被其他人恶意获取或篡改;而 Session 存储在服务器端,相对更加安全。
存储大小:Cookie 的大小有限制,一般不超过 4KB;而 Session 可以存储更多数据,但由于存在于服务器内存中,因此需要考虑服务器性能和资源消耗问题。
处理方式:Cookie 的处理方式比较简单,只需要读取和设置 Cookie 值即可;而 Session 的处理需要借助 Session ID,通过该 ID 找到对应的 Session 对象,并进行读取和修改。
生命周期:Cookie 可以设置过期时间,可以被保存到客户端的硬盘中,也可以在浏览器关闭时自动删除;而 Session 的生命周期通常是和用户会话绑定,当用户关闭浏览器或长时间不活动时,Session 会被销毁。
用户体验:使用 Cookie 可以记录用户的偏好设置,提高用户体验;而使用 Session 可以实现登录状态保持、用户信息共享等功能,也有利于提高用户体验。
总的来说,Cookie 和 Session 都有自身的优缺点和适用场景。在实际应用中,需要根据具体需求和安全考虑来选择合适的机制来实现对用户状态的跟踪和管理。
8. JVM内存区域划分
Java虚拟机内存区域可以分为以下五个部分:
程序计数器(Program Counter Register):是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的多线程环境中,程序计数器用于记录当前线程正在执行的字节码指令地址,以便线程恢复执行。
Java虚拟机栈(JVM Stack):每个Java方法在执行的同时都会伴随着一个栈帧(Stack Frame),栈帧保存了该方法的局部变量表、操作数栈、动态链接、方法出口等信息。Java虚拟机栈描述的是Java方法执行的内存模型。
本地方法栈(Native Method Stack):与Java虚拟机栈类似,但是为虚拟机使用到的Native方法服务。
Java堆(Java Heap):Java堆是Java虚拟机所管理的内存中最大的一块,被所有线程共享。Java堆是垃圾收集器管理的主要区域,也被称作垃圾收集堆。JVM堆主要用于存储Java程序中创建的对象。具体来说,它包含了如下几种类型的数据:
- 对象实例:Java程序中所有通过 new 关键字创建的对象都会被分配到堆内存中。
- 数组对象: Java数组也是一种对象,所以它们同样被分配到堆内存中。
- 类型类型对象:每个类型在 JVM 中都有一个对应的 Class 对象,用来描述这个类型的信息,比如字段、方法等等。这些 Class 对象也被存储在 JVM 堆中。
- 字符串常量池:字符串常量池是特殊的一块内存空间,用来缓存字符串常量。如果一个字符串常量已经存在于字符串常量池中,那么新创建的字符串对象就可以直接引用这个常量,而不需要再次创建一个新的对象。
方法区(Method Area/Metaspace):方法区是被各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码等数据。
9. 程序运行时候内存不足,会出现什么状况
- 抛出OutOfMemoryError异常,当JVM无法分配所需的内存时,就会抛出此异常。
- 程序运行缓慢或暂停,当没有足够的可用内存,就会导致操作系统将内存页写入磁盘交换区(swap space),从而使程序运行变得缓慢或暂停。
- 内存泄露:内存泄漏是指由于编程错误而导致无法释放不再使用的内存块。随着时间的推移,内存泄漏会导致应用程序消耗更多的内存,最终导致OutOfMemoryError异常。
- 数据丢失或损坏:如果程序在运行过程中发生OutOfMemoryError异常,可能会导致正在处理的数据丢失或损坏,从而导致程序崩溃或产生其他错误。
10. 显式调用GC会立即执行吗
显式调用System.gc()方法可以建议垃圾收集器(Garbage Collector)执行垃圾回收操作。但是,这并不保证垃圾回收会立即执行。
实际上,垃圾回收的具体实现取决于JVM的厂商和版本等因素。JVM可能会根据当前内存使用情况、可用资源以及其他因素来决定何时执行垃圾回收。
另外,显式调用System.gc()方法也不能保证完全清除所有未使用的对象。一些对象可能仍然保留在内存中,而且它们可能占用大量的内存空间。
因此,虽然可以使用System.gc()方法建议JVM执行垃圾回收,但不应该依赖它来确保在任何情况下都能立即释放内存。更好的做法是编写高效的代码,并对程序进行适当的内存管理,以最大程度地减少内存泄漏和内存浪费等问题。
11. 事务ACID特性
11.1 一致性
数据库的一致性是指在任何时间点,数据库中的数据都应该符合定义的规则和约束条件,以保持数据的正确性和有效性。换句话说,如果一个事务不遵循预定义的规则或约束条件,那么这个事务将会被回滚,以确保数据库的一致性。
11.2 持久性
事务持久性是指在事务提交后,数据库中的更改应该永久保存在存储介质中,并且即使发生系统故障或崩溃,这些更改也应该仍然存在。这是数据库事务的一个重要特性,它确保了数据库的可靠性和数据的完整性。
实现事务的持久性,DBMS通常使用日志记录和缓冲区技术。具体来说,当事务进行更新操作时,DBMS会将这些更改写入缓冲区中,并同时创建一个新的日志记录。如果事务成功提交,DBMS将把缓冲区中的更改写入磁盘,并将相应的日志记录标记为已提交
11.3 原子性
事务原子性是指一个事务中的所有操作要么全部成功完成,要么全部失败回滚。也就是说,事务的执行被视为一系列不可分割的操作,如果其中任何一个操作失败,则整个事务都将自动回滚到事务开始前的状态。
当一个事务开始执行时,DBMS会创建一个新的日志记录,并将所有执行的操作写入该日志。如果任何操作导致事务失败或中止,DBMS将使用日志来回滚事务并恢复数据库到之前的状态。在事务成功完成之后,这些日志记录将被标记为已提交,并且相应的更改将永久保存在数据库中。
比如一个银行转账操作需要从一个账户中提取一定金额,然后将此金额存入另一个账户。如果该操作包含两个单独的查询和两个单独的更新操作,则这些操作必须在同一个事务中执行。如果某一个操作失败,整个事务将回滚,并且不会对数据库造成任何影响。
11.4 隔离性
如下,为事务的几种隔离级别
读未提交(Read Uncommitted):最低的隔离级别,允许一个事务读取另一个事务还未提交的数据。这种隔离级别会导致脏读问题,即一个事务读取到了另一个事务还未提交的数据。
读已提交(Read Committed):允许一个事务只能读取已经提交的数据。这种隔离级别可以避免脏读问题,但可能会产生不可重复读和幻读问题。
可重复读(Repeatable Read):保证在同一个事务中多次读取同一数据时,其结果是一致的。在这个隔离级别下,事务在读取数据时会对其加锁,直到事务结束才会释放锁。这种隔离级别可以避免脏读和不可重复读问题,但仍然可能会产生幻读问题。
串行化(Serializable):最高的隔离级别,强制事务串行执行。在这个隔离级别下,所有事务都会被串行化执行,完全避免了并发控制问题,但同时也会带来很高的性能开销。
12. Linux常用指令
ls:列出目录下的文件和子目录。
cd:切换当前工作目录。
mkdir:创建一个新的目录。
rm:删除一个文件或目录。
cp:复制一个文件或目录。
-
cp file1 file2:将file1复制到file2。
-
cp -r dir1 dir2:将dir1目录及其内容递归地复制到dir2。
-
cp -i file1 dir1:将file1复制到dir1,如果dir1目录下已存在同名文件,则提示用户选择是否覆盖。
-
cp -a dir1 dir2:将dir1目录及其内容递归地复制到dir2,并保留所有文件属性(包括权限、时间戳等)。
-
cp -v file1 dir1:将file1复制到dir1,并显示每个成功复制的文件名。
mv:移动一个文件或目录,或者更改它的名称。
相当于剪切
mv file1 file2:将file1重命名为file2。
mv file1 dir1:将file1移动到dir1目录下,同时保留原始文件名。
mv -i file1 dir1:将file1移动到dir1目录下,如果dir1目录下已存在同名文件,则提示用户选择是否覆盖。
mv dir1 dir2:将dir1目录重命名为dir2。
mv -v file1 dir1:将file1移动到dir1目录下,并显示每个成功移动的文件名。
cat:连接文件并打印到标准输出设备上。
grep:在文件中查找指定的字符串。
在文件中查找指定字符串
在指定目录及其子目录下,找寻指定字符串
find:在文件系统中查找文件。
chmod:修改文件或目录的权限。
使用格式为
chmod [选项] 模式 文件名
模式由三个数字组成,分别表示所有者权限,群组权限,及其他用户权限。
数字 | 描述 |
---|---|
0 | 没有权限 |
1 | 执行权限 |
2 | 写权限 |
3 | 写和执行权限 |
4 | 读权限 |
5 | 读和执行权限 |
6 | 读和写权限 |
7 | 读、写和执行权限 |
如下图,修改X1.txt的访问权限。
chown:修改文件或目录的所有者。
ps:列出系统中运行的进程。
ps aux
top:实时显示系统中进程的资源占用情况。
如下图,直接输入top即可
ping:测试与另一台计算机之间的网络连接。
ssh:远程登录到另一台计算机。
scp:在本地和远程计算机之间复制文件。
tar:将多个文件和目录打包成单个文件,可以进行压缩。
将多个文件归档
tar -cf 归档文件名 文件名
在已有归档里添加新文件
tar -rf 归档文件名 添加文件名
查看归档文件中的文件列表
tar -tf 归档文件名
zip: 压缩文件或目录
zip zipfile.zip file1.txt file2.txt directory1/
unzip:解压缩zip文件。
df:显示磁盘空间使用情况。
du:显示目录或文件的大小。
tail: 查看日志
less: 分页查看日志或搜索日志
less是一个Linux中非常有用的命令,它可以让用户在终端中查看文件内容,支持向前/向后翻页、跳转、搜索等操作。下面介绍一些less的常见使用方法:
查看文件:less filename
这个命令会在终端中打印出filename文件的内容,并且允许你向上/向下翻页。
向前/向后翻页:空格键(向前翻页)和b键(向后翻页)
按下空格键或b键可以向前/向后翻一页。
跳转到文件开始或结束处:g键或G键
按下g键将跳转到文件的开始处,按下G键将跳转到文件的结尾处。
跳转到特定行:输入行号+回车键
在less中输入一个数字并按下回车键,将跳转到该行。
搜索文本:输入"/" + 匹配模式 + 回车键
在less中输入"/"加上想要搜索的模式,并按下回车键将进行文本搜索。
退出less:q键
在less中按下q键可以直接退出该程序。
这些是less的一些常用命令,其他的命令可以通过输入"h"获取帮助信息来学习。
13. 内存泄漏与内存溢出
13.1 内存泄漏
内存泄漏是指程序中已经分配的内存空间,由于某些原因没有被释放而导致的内存浪费。以下是一些可能导致内存泄漏的原因:
程序员忘记了手动释放 Heap 内存。在 C++ 和类似语言中,程序员需要手动管理动态分配的内存;如果他们忘记了释放该内存,就会导致内存泄漏。
对象之间存在循环引用。例如,当两个对象相互持有对方的引用时,它们之间就形成了一个循环引用。这种情况下,即使代码不再使用这些对象,它们仍然占用内存空间。
文件描述符未正确关闭。在某些编程语言中,文件描述符或其他类似资源也应该释放以便让操作系统回收相关内存。
未及时释放线程栈空间。在线程中分配的内存会保留在堆栈中,如果没有通过正确的线程退出方式释放内存,就会导致内存泄漏。
递归调用过深。在递归函数中,每次函数调用都会在堆栈中分配一段内存空间,如果递归深度太大,就会导致堆栈溢出和内存泄漏。
指针操作错误。指针操作错误,比如使用已释放的内存、指针越界等,都可能导致内存泄漏。
以上仅是一些常见的原因,实际上还有很多其他的原因也可能导致内存泄漏。
13.2 内存溢出
内存溢出是指程序在申请内存时,没有足够的空间分配给该程序使用,导致程序崩溃或异常的现象。以下是一些可能引起内存溢出的原因:
内存泄漏。当程序不释放已经分配的内存空间时,会导致系统中的可用内存减少,最终导致内存溢出。
堆栈溢出。在递归函数或者大量局部变量的情况下,堆栈可能被占满,从而导致堆栈溢出。
内存碎片。当程序申请内存后,多次进行内存分配和释放操作,就会产生内存碎片,导致程序无法找到足够大小的连续内存块。
数据结构设计不合理。如果程序设计了一个大的、复杂的数据结构,该结构可能需要大量的内存来保存,从而导致内存不足。
系统资源不足。当系统同时运行许多应用程序时,可能会导致可用内存不足,从而导致内存溢出。此外,在虚拟化环境或云计算等场景中,如果为应用程序分配的物理内存不足,则也可能导致内存溢出。
文件描述符管理不当。在某些编程语言中,文件描述符或其他类似资源也会占用内存,如果没有正确地管理这些资源,就可能导致内存溢出。
以上是一些常见的引起内存溢出的原因,实际上还有很多其他的原因也可能导致内存溢出。程序员需要注意对内存进行合理的管理和利用,以保证程序能够正常运行并避免内存泄漏和溢出等问题。
14. Mysql聚合查询
MySQL聚合查询是指对表中的数据进行聚合操作,如求和、计数、平均值、最大值、最小值等。常用的聚合函数包括:
COUNT():统计某列或所有列非空行的数量。
例如:SELECT COUNT(*) FROM table_name;
SUM():求某列的总和。
例如:SELECT SUM(column_name) FROM table_name;
AVG():求某列的平均值。
例如:SELECT AVG(column_name) FROM table_name;
MAX():求某列的最大值。
例如:SELECT MAX(column_name) FROM table_name;
MIN():求某列的最小值。
例如:SELECT MIN(column_name) FROM table_name;
聚合查询通常需要在SELECT语句中使用GROUP BY子句,以便按照指定的列或表达式对结果进行分组。例如:
SELECT column_name1, column_name2, COUNT(*)
FROM table_name
WHERE condition
GROUP BY column_name1, column_name2;
15. Mysql查询日志
MySQL的查询日志可以记录所有被执行的SQL语句,可以用于排除问题、优化性能或安全审计等方面。下面是一些常见的查询日志相关操作:
查看查询日志是否开启
在MySQL命令行中输入以下命令:
show variables like ‘%general%’;
如果结果中general_log和general_log_file的值为ON和具体的文件路径,则表示查询日志已经开启。
开启查询日志
如果查询日志未开启,可以通过以下方式开启:
SET GLOBAL general_log = ‘ON’;
SET GLOBAL general_log_file = ‘/var/log/mysql/query.log’; – 设置日志文件路径,可根据实际情况修改
注意:开启查询日志会产生大量的日志文件,因此应该在必要时才开启,并及时停止。
查看查询日志内容
可以使用less或tail等命令查看日志文件的内容,例如:
less /var/log/mysql/query.log
tail -f /var/log/mysql/query.log – 实时显示日志内容
关闭查询日志
可以通过以下方式关闭查询日志:
SET GLOBAL general_log = ‘OFF’;
需要注意的是,关闭查询日志后,之前产生的日志也不会被删除,因此需要及时备份和清理。