计算机基础知识


数据结构

哈希表

详解哈希表

哈希表的大小为何是素数

环境变量

环境变量是系统变量当中的一种,就是PATH。Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。

说白了,把可执行程序的路径放到环境变量里面,那么以后在任意的路径下就可以直接使用这个可执行程序,而不用输入绝对路径,方便。

1.在Windows中,是由可视化的窗口模式展现出来的

2.linux中,在 /etc/profile文件中设置
可以直接用vim进入文件进行设置,也可以用下面的语句

echo "export PATH=${PATH}:/usr/local/go/bon" >> /etc/profile

最好还是用vim进行修改,用echo输入到为你文件中,会出现冗余,直接添加比较好。用冒号分隔。

修改好以后,需要更新环境变量

source /etc/profile

计组+操作系统

cpu工作流程

CPU的根本任务就是执行指令,对计算机来说最终都是一串由“0”和“1”组成的序列。CPU从逻辑上可以划分成3个模块,分别是控制单元、运算单元和存储单元,这三部分由CPU内部总线连接起来。如下所示:

  1. 控制单元:控制单元是整个CPU的指挥控制中心,由程序计数器PC(Program Counter), 指令寄存器IR(Instruction Register)、指令译码器ID(Instruction Decoder)和操作控制器OC(Operation Controller)等,对协调整个电脑有序工作极为重要。它根据用户预先编好的程序,依次从存储器中取出各条指令,放在指令寄存器IR中,通过指令译码(分析)确定应该进行什么操作,然后通过操作控制器OC,按确定的时序,向相应的部件发出微操作控制信号。操作控制器OC中主要包括节拍脉冲发生器、控制矩阵、时钟脉冲发生器、复位电路和启停电路等控制逻辑。

  2. 运算单元:是运算器的核心。可以执行算术运算(包括加减乘数等基本运算及其附加运算)和逻辑运算(包括移位、逻辑测试或两个值比较)。相对控制单元而言,运算器接受控制单元的命令而进行动作,即运算单元所进行的全部操作都是由控制单元发出的控制信号来指挥的,所以它是执行部件。

  3. 存储单元:包括CPU片内缓存和寄存器组,是CPU中暂时存放数据的地方,里面保存着那些等待处理的数据,或已经处理过的数据,CPU访问寄存器所用的时间要比访问内存的时间短。采用寄存器,可以减少CPU访问内存的次数,从而提高了CPU的工作速度。但因为受到芯片面积和集成度所限,寄存器组的容量不可能很大。寄存器组可分为专用寄存器和通用寄存器。专用寄存器的作用是固定的,分别寄存相应的数据。而通用寄存器用途广泛并可由程序员规定其用途,通用寄存器的数目因微处理器而异。这个是我们以后要介绍这个重点,这里先提一下。

CPU的运行原理(简洁版):

  1. 取指令:CPU的控制器从内存读取一条指令并放入指令寄存器。指令的格式一般是这个样子滴:

  2. 指令译码:指令寄存器中的指令经过译码,决定该指令应进行何种操作(就是指令里的操作码)、操作数在哪里(操作数的地址)。

  3. 执行指令,分两个阶段“取操作数”和“进行运算”。

  4. 修改指令计数器,决定下一条指令的地址。

微机设计

其中:

  • 时钟 (clock) 对 CPU 内部操作与系统其他组件进行同步。
  • 控制单元 (control unit, CU) 协调参与机器指令执行的步骤序列。
  • 算术逻辑单元 (arithmetic logic unit, ALU) 执行算术运算,如加法和减法,以及逻辑运算,如 AND(与)、OR(或)和 NOT(非)。

CPU 通过主板上 CPU 插座的引脚与计算机其他部分相连。大部分引脚连接的是数据总线、控制总线和地址总线。

内存存储单元 (memory storage unit) 用于在程序运行时保存指令与数据。它接受来自 CPU 的数据请求,将数据从随机存储器 (RAM) 传输到 CPU,并从 CPU 传输到内存。

由于所有的数据处理都在 CPU 内进行,因此保存在内存中的程序在执行前需要被复制到 CPU 中。程序指令在复制到 CPU 时,可以一次复制一条,也可以一次复制多条。

总线 (bus) 是一组并行线,用于将数据从计算机一个部分传送到另一个部分。一个计算机系统通常包含四类总线:数据类、I/O 类、控制类和地址类。

数据总线 (data bus) 在 CPU 和内存之间传输指令和数据。I/O 总线在 CPU 和系统输入 / 输出设备之间传输数据。控制总线 (control bus) 用二进制信号对所有连接在系统总线上设备的行为进行同步。当前执行指令在 CPU 和内存之间传输数据时,地址总线 (address bus) 用于保持指令和数据的地址。

时钟与 CPU 和系统总线相关的每一个操作都是由一个恒定速率的内部时钟脉冲来进行同步。机器指令的基本时间单位是机器周期 (machine cycle) 或时钟周期 (clock cycle)。

时钟周期持续时间用时钟速度的倒数来计算,而时钟速度则用每秒振荡数来衡量。例如,一个每秒振荡 10 亿次 (1GHz) 的时钟,其时钟周期为 10 亿分之 1 秒 (1 纳秒 )。(CPU主频)

执行一条机器指令最少需要 1 个时钟周期,有几个需要的时钟则超过了 50 个(比如 8088 处理器中的乘法指令)。由于在 CPU、系统总线和内存电路之间存在速度差异,因此,需要访问内存的指令常常需要空时钟周期,也被称为等待状态 (wait states)。

指令执行周期

原文链接
一条机器指令不会神奇地一下就执行完成。CPU 在执行一条机器指令时,需要经过一系列预先定义好的步骤,这些步骤被称为指令执行周期 (instruction execution cycle)。

假设现在指令指针寄存器中已经有了想要执行指令的地址,下面就是执行步骤:

1) CPU 从被称为指令队列 (instruction queue) 的内存区域取得指令,之后立即增加指令指针的值。

2) CPU 对指令的二进制位模式进行译码。这种位模式可能会表示该指令有操作数(输入值)。

3) 如果有操作数,CPU 就从寄存器和内存中取得操作数。有时,这步还包括了地址计算。

4) 使用步骤 3 得到的操作数,CPU 执行该指令。同时更新部分状态标志位,如零标志 (Zero)、进位标志 (Carry) 和溢出标志 (Overflow)。

5) 如果输出操作数也是该指令的一部分,则 CPU 还需要存放其执行结果。

通常将上述听起来很复杂的过程简化为三个步骤:取指 (Fetch)、译码 (Decode) 和执行 (Execute)。操作数 (operand) 是指操作过程中输入或输出的值。例如,表达式 Z=X+Y 有两个输入操作数 (X 和 Y),—个输岀操作数 (Z)。

下图是一个典型 CPU 中的数据流框图。该图表现了在指令执行周期中相互交互部件之间的关系。在从内存读取程序指令之前,将其地址放到地址总线上。然后,内存控制器将所需代码送到数据总线上,存入代码高速缓存 (code cache)。指令指针的值决定下一条将要执行的指令。指令由指令译码器分析,并产生相应的数值信号送往控制单元,其协调 ALU 和浮点单元。虽然图中没有画出控制总线,但是其上传输的信号用系统时钟协调不同 CPU 部件之间的数据传输。

缓存

原文链接
作为一个常见现象,计算机从内存读取数据比从内部寄存器读取速度要慢很多。这是因为从内存读取一个值,需要经过下述步骤:

将想要读取的值的地址放到地址总线上。
设置处理器 RD(读取)引脚(改变 RD 的值)。
等待一个时钟周期给存储器芯片进行响应。
将数据从数据总线复制到目标操作数。
上述每一步常常只需要一个时钟周期,时钟周期是基于处理器内固定速率时钟节拍的一种时间测量方法。计算机的 CPU 通常是用其时钟速率来描述。例如,速率为 1.2GHz 意味着时钟节拍或振荡为每秒 12 亿次。

因此,考虑到每个时钟周期仅为 1/1 200 000 000 秒,4 个时钟周期也是非常快的。但是,与 CPU 寄存器相比,这个速度还是慢了,因为访问寄存器一般只需要 1 个时钟周期。

CPU和主存之间直接数据传输的方式转变成CPU和cache之间直接数据传输。cache负责和主存之间数据传输。

加载并执行程序

在程序执行之前,需要用一种工具程序将其加载到内存,这种工具程序称为程序加载器 (program loader)。加载后,操作系统必须将 CPU 指向程序的入口,即程序开始执行的地址。以下步骤是对这一过程的详细分解。

1) 操作系统(OS)在当前磁盘目录下搜索程序的文件名。如果找不到,则在预定目录列表(称为路径(path))下搜索文件名。当 OS 无法检索到文件名时,它会发出一个出错信息。

2) 如果程序文件被找到,OS 就访问磁盘目录中的程序文件基本信息,包括文件大小,及其在磁盘驱动器上的物理位置。

3) OS 确定内存中下一个可使用的位置,将程序文件加载到内存。为该程序分配内存块,并将程序大小和位置信息加入表中(有时称为描述符表(descriptor table))。另外,OS 可能调整程序内指针的值,使得它们包括程序数据地址。

4) OS 开始执行程序的第一条机器指令(程序入口)。当程序开始执行后,就成为一个进程(process)。OS 为这个进程分配一个标识号(进程 ID),用于在执行期间对其进行追踪。

5) 进程自动运行。OS 的工作是追踪进程的执行,并响应系统资源的请求。这些资源包括内存、磁盘文件和输入输出设备等。

6) 进程结束后,就会从内存中移除。

不论使用哪个版本的 Microsoft Windows,按下 Ctrl-Alt-Delete 组合键,可以选择任务管理器(task manager)选项。在任务管理器窗口可以查看应用程序和进程列表。

应用程序列表中列出了当前正在运行的完整程序名称,比如,Windows 浏览器,或者 Microsoft Visual C++。如果选择进程列表,则会看见一长串进程名。其中的每个进程都是一个独立于其他进程的,并处于运行中的小程序。

可以连续追踪每个进程使用的 CPU 时间和内存容量。在某些情况下,选定一个进程名称后,按下 Delete 键就可以关闭该进程。

指令

原链接,详细内容见原文

  • 一条指令就是机器语言的一个语句,它是一组有意义的二进制代码。
  • 一台计算机的所有指令的集合构成该机的指令系统,也称为指令集。

指令的格式

从最基本的结构上来说:一条指令通常要包括操作码字段和地址码字段两部分:

操作码字段告诉用户做什么操作?
地址码告诉用户对谁操作?

寻址方式

原链接,详细内容见原文

指令寻址的方式包括两部分:

一种是指令的寻址
(是不是很晕?指令寻址怎么又包括指令寻址。hh因为这里的指令寻址指的是具体的操作码上发出的指令。是狭义上的指令寻址。)
另一种是数据的寻址(可以理解为地址码上操作数的地址寻址)

指令寻址方式

程序执行跳转指令,将程序计数器中的数据改为7。

  1. 顺序寻址
    从0开始执行,我们就需要在pc中写入地址0。执行完零号指令后,由于这是普通的取数指令,因此程序计数器自动+1,于是cpu开始执行指令1。
  1. 跳转寻址
    知道碰到跳转指令,也就是指令3,程序执行跳转指令,将程序计数器中的数据改为7。

数据寻址方式

计算机网络

cookie和session

cookie和seesion主要区别

星巴克开始优惠活动,每消费10杯咖啡,会免费赠送1杯。考虑到一个人一次性消费10杯咖啡几乎不可能,所以需要采取某种方式来记录顾客的消费数量。

1)分给顾客一张卡片,每消费一次记录一次;

2)发给顾客一张卡片,上面有卡号,顾客每消费一次,由店员在操作机上记录一次。

而方案一和二正是对应的客户端记录和服务端记录。与之相对应的正是cookie和session。 好了,我们进入正题。

什么是cookie

HTTP是一种无状态协议,服务器没有办法单单从网络连接上面知道访问者的身份,为了解决这个问题,就诞生了Cookie

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie

客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie。

cookie的弊端

cookie 可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果 Cookie 很多,这无形地增加了客户端与服务端的数据传输量,

session

Session 的出现正是为了解决这个问题。同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 是客户端第一次访问服务器的时候生成的, 而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 ID,客户端只要传回这个 ID 就行了,这个 ID 通常是 NANE 为JSESIONID 的一个 Cookie。

Session机制是一种服务端的机制,服务器使用一种类似散列表的结构来保存信息。

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端里的请求里是否已包含了一个session标识—sessionID,

如果已经包含一个sessionID,则说明以前已经为此客户端创建过session,服务器就按照sessionID把这个session检索出来使用

如果客户端请求不包含sessionID,则为此客户端创建一个session并且声称一个与此session相关联的sessionID,

sessionID的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串(服务器会自动创建),这个sessionID将被在本次响应中返回给客户端保存。

centOS7 桥接模式设置静态Ip的方法步骤

原文链接

前言

如果你虚拟机IP是自动获取的,难免会碰到IP经常变动,给xshell相关连接工具使用造成不便,那么怎么固定IP且正常访问外网地址呢?由于主机网络采用的是自动获取IP方式,所以每次重启机器可能导致IP地址的变更,不利于项目的部署和运行

静态ip就是虚拟机的ip 外界想要连你的虚拟机的ip

虚拟机选择桥接模式

注意虚拟机网卡要选择主机上网的网卡

虚拟机设置静态ip(关键步骤)

虚拟机的网卡名称是ens33

然后用vim编辑以下文件

/etc/sysconfig/network-scripts/ifcfg-xxx

上面的xxx就是虚拟机的网卡名称,不同的linux发行版名称可能不同。原因见原链接

需要修改的属性:

ONBOOT=YES #no换成yes
BOOTPROTO=static #dhcp换成static
添加:
IPADDR=192.168.230.129 #静态ip地址 与主机中IP的前三位一致,最后一位需要修改,不要跟主机ip一样导致发生冲突
GATEWAY=192.168.230.1 #默认网关 和物理主机一样就可以了
NETMASK=255.255.255.0 #子网掩码 和物理主机一样就可以了
DNS1=8.8.8.8      #DNS,写谷歌的地址就可以了。

具体解释:

TYPE=Ethernet    # 网卡类型:为以太网
PROXY_METHOD=none   # 代理方式:关闭状态
BROWSER_ONLY=no    # 只是浏览器:否
BOOTPROTO=dhcp    # 网卡的引导协议:DHCP[中文名称: 动态主机配置协议]
DEFROUTE=yes    # 默认路由:是, 不明白的可以百度关键词 `默认路由`
IPV4_FAILURE_FATAL=no  # 是不开启IPV4致命错误检测:否
IPV6INIT=yes    # IPV6是否自动初始化: 是[不会有任何影响, 现在还没用到IPV6]
IPV6_AUTOCONF=yes   # IPV6是否自动配置:是[不会有任何影响, 现在还没用到IPV6]
IPV6_DEFROUTE=yes   # IPV6是否可以为默认路由:是[不会有任何影响, 现在还没用到IPV6]
IPV6_FAILURE_FATAL=no  # 是不开启IPV6致命错误检测:否
IPV6_ADDR_GEN_MODE=stable-privacy   # IPV6地址生成模型:stable-privacy [这只一种生成IPV6的策略]
NAME=ens33     # 网卡物理设备名称
UUID=f47bde51-fa78-4f79-b68f-d5dd90cfc698 # 通用唯一识别码, 每一个网卡都会有, 不能重复, 否两台linux只有一台网卡可用
DEVICE=ens33     # 网卡设备名称, 必须和 `NAME` 值一样
ONBOOT=no      # 是否开机启动, 要想网卡开机就启动或通过 `systemctl restart network`控制网卡,必须设置为 `yes`

重启网络服务

#centos7

systemctl restart network 

测试

输入命令ping www.baidu.com(测试外网)

输入命令ping 192.168.2.153(宿主机ip)

注意:
如果无法ping通宿主机,很有可能是因为防火墙。
宿主机无法ping通虚拟机,也有可能是因为防火墙。

VMware三种网卡解析

原文链接

虚拟网卡名 网络属性 定义
VMnet0 物理网卡 Bridge桥接
Vmnet1 虚拟网卡 host-only仅主机
VMnet8 虚拟网卡 NAT

但是我们查看主机的网络链接,有时却看不见VMnet0

通过网络配置这里,能够看见使用那张网卡(这里是virtualbox,VMware也是差不多)

所以根据上面两张图的对比,本地网络连接中的以太网3就是桥接模式使用的网卡。

VM虚拟机-三种网络连接方式(桥接、NAT、仅主机模式)

原文链接

桥接

桥接,即架设了一条桥,让虚拟机成为一台真正的计算机,直接连入到实际网络中了。

因此,它使得虚拟机能被分配到一个网络中独立的IP,所有网络功能完全和在网络中的真实机器一样,它和主机连接在同一个交换机上(此交换机通过vmnet0模拟),处于同一个 LAN,它可以访问网内任何一台机器。

此模式下虚拟机:

  1. 可以与主机相互访问

  2. 可以与网络中其他主机相互访问

  3. 可以与其他虚拟机相互访问

所以,桥接模式下的虚拟机,你把它直接认为是真实计算机就行了。

默认情况下DHCP会自动为虚拟机配置网络,但如果你需要在桥接模式下,手动为虚拟系统配置IP地址时,配置的虚拟机的ip不能是已经被占用的地址,还要和宿主机器处于同一网段,不然会造成地址冲突,只有这样虚拟系统才能和宿主机器以及外网进行通信。


复制物理网络连接状态

一般在虚拟机设置为桥接时就能看见这个选项(无特殊要求默认不用勾选)

这个选项是只在移动设备上有用,比如在笔记本上使用VMware软件,最开始主机用有线连接的局域网,开启虚拟机(使用桥接),虚拟机系统获取的局域网地址为192.168.1.4。然后你把主机的有线拔掉,连接上同一局域网的wifi时,如果你选择了复制物理网络连接状态这个选项,那你的虚拟机系统的IP不会变化(还是192.168.1.4),如果你没有选择复制物理网络连接状态这个选项,那你的虚拟机系统的IP可能就会发生变化,比如变为192.168.1.5。

NAT

NAT,虚拟机访问网络的所有数据都是由主机提供的,虚拟机并不真实存在于网络中,主机与网络中的任何机器都不能查看和访问到虚拟机的存在。

虚拟机和主机之间通过VMnet8这个网卡来模拟路由器的作用,进行nat地址转换功能,负责将虚拟机发到 VMnet8 的包进行地址转换之后发到实际的网络上,再将实际网络上返回的包进行地址转换后通过 VMnet8 发送给虚拟机。

此模式下虚拟机:

   可以单向访问主机

   可以单向访问其他网络中主机

   不可以访问其他虚拟机

虚拟机可以访问主机能访问到的所有网络,但是对于主机以及主机网络上的其他机器,虚拟机又是不可见的,甚至主机也访问不到虚拟机。包括所有nat模式下的虚拟机之间相互都不能访问,虚拟机与虚拟机各自完全独立,相互间无法通过网络访问彼此。

仅主机

仅主机,虚拟机的与主机通过VMnet1连接,VMnet1不提供提供任何路由服务,因此虚拟机只能和宿主机进行通信,而不能连接到实际网络上。

其实就是NAT模式去除了nat地址转换功能

此模式下虚拟机:

   可以与主机互相访问

   不可以访问其他网络中主机

   不可以访问其他虚拟机

仅主机模式看着很简单,但是其实这是一种比较复杂的模式,其他模式可以实现的功能,在仅主机模式下,通过虚拟机及网卡的设置都可以被实现。所以该模式需要有比较扎实的网络基础知识

这种模式下,我们可以理解为虚拟机在主机中模拟出一张专供虚拟机使用的网卡VMnet1,所有虚拟机都是连接到该网卡上的,我们可以通过设置这张网卡来实现上网及其他很多功能,比如(网卡共享、网卡桥接等)。

正向代理和反向代理区别

原文链接

一 什么是代理

代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介。
刚开始的时候,代理多数是帮助内网client访问外网server用的
后来出现了反向代理,”反向”这个词在这儿的意思其实是指方向相反,即代理将来自外网客户端的请求转发到内网服务器,从外到内

二 正向代理

正向代理类似一个跳板机,代理访问外部资源

比如我们国内访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器,请求发到代理服,代理服务器能够访问谷歌,这样由代理去谷歌取到返回数据,再返回给我们,这样我们就能访问谷歌了

正向代理的用途:

  (1)访问原来无法访问的资源,如google

(2) 可以做缓存,加速访问资源

  (3)对客户端访问授权,上网进行认证

  (4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息   

三 反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器

反向代理的作用:
(1)保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网

(2)负载均衡,通过反向代理服务器来优化网站的负载

四 总结
正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端.
反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端

看图理解一:

看图理解二:

正向代理中,proxy和client同属一个LAN,对server透明;
反向代理中,proxy和server同属一个LAN,对client透明。
实际上proxy在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把后出现的那种代理方式叫成了反向代理

总结:
正向代理: 买票的黄牛

反向代理: 租房的代理

Nginx

原文链接
“Nginx 是一款轻量级的 HTTP 服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的 IO 性能,时常用于服务端的反向代理负载均衡。”
Nginx 是一款 http 服务器 (或叫web服务器)。它是由俄罗斯人 伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点开发的,并于2004年首次公开发布的。

web服务器:负责处理和响应用户请求,一般也称为http服务器,如 Apache、IIS、Nginx

应用服务器:存放和运行系统程序的服务器,负责处理程序中的业务逻辑,如 Tomcat、Weblogic、Jboss(现在大多数应用服务器也包含了web服务器的功能)

Nginx 是什么,总结一下就是这些:

  • 一种轻量级的web服务器
  • 设计思想是事件驱动的异步非阻塞处理(类node.js)
  • 占用内存少、启动速度快、并发能力强
  • 使用C语言开发
  • 扩展性好,第三方插件非常多
  • 在互联网项目中广泛应用

Nginx配置

安装/卸载

安装、卸载、启动自查找资料

修改配置
经常要用到的几个文件路径:

/usr/local/etc/nginx/nginx.conf (nginx配置文件路径)
/usr/local/var/www (nginx服务器默认的根目录)
/usr/local/Cellar/nginx/1.17.9 (nginx的安装路径)
/usr/local/var/log/nginx/error.log (nginx默认的日志路径)

nginx 默认配置文件简介:

## 首尾配置暂时忽略
server {  
        # 当nginx接到请求后,会匹配其配置中的service模块
        # 匹配方法就是将请求携带的host和port去跟配置中的server_name和listen相匹配
        listen       8080;        
        server_name  localhost; # 定义当前虚拟主机(站点)匹配请求的主机名

        location / {
            root   html; # Nginx默认值
            # 设定Nginx服务器返回的文档名
            index  index.html index.htm; # 先找根目录下的index.html,如果没有再找index.htm
        }
}

## 首尾配置暂时忽略

server{ } 其实是包含在 http{ } 内部的。每一个 server{ } 是一个虚拟主机(站点)。
上面代码块的意思是:当一个请求叫做localhost:8080请求nginx服务器时,该请求就会被匹配进该代码块的 server{ } 中执行。
当然 nginx 的配置非常多,用的时候可以根据文档进行配置。

英文文档:nginx.org/en/docs/
中文文档:www.nginx.cn/doc/

Nginx有哪些应用?
主要有4大应用(动静分离、正向代理、反向代理、负载均衡)

动静分离

如上图所示,动静分离其实就是 Nginx 服务器将接收到的请求分为动态请求和静态请求。
静态请求直接从 nginx 服务器所设定的根目录路径去取对应的资源,动态请求转发给真实的后台(前面所说的应用服务器,如图中的Tomcat)去处理。
这样做不仅能给应用服务器减轻压力,将后台api接口服务化,还能将前后端代码分开并行开发和部署。(传送门:nginx动静分离的好处

server {  
        listen       8080;        
        server_name  localhost;

        location / {
            root   html; # Nginx默认值
            index  index.html index.htm;
        }
        
        # 静态化配置,所有静态请求都转发给 nginx 处理,存放目录为 my-project
        location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
            root /usr/local/var/www/my-project; # 静态请求所代理到的根目录
        }
        
        # 动态请求匹配到path为'node'的就转发到8002端口处理
        location /node/ {  
            proxy_pass http://localhost:8002; # 充当服务代理
        }
}

访问静态资源 nginx 服务器会返回 my-project 里面的文件,如获取 index.html:

访问动态请求 nginx 服务器会将它从8002端口请求到的内容,原封不动的返回回去:


负载均衡

负载均衡是什么?
随着业务的不断增长和用户的不断增多,一台服务已经满足不了系统要求了。这个时候就出现了服务器 集群。
在服务器集群中,Nginx 可以将接收到的客户端请求“均匀地”(严格讲并不一定均匀,可以通过设置权重)分配到这个集群中所有的服务器上。这个就叫做负载均衡。
负载均衡的示意图如下:


负载均衡的作用

分摊服务器集群压力
保证客户端访问的稳定性

前面也提到了,负载均衡可以解决分摊服务器集群压力的问题。除此之外,Nginx还带有健康检查(服务器心跳检查)功能,会定期轮询向集群里的所有服务器发送健康检查请求,来检查集群中是否有服务器处于异常状态。
一旦发现某台服务器异常,那么在这以后代理进来的客户端请求都不会被发送到该服务器上(直健康检查发现该服务器已恢复正常),从而保证客户端访问的稳定性。

配置负载均衡

配置一个简单的负载均衡并不复杂,代码如下:

## 负载均衡:设置domain
upstream domain {
    server localhost:8000;
    server localhost:8001;
}
server {  
        listen       8080;        
        server_name  localhost;

        location / {
            # root   html; # Nginx默认值
            # index  index.html index.htm;
            
            proxy_pass http://domain; # 负载均衡配置,请求会被平均分配到8000和8001端口
            proxy_set_header Host $host:$server_port;
        }
}

8000和8001是我本地用 Node.js 起的两个服务,负载均衡成功后可以看到访问 localhost:8080 有时会访问到8000端口的页面,有时会访问到8001端口的页面。


能看到这个效果,就说明你配置的负载均衡策略生效了。
实际项目中的负载均衡远比这个案例要更加复杂,但是万变不离其宗,都是根据这个理想模型衍生出来的。
受集群单台服务器内存等资源的限制,负载均衡集群的服务器也不能无限增多。但因其良好的容错机制,负载均衡成为了实现高可用架构中必不可少的一环。

ping和ssh

ping 和 ssh 的连通性是相互独立的。如果你不能 ping 通一个 IP,不意味着你不能 ssh 到它;同样,如果你可以 ping 通一个 IP,也不意味着你可以 ssh 到它。

ping 和 ssh 使用的是不同的网络协议和端口。ping 使用的是 ICMP (Internet Control Message Protocol),而 ssh 使用的是 TCP 协议,默认端口为22。这意味着以下几种情况可能发生:

  1. ICMP 被阻止:在许多网络环境中,出于安全原因,ICMP 可能被防火墙或路由器屏蔽。这意味着你可能无法 ping 通一个 IP,但是还是可以通过 ssh 连接它。

  2. SSH 服务未运行:即使你可以 ping 通一个 IP,如果那台计算机上没有运行 SSH 服务,或者 SSH 服务配置不当,你仍然无法通过 ssh 连接它。

  3. SSH 端口被阻止:某些网络可能允许 ICMP,但阻止了 SSH 的默认端口(22)。这可能是因为网络管理员想要防止未经授权的远程访问。

  4. 使用非默认端口的 SSH:有时,为了安全或其他原因,SSH 可能配置为在非默认端口上运行。在这种情况下,即使默认的 SSH 端口被阻止,你仍然可能能够连接,只要你知道正确的端口号。

代理软件全局模型ip是否被修改

使用全局代理模式时,你的公共 IP 地址(从外部服务器或网站看到的 IP 地址)会被修改为代理服务器的 IP 地址。这是因为所有的网络请求都通过代理服务器进行,在到达最终的服务器或网站之前,首先到达代理服务器,然后由代理服务器转发。因此,对于外部服务器或网站,它们看到的请求似乎是来自代理服务器,而不是你的原始设备。

不过本地cmd查看ip是没有变化的

编译

不同的语言,不同的开发环境,编译出的东西不一定一样。

比如C/C++,windows下编出的是后缀为exe的可执行程序,双击就能直接运行。但如果在linux下编出的后缀是没有exe的,是一个可运行的二进制文件。原因是因为编译器不同,linux环境的编译器一般是gcc,windows下一般是MinGW等(用VSCODE跑C一般就是这个编译器)

不过java比较特殊,因为编出来的class文件是运行在JVM上,在os上一层,与操作系统没有直接联系。所以windows编出来的class,或者打包的tar/war可以直接扔到服务器(linux)上使用(B站黑马程序员的jenkins教程—(SpringCloud微服务部署)就是这样的)

Web

原文链接

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

Cookie机制

在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。

  而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。

  Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

什么是Cookie

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

  由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

  Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

Session机制

Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

什么是Session

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

  如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。   

cookie和session的区别

1、cookie数据存放在客户的浏览器上,session数据放在服务器上.

简单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,

客户端每次请求服务器的时候会发送 当前会话的session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。

由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的session_id,用特殊的浏览器伪造该用户的请求也是能够成功的。

session_id是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性。

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。

3、设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。

4、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。

5、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)

密码学

MD5加密

为什么要对密码MD5
密码明文传递或者直接写到数据库中,都有被偷看的风险

为什么要对密码做两次MD5
现在存在的一些反查md5的软件,做两次为了更好的保密

整体流程如何实现

1.整体加密流程

MD5(MD5(pass明文+固定salt)+随机salt)
第一次固定salt写死在前端
第二次加密采用随机的salt 并将每次生成的salt保存在数据库中

2.登录流程:

前端对用户输入的密码进行md5加密(固定的salt)
将加密后的密码传递到后端
后端使用用户id取出用户信息
后端对加密后的密码在进行md5加密(取出盐),然后与数据库中存储的密码进行对比,
ok登录成功,否则登录失败

3.注册流程

前端对用户输入的密码进行md5加密(固定的salt)
将加密后的密码传递到后端
后端随机生成一个salt,
使用生成salt对前端传过来的密码进行加密,然后将加密后密码和salt一起保存到db中

硬件知识

cpu核心数与线程数

原文链接

物理 cpu 数(physical cpu)

指主板上实际插入的 cpu 硬件个数(socket)。(但是这一概念经常被泛泛的说成是 cpu 数,这很容易导致与 core 数,processor 数等概念混淆,所以此处强调是物理 cpu 数)。

由于在主板上引入多个 cpu 插槽需要更复杂的硬件支持(连接不同插槽的 cpu 到内存和其他资源),通常只会在服务器上才这样做。在家用电脑中,一般主板上只会有一个 cpu 插槽。

核心(core)
一开始,每个物理 cpu 上只有一个核心(a single core),对操作系统而言,也就是同一时刻只能运行一个进程/线程。 为了提高性能,cpu 厂商开始在单个物理 cpu 上增加核心(实实在在的硬件存在),也就出现了双核心 cpu(dual-core cpu)以及多核心 cpu(multiple cores),这样一个双核心 cpu 就是同一时刻能够运行两个进程/线程的。

同时多线程技术(simultaneous multithreading)和 超线程技术(hyper–threading/HT)

本质一样,是为了提高单个 core 同一时刻能够执行的多线程数的技术(充分利用单个 core 的计算能力,尽量让其“一刻也不得闲”)。

simultaneous multithreading 缩写是 SMT,AMD 和其他 cpu 厂商的称呼。 hyper–threading 是 Intel 的称呼,可以认为 hyper–threading 是 SMT 的一种具体技术实现。

在类似技术下,产生了如下等价术语:

  • 虚拟 core: virtual core
  • 逻辑 processer: logical processor
  • 线程:thread

所以可以这样说:某款采用 SMT 技术的 4 核心 AMD cpu 提供了 8 线程同时执行的能力;某款采用 HT 技术的 2 核心 Intel cpu 提供了 4 线程同时执行的能力。

查看 cpu 信息
1.linux系统:

//法一
lscpu
CPU(s):                24
On-line CPU(s) list:   0-23
Thread(s) per core:    2
Core(s) per socket:    6
Socket(s):             2
//法二
cat /proc/cpuinfo
processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 60
model name  : Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz
stepping    : 3
microcode   : 0x22
cpu MHz     : 2393.631
cache size  : 6144 KB
physical id : 0
siblings    : 8
core id     : 0
cpu cores   : 4
...

其中有几个physical id,机器上就安装了几个物理CPU
cpu core记录了每个物理CPU,内部有几个物理核
siblings 代表每个物理CPU有多少个逻辑核

2.windows

多线程程序线程数
为了让我们的多线程程序更好的利用 cpu 资源,我们通常会先了解机器拥有的 processor 数,有若干手段可以获取这一信息:

  • cpuinfo 中查看:比如上文中的 cat /proc/cpuinfo | grep “processor” | wc -l
  • top 命令查看:cpu0,cpu1,…
  • 编程:比如在 Java 中用 Runtime.getRuntime().availableProcessors()

具体在多线程程序中设置线程数多大,对计算密集型的程序有的建议是 processor count + 1,有的建议是 processor count 的 1.5 倍,都是经验值,实测为准。

小结

  • 一台完整的计算机可能包含一到多个物理 cpu
  • 从单个物理 cpu (physical cpu)的角度看,其可能是单核心、双核心甚至多核心的
  • 从单个核心(core)的角度看,还有 SMT / HT 等技术让每个 core 对计算机操作系统而言用起来像多个物理 core 差不多

总的逻辑 cpu 数 = 物理 cpu 数 每颗物理 cpu 的核心数 每个核心的超线程数

cpu 线程与进程关系

原文链接

进程与线程

两种常见解释

1.进程和线程都是一个时间段的描述,是CPU工作时间段的描述。
2.进程是资源分配的最小单位,线程是CPU调度的最小单位

解释:

  1. CPU太快了,只有缓存存储器SRAM才能勉强追上它的速度,因此,一台机器上同时开30个程序,CPU可以把这30个程序变成顺序执行,每个只执行一小段,立马切换到下一个程序,再执行一小段,再切回来,人是无感知的。
  2. 一个程序准备开始执行的时候,相关资源必须要准备好,比如RAM地址,显卡,磁盘资源,这些准备好的东西打包一起就叫做上下文环境,然后CPU开始执行程序A,当然只执行了一小段时间,CPU就要切换到别的程序执行B,以保证几个程序的并发,切换之前要把A的上下问状态保存起来,下次切回来的时候接着用。
  3. 因此,进程就是包换上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文
  4. 进程的颗粒度太大,每次都要有上下的调入,保存,调出。线程就是进程的小分支,比如进程A有a,b,c三个线程,那么线程a,b,c就共享了进程A的上下文环境,成为了更细小的执行时间。

程序中的线程与CPU线程

看到这里会懵逼,假设一台8CPU32核的服务器,是不是跑的程序最多只能开32个线程呢?

答案当然是否定的,我们常说的进程中的线程,与CPU的线程,虽然都叫线程,但完全不是一回事。

程序的线程是软件概念,一个程序可以有多个线程,可以在一个CPU核上轮流并发执行。
CPU的线程是硬件的概念,就是核。八线程就是能让八个线程并行执行。

linux中的线程

暂时来不及总结,原文链接有。

概念

脚手架、框架、架构

  • 脚手架是指一个项目模板,通过这个模板可以生成固定模板的项目。
  • 框架一般是说应用框架,就是别人已经搭建好的成熟组件,我们只需要填代码就行,比如Spring
    Boot就是一个框架,我们要开发spring应用,就可以在这个框架里面按照它的规范去写代码。
  • 架构是指解决特定业务场景的技术解决方案。

文章作者: Jason Lin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source Jason Lin !
  目录