题目链接:https://leetcode-cn.com/problems/two-sum/

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

题目分析

使用哈希表解题,贼舒服。

Java题解

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> hashMap = new HashMap<>();
int i = 0;
for (int num : nums) {
if (hashMap.containsKey(target - num)) {
return new int[] {i, hashMap.get(target - num)};
}
hashMap.put(num, i++);
}
return new int[0];
}
}

一、函数的定义和使用

1、语法格式

格式一
格式二

2、如何调用函数

  • 直接使用函数名调用,可以将其想象成Shell的一条命令
  • 函数内部可以使用参数 $1、$2、$3......$n
  • 调用函数: function_name $1 $2

3、示例演示

  • 创建函数
1
2
3
4
Test()
{
echo "Hello Test"
}
  • 使用函数
1
Test

4、小脚本(nginx守护进程)

写一个nginx脚本,如果nginx服务宕掉,则该服务可以检测并且将进程重新启动;如果正常运行,则不作任何处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
#

this_pid=$$

while true
do
ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null

if [ $? -eq 0 ];then
echo "Nginx is running well"
sleep 3
else
systemctl start nginx
echo "Nginx is down,Start it...."
fi
done

二、向函数传递参数

1、Shell中传参

2、Shell中函数调用

3、小脚本

写一个脚本,该脚本可以实现计算器的功能,可以进行 +、-、*、/四种运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
#

function calcu
{
case $2 in
+)
echo "`expr $1 + $3`"
;;
-)
echo "`expr $1 - $3`"
;;
\*)
echo "`expr $1 \* $3`"
;;
/)
echo "`expr $1 / $3`"
;;
esac
}

calcu $1 $2 $3

三、函数的返回值

1、return

  • 使用return返回值,只能返回1-255的整数
  • 函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常返回0或1

2、echo

  • 返回任何字符串结果
  • 通常适用于返回数据,比如一个字符串或者列表值

3、小练习

获取系统中所有的用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
#

function get_users
{
users=`cat /etc/passwd | cut -d: -f1`
echo $users
}

user_list=`get_users`

index=1
for u in $user_list
do
echo "The $index user is : $u"
index=$(($index+1))
done

四、局部变量和全局变量

  • 不作任何声明,Shell中的变量都是全局变量
  • 大型脚本程序中应当慎用全局变量

1、局部变量的定义

定义变量时,使用 local关键字

函数内和外若存在同名变量,则函数内部变量会覆盖外部变量

2、小脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
#

var1="Hello world"

function test
{
local var2=87
}

test

echo $var1
echo $var2

五、函数库

  • 经常使用的重复代码封装成函数文件
  • 一般不是直接执行的,而是由其他脚本调用

1、小脚本

  • 函数库脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function add
{
echo "`expr $1 + $2`"
}

function reduce
{
echo "`expr $1 - $2`"
}

function multiple
{
echo "`expr $1 \* $2`"
}

function divide
{
echo "`expr $1 / $2`"
}

# x
function sys_load
{
echo "Memory Info"
echo
free -m
echo

echo "Disk Usage"
echo
df -h
echo
}
  • 调用函数脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
#

# 引入库文件
. /root/lesson/3.5/lib/base_function

add 12 23

reduce 90 30

multiple 12 12

divide 12 2

一、变量替换

示例:

1、定义变量

1
va_1="i love you, do you love me?"

2、打印看看

1
echo $va_1

显示如下字符串: i love you, do you love me?

3、进行字符替换

1
var1=${va_1#*ov}

var1如下所示: e you, do you love me?

二、字符串处理

1、获取字符串长度

2、获取子串在字符串中的索引位置

语法: expr index $string $substring

3、计算子串的长度

语法: expr match $string substr

4、抽取子串

三、小练习

问题如下:

Shell脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env bash

string="Bigdata process framework is Hadoop,Hadoop is an open source project"

function tips_info
{
echo "******************************************"
echo "*** (1) 打印string长度"
echo "*** (2) 在整个字符串中删除Hadoop"
echo "*** (3) 替换第一个Hadoop为Mapreduce"
echo "*** (4) 替换全部Hadoop为Mapreduce"
echo "******************************************"
}

function print_len
{
if [ -z "$string" ];then
echo "Error,string is null"
exit 1
else
echo "${#string}"
fi
}

function del_hadoop
{
if [ -z "$string" ];then
echo "Error,string is null"
exit 1
else
echo "${string//Hadoop/}"
fi
}

function rep_hadoop_mapreduce_first
{
if [ -z "$string" ];then
echo "Error,string is null"
exit 1
else
echo "${string/Hadoop/Mapreduce}"
fi
}

function rep_hadoop_mapreduce_all
{
if [ -z "$string" ];then
echo "Error,string is null"
exit 1
else
echo "${string//Hadoop/Mapreduce}"
fi
}


while true
do

echo "【string=\"$string\"】"
tips_info
read -p "Please Switch a Choice: " choice
case "$choice" in
1)
echo
echo "Length Of String is: `print_len`"
echo
continue
;;
2)
echo
echo "删除Hadoop后的字符串为:`del_hadoop`"
echo
;;
3)
echo
echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_first`"
echo
;;
4)
echo
echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_all`"
echo
;;
q|Q)
exit 0
;;
*)
echo "error,unlegal input,legal input only in { 1|2|3|4|q|Q }"
continue
;;
esac
done

四、命令替换

一段命令的执行结果是另一个命令的一部分,类似于函数引用

  • 例子1

    获取系统所有用户并输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
     #!/bin/bash
    #

    index=1
    for user in `cat /etc/passwd | cut -d ":" -f 1`
    do
    echo "This is $index user: $user"
    index=$(($index + 1))
    done
  • 例子2

    查看系统nginx进程是否存在,若不存在就启动它

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    #

    nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)

    echo "nginx_process_num = $nginx_process_num"

    if [ $nginx_process_num -eq 0 ];then
    systemctl start nginx
    fi

五、有类型变量

1、declare命令

六、数学运算

1、expr命令

2、expr操作符对照表(上)

注意!当使用两变量做比较使用 |、&、<、>、<=、>=符号的时候,需要进行转义,如下:

1
expr $num1 \>= $num2

3、expr操作符对照表(下)

1
num3=`expr $num1 + $num2`

4、小练习

提示用户输入一个正整数num,然后计算1+2+3+4+···+num的值,必须对num是否为正整数做判断,不符合的话应当进行再输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
#

while true
do
read -p "pls input a positive number: " num

expr $num + 1 &> /dev/null

if [ $? -eq 0 ];then
if [ `expr $num \> 0` -eq 1 ];then
for((i=1;i<=$num;i++))
do
sum=`expr $sum + $i`
done
echo "1+2+3+....+$num = $sum"
exit
fi
fi
echo "error,input enlegal"
continue
done

Shell脚本中 $0、$?、$!、$$、$*、$#、$@等的意义说明:

  • $$

    Shell本身的PID(ProcessID,即脚本运行的当前 进程ID号)

  • $!

    Shell最后运行的后台Process的PID(后台运行的最后一个进程的 进程ID号)

  • $?

    最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)

  • $-

    显示shell使用的当前选项,与set命令功能相同

  • $*

    所有参数列表。如”$*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数,此选项参数可超过9个

  • $@

    所有参数列表。如”$@”用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数

  • $@

    跟$*类似,但是可以当作数组用

  • $#

    添加到Shell的参数个数

  • $0

    Shell本身的文件名

  • $1~$n

    添加到Shell的各参数值。$1是第1参数、$2是第2参数…、

七、bc运算

简单介绍:

  • bc是bash内建的运算器,支持浮点数运算
  • 内建变量scale可以设置,默认为0

1、bc操作符对照表

1、加减乘除
2、求余以及指数运算

2、在脚本中使用bc

1
echo  "scale=4;23.33+24" | bc

|表示将前一条命令的输出,用作后一条命令的输入

路由器工作原理

分组调度

排队的分组如何经输出链路传输的问题

1、先进先出

2、优先权排队

  • 高优先权类
  • 低优先权类

3、循环和加权公平排队

网际协议:IPv4、寻址、IPv6及其他

如今有两个版本的IP正在使用:IPv6IPv4

IPv4数据报格式

  • 版本(号)
  • 首部长度
  • 服务类型
  • 数据报长度(字节)
  • 标识、标志、片偏移
  • 寿命
  • 协议
  • 首部检验和
  • 源和目的IP地址
  • 选择
  • 数据

IPv4数据报分片

一个链路层帧能承载的最大数据量叫做最大传送单元(Maximum Transmission Unit,MTU)

IPv4的设计者决定将数据报的重新组装工作放到端系统中

IPv4编址

主机与物理链路之间的边界叫做接口(interface),从技术上讲,一个IP地址与一个接口相关联,而不是与包括该接口的主机或者路由器相关联。

1、获取一个地址

2、获取主机地址:动态主机配置协议

  • DHCP服务器发现
  • DHCP服务器提供
  • DHCP请求
  • DHCP ACK

网络地址转换

NAT路由器

IPv6

32比特的IP地址即将分配完,所以开发了新的IP协议:IPv6

1、IPv6数据报格式

通用转发和SDN

小结

我们讨论了网络层的数据平面(data plane)功能,即每台路由器的如下功能:决定到达输入链路之一的分组如何转发到该路由器的输出链路之一

路由选择算法:目的是从发送方到接收方的过程中确定一条通过路由器网络的好的路径

根据算法集中还是分散划分:

  • 集中式路由选择算法
  • 分散式路由选择算法

根据动态静态划分:

  • 动态路由选择算法
  • 静态路由选择算法

根据负载敏感和迟钝划分:

  • 负载敏感
  • 负载迟钝

1、链路状态路由选择算法

Dijkstra算法

2、距离向量路由选择算法

距离向量算法是一种迭代的、异步的和分布式的算法

运输层位于应用层与网络层中间,为不同主机上的应用进程之间的通信起着至关重要的作用。还有两个非常重要的协议:TCP和UDP运输层协议。

总结一下UDP和TCP最基本的责任:将两个端系统间IP的交付服务拓展为运行在端系统上的两个进程之间的交付服务。

将主机间交付拓展到进程间交付被称为运输层的多路复用(transport-layer multiplexing)多路分解(demultiplexing)

进程到进程之间的数据交付和差错检测是两种最低限度的运输层服务

多路复用与多路分解

网络层提供的主机到主机之间的服务 - 变成 - 运行在主机上的应用程序进程到进程之间的服务

  • 多路分解

将运输层报文段中的数据交付到正确的套接字(socket)

  • 多路复用

在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(用于以后的多路分解)

无连接运输UDP

无连接的,运输层之间没有握手

选择UDP的原因:

  • 关于发送什么数据以及何时发送的应用层控制更为精细

  • 无需连接建立

  • 无连接状态

  • 分组首部开销小

    TCP报文段有20字节的首部开销,UDP仅有8字节的开销

UDP报文段结构

只有四个字段:源端口号、目的端口号、长度、检验和

每个字段两个字节(16bit)

长度字段指示了UDP报文段中的字节数(首部+运送的数据)

检验和用来检查报文段中是否出现了错误,实际上,计算校验和时,还包括了IP首部的一些字段

UDP检验和

为什么UDP也要提供校验和?

因为不能保证源和目的之间所有的链路都提供差错检测

可靠数据传输机制

停止等待协议==》滑动窗口协议==》选择重传协议

机制 用途和说明
检验和
定时器
序号
确认
否定确认
窗口、流水线

面向连接的运输:TCP

TCP连接提供的是双全工服务

TCP报文段结构

1、序号和确认号

  • 序号

TCP将数据看成一个无结构的、有序的字节流,所以序号是建立在传送的字节流之上的

一个报文段的序号(sequence number for a segment)应该是该报文段首字节的字节流编号

  • 确认号

主机A填充进报文段的确认号是希望从主机B收到的下一个字节的序号

TCP只确认该流中至第一个丢失字节为止的字节,所以TCP被称为累计确认(cumulative acknowledge)

可靠的数据传输

流量控制

TCP连接管理

三次握手的详细过程

为什么需要初始序号?为什么需要三次握手而不是两次握手?

四次挥手的详细过程

在CPU中:

  • 运算器进行信息的处理
  • 寄存器进行信息的存储
  • 控制器控制各种器件进行工作
  • 内部总线连接各种器件,在他们中进行数据的传送
  • ……

不同的CPU有不同的寄存器,如8086CPU中就有: AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW

接下来我们先来认识一部分寄存器

一、通用寄存器

8086CPU的所有寄存器都是16位的,可以存放两个字节。AX、BX、CX、DX这个四个寄存器通常用来存放一般性的数据,被称为通用寄存器。

如AX的逻辑结构图如下所示:

8086CPU上一代是8位的,为了保证兼容性,可以将AX、BX、CX、DX分为8个独立的寄存器来使用:

  • AX分为AH和AL
  • BX分为BH和BL
  • ……

8086CPU的16位寄存器分为两个8位寄存器的情况如下所示:

AX的低8位(o位7位)构成了AL寄存器,高8位(8位15位)构成了AH寄存器。AH和AL寄存器是可以独立使用的8位寄存器。图2.4展示了l6位寄存器及它所分成的两个8位寄存器的数据存储的情况。

二、字在寄存器中的存储

出于兼容性的考虑,8086CPU可以一次性处理以下两种尺寸的数据:

  • 字节:记为byte,一个字节由8个bit组成,可以存放在8位寄存器中
  • 字:记为word,一个字由两个字节组成,分为2高位字节和低位字节,如下所示:

三、几条汇编指令

通过汇编指令控制CPU工作:

四、物理地址

五、16位结构的CPU

六、8086CPU给出物理地址的方法

七、“段地址*16 + 偏移地址 = 物理地址”的本质含义

八、段的概念

九、段寄存器

十、CS和IP

十一、修改CS、IP的指令

十二、代码段

maven的生命周期:项目构建的各个阶段,包括 清理、编译、测试、报告、打包、安装、部署

插件:要完成项目的各个阶段,要使用maven命令,执行命令的功能是通过插件完成的。插件就是 jar,代表一些类。

命令:执行maven功能是由命令发出的,比如 mvn compile

单元测试(Junit):

Junit是一个单元测试的工具在Java中经常使用

单元:在Java中指方法,一个方法就是一个单元

作用:使用Junit来测试方法是否达标了

maven相关命令:

(1)mvn clean

(2)mvn compile:编译代码与拷贝文件

(3)

一、Vocabulary

1、edge

v.(使)徐徐移动,渐渐移动

2、vaccine

n.疫苗

3、transmission

n.传播,传染;(电视节目的)播送

4、campaign

n.(尤指政治、商业或军事的)专项活动,运动;战役,作战

5、immunisation

免疫接种

二、Phrase

1、ramp up

提高,使增加

三、SpecificNoun

1、Delta Covid variant

Delta新冠肺炎变异毒株(Covid:冠状病毒,是Corona Virus Disease的缩写)