1.常量指针和指针常量
其实也很好理解,看const和*谁更在变量a的前面
如果是*,则说明是这个值不能修改;如果是const,就是这个指针不能修改(不能改变指向)
2.二维数组大小
3.大小端问题
大端:低位存高地址
小端:低位存低地址
%d是按每4个字节打印的
4.位段
首先要明白的是位段存的bit的最大值是这个类型的大小。首先unsigned是4字节,a+b=30,未满4字节但算4字节,又因为c+d超过了4字节,所以不能用位段,那就各占了4字节,然后对于char1字节进行对齐,一共就是16字节。
5.printf对齐打印
如果要左对齐就是-再加上要对齐多少位,右对齐就不用加-,多少位精度就是.x(x表示多少位)
6.关于容器和容器适配器
可能有时会搞混STL中的容器和容器适配器,我们以stack举例
容器(Containers)是C++ STL中的一种数据结构,用于存储和管理一组相关的对象。容器提供了许多有用的方法和算法,使得操作和管理对象集合更加方便和高效。
常见的容器类型包括:vector、list、deque、set、map、unordered_set、unordered_map等。
容器适配器(Container Adapters)是一种特殊的容器,它们基于已有的容器实现,并提供了不同的接口和功能。容器适配器用于修改或限制底层容器的操作,以满足特定的需求。
常见的容器适配器包括:
1.栈(stack):栈是一种后进先出(LIFO)的数据结构。栈适配器基于其他容器(如vector、deque)实现,仅提供了push、pop、top等操作。通过使用栈适配器,可以实现后进先出的数据处理。
2.队列(queue):队列是一种先进先出(FIFO)的数据结构。队列适配器基于其他容器(如list、deque)实现,仅提供了push、pop、front、back等操作。通过使用队列适配器,可以实现先进先出的数据处理。
3.优先队列(priority_queue):优先队列是一种按照元素优先级进行排序的容器。优先队列适配器基于vector实现,并使用堆(heap)数据结构来维护元素的优先级。它提供了push、pop、top等操作,并且自动根据元素的优先级对元素进行排序。
7.C++11中的auto
在C++11中,auto删除了声明自动类型变量的 功能,只能用来进行变量类型的推导。
8.strcpy和strcat
9.结构体内存对齐
首先会有一个对齐参数,4或者8.除了第一个成员一定在对齐的位置上后,对与后续的成员的对齐规则为:
有一个最小对齐数min,它是(对齐参数,下一个成员的类型的大小)中的最小值,先看该对齐位能不能被min整除,如果能就不再需要对齐,直接放入;如果不能,则需要补上一定的字节使其能够被min整除。最后都放完后还需要将所占有的字节数与该结构体中最大的成员变量的大小进行相除,同样不能被整除就补上字节。
注意:空类的大小是1字节,因为它要进行占位。
10.printf的%打印格式
%后接的字符需要符合规定,不然编译器会忽略%。
11.内联函数的复习
inline是一个建议性的关键字,在编译阶段会将内联函数展开,就是将函数调用直接使用函数体来进行替换。
12.缺省参数复习
需要注意的是:当这个位置的参数给了缺省值后,后面的参数都必须是缺省参数。
13.初始化列表与构造函数体
重点1.初始化列表是进行初始化。
重点2.构造函数体内进行的是赋值。
以下成员必须在初始化列表中初始化
1.const修饰的成员变量。(因为它初始化的时候必须赋值)
2.引用类型的成员变量。(引用类型初始化的时候也必须赋值,不能分开)
3.类类型对象,并且该类没有默认的构造函数。(因为必须靠我们自己来传参才能构造)
14.类定义复习
类定义有两种方式:
1.可以将声明和成员函数的定义全部放在类中。
2.类中可以只放变量和成员函数的声明,成员函数可以放在.cpp文件中定义。注意:成员函数前必须添加 类名::
15.友元函数
需要注意两点,1.友元函数不是类的成员函数, 友元函数中可以访问类的私有成员。
2.非静态的成员函数具有隐藏的this指针,受访问限定符约束,通过对象调用。
16.运算符重载和类型转换的场景
17.new的复习
18.编译器对连续的拷贝构造的优化
之前我们都知道,在函数内对象传值返回并且用来初始化一个新对象的时候,应该对调用两次拷贝构造,但是编译器会对连续的拷贝构造优化成一次。传参的时候如果有连续的拷贝构造也是一样
19.函数重载复习(友元函数重载)
需要注意的是,类成员函数的重载,形参数目实际上要少1,少了this这个参数。
但是友元函数重载必须要有一个类类型对象的参数。
20.引用传参的复习
引用的底层还是用指针来实现的,本质还是指针。所以引用并不是传值,而是地址。
21.类重写前置++和后置++
类中重写前置++括号()内没有参数,后置会有一个(int)
22.静态数据成员
静态数据成员是所有对象共有的,它只能在类中声明,在类外定义。
但是如果是const修饰的静态成员,就能在类中初始化
以上代码运行能通过·。
23.const修饰的变量
通过以上这道题可以看出,a这个变量被const进行了修饰,那么就已经是一个常量了。然后int*类型的指针p,因为a的地址也是const的类型的,所以先需要进行(int*)的强转。然后通过地址改变了a这块区域的值为20。但是编译器在编译代码时,在程序中看到对常量中的内容读取时,会直接使用常量中的内容替换该常量。 所以读取a的时候值还是10。其实主要是将a存入了寄存器当中,每次读取是从寄存器中读取的,我们可以加入volatile对变量a进行修饰,这样每次读取a的时候就总是从内存中读取了,那么下次读取a的值就会是相应的被修改的值(这里是11)
24.类的常成员函数
类的常成员函数就是在这个函数后加上const,这个const实际修饰的时this指针,表明在该成员函数内,不能修改非静态的成员变量。
25.C++不能被重载的运算符
不能被重载的运算符有 . .* :: ?:(三目运算符) sizeof 一共是五种。
26.编译器默认生成的成员函数
注意:析构函数没有参数
C++11中新增了两个,分别是默认的移动构造 和默认的移动赋值。
27.赋值运算符的重载
赋值运算符(=)的重载只能在类当中 ,类外不行
另外补充:流插入和流提取(就是<<和>>)要在类外实现,记得要友元。
28. 析构函数的注意事项
注意:
1.this指针不能被修改,它是经过const修饰的。
2.不能在析构函数中delete this,因为delete this意味着要销毁这个对象,那么编译器又会调用析构函数,形成逻辑死循环,无限递归,然后导致栈溢出而程序崩溃。
29.堆和栈
栈是可以动态开辟的,堆不可以静态开辟(指编译阶段就知道所需要的空间大小)。
C语言中,用alloca可以动态开辟栈空间,并且会在使用完后自动释放,无需手动释放。
30.C++输入一串带空格的字符串
我们可以用getline()函数。
int main()
{
string s;
getline(cin,s);
return 0;
}
31.关于虚函数
1.内联函数不可以是虚函数,虽然编译不会报错,那是因为inline是一个建议性的关键字,编译器会忽略inline属性。因为虚函数本质是要把这个函数的地址存放到虚函数表的,而内联函数在编译阶段会直接展开,不能放到虚函数表。
2.static函数也不能是虚函数,因为static函数没有this指针,虚函数的调用需要this指针来完成。
3.有纯虚函数的类也叫抽象类,抽象类不可以实例化。并且纯虚函数也可以有具体的实现。
4.抽象类的子类如果不重写这个虚函数,那么子类也是抽象类。
5.当该类有虚函数后,该类实例化的对象的第一个位置放的是这个虚函数表指针。
6.因为虚函数的调用需要在程序运行时期,通过虚表指针到虚表中查找再调用,因为虚函数相比静态成员函数和非类的成员函数相比,虚函数的效率较低。
32.杂项
1.首先p是一个指针,const修饰的是这个p指向的值,所以p可以修改,指向的值不可以被修改。
2.只要是指针,那么32位上是4字节,64位上是8字节 .
3.inline会检查函数参数,但是调用开销于宏差不多。
4.重载是静态绑定,虚函数是动态绑定。
32.this指针
一个类有多个对象,每当我们调用不同对象但是是相同的函数时,编译器怎么知道该返回哪个对象的值呢?
所以this指针的作用就是保证每个对象拥有自己的数据成员,但是共享处理这些数据的代码(也就是成员函数)。
33.const的对象的调用(常对象)
因为常对象里的成员绝对不可修改,所以在调用函数的时候只能调用const修饰的函数(常函数)。注意:这个const修饰的不是返回值,而是函数。
34.虚拟继承
虚拟继承是用来解决菱形继承的问题的,虚拟继承后,“爷爷类”A中的东西对于孙子来说只有一份,对于调用构造函数也是如此。
35.继承权限
关于继承的权限我们可以从两个角度入手 1.站在子类角度 :对于子类内部来说,可以直接访问父类的公有和保护成员,这个访问权限与继承方式无关。
2.站在对象的角度(类外):对象的访问只能访问公有成员,并且对于父类的成员,能否通过子类对象访问跟继承权限有关,可以理解为公有继承的话父类的成员的访问权限不变,保护继承则继承下来的父类成员最高权限降为保护级别,也就是通过对象访问不了。私有继承同理。
36.关于多态 注意事项
1.构造函数不能是虚函数,因为虚函数表是在父类构造函数时期初始化的。
2.在构造函数内部不能发生多态。
3.重点! 要明白多态的本质是替换在虚函数表中函数的地址,它是先找到父类的函数名,然后再去找函数的地址,注意,如果此时这个父类函数有缺省值的话,用的是父类的缺省值!
4.还可能会遇到一个奇葩场景,就是父类没有虚函数,而子类有虚函数,那么用父类的指针去指向子类对象时,虚表指针一般都是放在父类的第一个成员的,而因为父类没有虚函数,所以就没有这个空间来存放这个指针,所以当我们使用delete释放的时候就会造成空间的非法访问而程序崩溃。
5.在多继承时,一定要注意继承的顺序。还有析构函数一定要是虚函数,不能也有可能程序崩溃,或者资源释放不完全而内存泄漏。
37.杂项
注意:在stl中的库中的sort的排序是不稳定的,它底层也是用插入和快排混合的进行优化的。
38.一级容器
说起一级容器,我们需要先了解容器的分类
序列式容器:也就是线性结构,没有前后关系。
关联式容器:非线性结构,没有前后关系。
一级容器指的是它的数组类型不能是组合类型
但是注意:一般STL不大喜欢把容器分为一级容器啥的,一般就分为序列式容器和关联式容器。
补充:
在STL中有6大组件,如上。
适配器也就是说需要一个容器来给它进行改装适配,以此来达到需求的效果。
补充:
39.动态转换
如上这个动态转换的作用就是先检测这pa到底是不是C类型的指针,如果是就会转换成功,如果不是则返回一个空,以此来增加程序的安全性。
40.next_permutation
这是一个算法函数, permutation (置换)。它的作用可以用来做全排序或者计数全排序的个数。用法如下
在这个函数里面记得传容器的迭代器。
甚至我们还可以通过这种+数字的方式来进行控制,比如上述是控制前三排的排列组合。
41.进程地址空间
在CPU和物理内存之间进行地址转换时,MMU将地址从虚拟(逻辑)地址空间映射到物理地址空间
MMU是内存管理单元,一种负责处理CUPU的内存访问请求。
42.各大排序的稳定性
简单选择排序,希尔排序,堆排序,快排是不稳定的。
43.递归时局部变量和全局变量的选择
当path为int时,把path做为参数进行传递,当path为vector等数据结构时,把path作为全局变量进行操作。
理由如下
ps :力扣题号:494
44.进程和线程(小题)
进程比线程安全的原因是每个进程有独立的虚拟地址空间,有自己独有的数据,具有独立性,不会数据共享这个太过宽泛与片面。
45.多线程和多进程
异常针对的是整个进程,因此单个线程的崩溃会导致异常针对进程触发,最终退出整个进程。
------------------------------------------------------------------------------------------------------------------------
程序是静态的,不涉及进程,进程是程序运行时的实体,是一次程序的运行。
关于线程的查看和操作
主线程调用pthread_exit只是退出主线程,并不会导致进程的退出。
46.关于虚拟存储
虚拟存储本质上就是进程的虚拟地址空间。
装入程序时,只将程序的一部分装入内存,而其余部分留在外村,就可以启动程序执行。
如果采用连续分配的方式,会使相当一部分内存都处于暂时或“永久”的空闲状态,会造成内存资源很严重的浪费,也无法从逻辑上扩大内存容量。因此虚拟内存的实现只能建立在离散分配的内存管理的基础上,也就是非连续分配。
另外,虚拟存储器容量既不受外存容量限制,也不受内存容量限制,而是由CPU的寻址范围决定的。
47.线程共享和线程独有的资源
线程所共享的:
1.进程代码段。
2.进程的公共数据(利用这些数据,可以很容易实现线程间的通信)
3.进程打开的文件描述符。
4.信号的处理器。
5.进程的当前目录和进程用户ID和进程组ID。
线程独有的:
1.线程ID。
2.栈。
3. 错误返回码。
4.线程优先级。
5.errno。
48.关于线程的一些调度算法
先来先服务算法
1.是一种最简单的调度算法,既可以用于作业调度,也可用于进程调度。
2.有利于进行长作业,而不利于短作业。
3.有利于CPU繁忙型作业 ,而不利于I/O型繁忙作业。
高响应比优先算法
1.当等待时间相同时,短进程的优先权高。
2. 当运行时间相同时,作业的优先权又取决于等待时间,相当于相当于先到先服务。
3.长作业的优先级会随着等待时间增长而升高,因此长作业在等待一段时间后仍能得到调度。
时间片轮转算法
时间片轮转算法调度是一种最古老,最简单,最公平的且使用最广泛的算法。每个进程被分配一个时间片,即该进程允许执行的时间,如果超出了这个时间,进程还在运行,那么就会被强制从cpu上剥离下来,分配给另一个进程。如果进程在时间片结束前阻塞或结束,则cpu当即就进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片之后,就会被移动到队列末尾。
非抢占式短任务优先
就是短任务优先级高,长任务优先级低。在短任务非常多的情况下,对长任务非常不友好。
49.关于线程的活跃度失败
活跃度失败就是指进程或线程的等待时间过长,失败的主要情况包括:饥饿,活锁,死锁。
饥饿
就是某些线程对锁的竞争力太强,导致竞争力弱的线程因竞争不到锁而长期处于等待状态。
活锁
就是比如两个线程太过于谦让, 都想让对方先使用资源,你让我,我让你,最终两个线程都无法得到资源。
活锁不会被阻塞,而是不停地检测一个永远不可能为真的条件,出去进程本身有的资源外,活锁状态的进程会持续消耗宝贵的CPU时间。
死锁
比如两个线程互相等待对方释放资源,结果谁也得不到。
综上,饥饿,活锁,死锁都会导致线程的活跃度降低。
50.静态/动态优先权,强/非强占式概念
1.强占式:现进程在运行过程中,如果有重要或紧迫的进程到达(其状态必须为就绪状态),则现运行的进程将被迫放弃处理机,系统将处理机立刻分配给新到达的进程。
2.静态优先权:在进程创建时确定的,优先权在进程的整个运行期间保持不变。
3.动态优先权:在创建进程时所赋予的优先权,是可以随进程的推进,或随其等待的时间增加而改变(增加)的,以便获得更好的性能调度。
4.非强占式静态优先权法:优先权不会变,假如有一个最低优先权的线程在等待,那么等优先级高的进程执行完后就可以轮到该进程执行了。
5.强占式静态优先权法:说明高优先权的进程可以抢夺CPU的执行权。假如一个低优先权的进程正在执行,当一个高优先权的进程处于就绪状态时,那么CPU就会执行高优先权的进程,让低优先权的进程等待,假如一直有高优先权的进程处于就绪状态,那么低优先权的进程就会一直等待。
6.时间片轮转调度算法:执行的时间片完毕后,被执行的进程会被放到等待队列的队尾,等待循环。
7.非强占式动态优先权法:虽然是非强占式的,但是如果一个进程一直等待,那么它的优先权就会动态增长,从而获得CPU的执行权。
补充:
分时操作系统:是使一台计算机采用时间片轮转的方式同时为几个、几十个、甚至是几百个用户提供服务的操作系统。
在所有非抢占CPU调度算法中,平均响应时间最优的是短任务优先算法,但是它往往不能确定所有任务的运行时间。 先来先服务的算法平均响应时间最长,不适合用于分时操作系统。
51.信号量
当信号量大于0时,表示这个信号量是空闲的,允许进程(线程)使用这个信号量。
当信号量等于0时,表示这个信号量被别的进程使用了,现在不可以使用这个信号量,但是PCB等待队列也没有进程在等待。
当信号量小于0时,那么绝对值是多少就代表有多少个进程在等待。
52.操作系统的调度单位
如果系统只有用户态线程,则线程对操作系统是不可见的,操作系统只能调度进程。
如果操作系统中有内核态线程,则操作系统可以按线程进行调度。
另外,作业是指:多个进程,完成一个功能。
53.64位操作系统的64是什么意思?
64位的操作系统指的是CPU的字长,也就是说每次可以处理64位的二进制数据,内存地址是64位。与之相对的32位操作系统,每次可以处理32位的二进制数据,内存地址是32位。
54.杂项
malloc是库函数,不是系统调用,库函数封装了系统调用。
coredump是核心转储文件,ulimit -c 更改的是coredump文件大小的命令。
当进程异常终止时,如内存访问错误或接收到无法处理的信号时,操作系统会生成一个文件(通常称为“core”文件),记录该进程终止时的内存映像以及CPU的状态(如处理器寄存器等)。这个文件就是CoreDump。
Linux下文件的三个时间参数:
1.modification time 内容修改时间,是指文件内容发生变化而修改的时间。
2.change time 状态修改时间,是指文件的属性或权限发生改变而修改的时间。
3.access time 最后访问时间,是指文件被读取而更新的时间。
因此 如果用mv移动文件路径,只会更改文件的状态修改时间。
当内存访问越界时,线程会收到信号,进而进行信号处理,调用信号处理函数。
renice指令可以重新调整程序执行的优先权等级。
注意3进制求补码的取反的过程
主机名的本质就是域名。
HTTP是一种请求/响应的协议
55.程序中断
是指计算机执行现行程序的过程中,出现某些急需处理的异常情况和特殊请求,cpu暂时终止现行程序,而转而去执行可能会发生的更紧迫的事件处理,在处理完毕后,cpu将自动返回原来的程序继续执行。
比如当我们键盘输入时,进程需要中断进行IO读取,也就是会导致程序中断,转而进行IO。
56.umask掩码
umask能指定建立文件时预设的权限掩码。
文件的默认666,目录默认777。因此创建一个文件时,假设umask是244,那么该文件的权限就是666 - 244 = 422。也就是r-- -w- -w-。
57.Cache
设置Cache的目的是为了解决,CPU和主存之间的速度匹配问题。
设置Cache的理论基础,是程序访问的局部性原理。
Cache是介于中央处理器和主存储存器之间的高速小容量储存器,注意它不属于主存的一部分。
Cache的功能均由硬件实现,对程序员是透明的。
58.内存抖动
内存页面频繁更换,导致整个系统效率急剧下降,这个现象称为内存抖动。
抖动一般是内存算法分配不好,内存太小或者程序的算法不佳引起的页面频繁从内存调入调出。
内存抖动是指在一个较短时间内,系统中存在大量的对象被创建或者被回收的现象。这种现象通常发生在循环中频繁创建对象时,由于新对象需要占用内存空间,如果这种创建行为频繁发生,就会导致内存抖动。
59.OSI分层模型
注意各个层的传输单位还有协议,并且参考对应的TCP/IP模型
TCP/IP模型将OSI模型中的应用层,表示层和会话层都压缩成了一层---应用层,还有数据链路层和物理层都压缩成了一层---物理层。
60.关于报文丢失重传问题
如果主机A给主机B连续发送了两个TCP报文段,其序号分包是70和100,并且序号70的报文丢失了,主机B只接收到了序号100的报文,那么主机B返回给主机A的应答中的确认序号为70,注意:不是101也不是71。因为序号70的报文主机B没有接收到,因此返回确认序号70的报文是希望主机A重发序号70的报文,并且序号100的报文依然在主机B的接收缓冲区中,只有等主机A的序号70的报文来到才会一起被上层提取。
61.网络号
网络号 = ip地址 & 子网掩码
62.IP地址块
比如211.168.15.192/26。
注意这个/26,它的意思是该IP地址的主机号范围使用后6个比特位(32 - 26)。那么子网掩码就是
11111111.11111111.11111111.11000000。
它的IP地址注意最后一截就是 略... .11000000。(192/26~=7)
63.错排问题的公式
64.关于http
http的合法请求
http1.0,三种:post,get,head
http1.1,八种:post,get,head,options,put,delete,trace,connect
Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制,而这个限制是实实在在存在的,因此Http Get提交参数是有长度限制的,而HTTP POST方式提交参数没有长度限制。
HEAD请求是没有响应体的,仅传输状态行和标题部分。
DELETE方法用来删除指定的资源,它会删除URI给出的目标资源的所有当前内容。
PUT方法用于将数据发送到服务器以创建或更新资源,它可以用上传的内容替换目标资源中的所有当前内容。
POST请求主要用于向服务器提交表单数据,因此POST请求不会被缓存,POST请求不会保留在浏览器历史记录当中,POST请求不能被保存为书签,POST请求对数据长度没有要求。
GET请求主要用于从服务器获取实体资源,资源可被缓存,可以记录历史记录。
301 状态码表明目标资源被永久的移动到了一个新的 URI,任何未来对这个资源的引用都应该使用新的 URI。
302 状态码表示目标资源临时移动到了另一个 URI 上。由于重定向是临时发生的,所以客户端在之后的请求中还应该使用原本的 URI。
由于历史原因,用户代理可能会在重定向后的请求中把 POST 方法改为 GET方法。如果不想这样,应该使用 307(Temporary Redirect) 状态码
303 状态码表示服务器要将浏览器重定向到另一个资源。从语义上讲,重定向到的资源并不是你所请求的资源,而是对你所请求资源的一些描述。
比如303 常用于将 POST 请求重定向到 GET 请求,比如你上传了一份个人信息,服务器发回一个 303 响应,将你导向一个“上传成功”页面。
307 的定义实际上和 302 是一致的,唯一的区别在于,307 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上。
308 的定义实际上和 301 是一致的,唯一的区别在于,308 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上。
关于HTTP 报头
User-Agent: 声明用户的操作系统和浏览器版本信息。
Content-Type: 正文数据类型,用于告知对端正文的编码类型及处理方式。
在响应报文头部设置字符编码是在Content-Type中设置charset属性,大小写不敏感,比如Content-Type: charset=utf-8等同于Content-Type: charset=UTF-8
Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上。
location: 搭配3xx状态码使用, 实现重定向,告诉客户端接下来要去哪里访问。
65.关于Cookie
cookie是一种保存在客户端的小型文本文件,用于保存服务器通过Set-Cookie字段返回的数据,在下次请求服务器时通过Cookie字段将内容发送给服务器。是HTTP进行客户端状态维护的一种方式
而Set-Cookie以及Cookie字段可以包含有多条信息,也可以由多个Cookie及-Set-Cookie字段进行传输多条信息
并且cookie有生命周期,在超过生命周期后cookie将失效,对应的cookie文件将被删除。
HTTP的cookie是明文传送的,HTTPS是HTTP的加密传输,因此HTTPS的cooike是才密文传送的
Cookie的基础属性:
domain:可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
path:Cookie的使用路径。如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”。
httponly:如果cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性,但不是绝对防止了攻击
secure:该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。
expires:指定了coolie的生存期,默认情况下cookie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失,如果想让cookie存在一段时间,就要为expires属性设置为未来的一个过期日期。现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期
关于Cookie的安全机制,哪些设置可以提高安全性
1.指定cookie domain的子域名:
domain:可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
path:Cookie的使用路径。如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”。
2.httponly设置:
httponly:如果cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性,但不是绝对防止了攻击。
3.cookie secure设置,保证cookie在https层面传输:
secure:该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。
expires:指定了coolie的生存期,默认情况下cookie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失,如果想让cookie存在一段时间,就要为expires属性设置为未来的一个过期日期。现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期
总结:
- 对保存到cookie里面的敏感信息加密
- 设置指定的访问域名
- 设置HttpOnly为true
- 设置Secure为true
- 给Cookie设置有效期
- 给Cookies加个时间戳和IP戳,实际就是让Cookies在同个IP下多少时间内失效
cookie是一种保存在客户端的小型文本文件,用于保存服务器通过Set-Cookie字段返回的数据,在下次请求服务器时通过Cookie字段将内容发送给服务器。是HTTP进行客户端状态维护的一种方式
但是cookie存在一定的缺陷:比如有大小限制,以及cookie不断的传递客户端的隐私信息,存在一定的安全隐患(比如认为篡改),因此有了session管理
session服务器为了保存用户状态而创建的临时会话,或者说一个特殊的对象,保存在服务器中,将会话ID通过cookie进行传输即可,就算会话ID被获取利用,但是session中的数据并不会被恶意程序获取,这一点相对cookie来说就安全了一些,但是session也存在一些缺陷,需要建立专门的session集群服务器,并且占据大量的存储空间(要保存每个客户端信息)
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。
Session可以存放各种类别的数据,相比只能存储字符串的cookie,能给开发人员存储数据提供很大的便利。
一般session的有效期默认是30分钟。
如果浏览器禁用了cookie,session机制不会失效。
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
66.关于数据链路层
局域网体系结构中 数据链路层 被划分成 MAC 和 LLC 两个子层,
MAC子层的主要功能包括数据帧的封装/卸装,帧的寻址和识别,帧的接收与发送,链路的管理,帧的差错控制等
LLC 是在高级数据链路控制(HDLC:High-Level Data-Link Control)的基础上发展起来的。
一个广域网和一个局域网相连,且需要进行协议转换,需要的设备是 网关。
路由器属于网络层设备,IP协议工作在网络层,它是一种负责寻径的网络设备
网关(Gateway)又称网络连接器、协议转换器,是在多个网络之间提供数据转换服务的计算机系统数据转换服务
集线器属于物理层设备
NIC是物理网卡的结构,是数据链路层,数据链路层分为LLC和MAC子层。
MTU:最大传输单元(Maximum Transmission Unit,MTU)用来通知对方所能接受数据服务单元的最大尺寸,说明发送方能够接受的有效载荷大小,是链路层的数据单元大小限制
数据在不同的层次或者不同的场景有不同的叫法,
数据段是传输层的说法,数据报是网络层的说法,数据帧是数据链路层的说法
数据片指的是UDP报文因为过大在网络层进行分割成小报文的说法,叫做数据分片
67.关于局域网
局域网通常指的是网络覆盖范围在1000米以内的网络,地域范围较小,往往属于一个单位所有,由单位自建自管,具有多种类型。
局域网使用专门铺设的传输介质进行联网和数据通信,数据传输速率高,延迟时间短,误码率低。
一般家庭或企业的局域网布线都是使用普通网线(现在一般网线都是双绞线,当然也有其他的一些种类)
局域网按照传输介质使用的访问控制方法,可以分为以太网、FDDI网和令牌网,目前广泛使用的是以太网,它以集线器或交换机为中心构成。
路由器的主要功能是路由功能连接其他网络对外通信。我们生活中都是购买路由器组建一个局域网,但是路由器并非必须的设备。
中继器(RP repeater)是工作在物理层上的连接设备。适用于完全相同的两个网络的互连,主要功能是通过对数据信号的重新发送或者转发,来扩大网络传输的距离
结语
由于字数限制,错题笔记1先到这里,今后只会更新笔记中可能会出现的错误,或者是对相同问题的补充,^ - ^。