数据结构与算法

目录

第一节 基本概念
1.1 数据结构
1.1.1 定义
1.2 算法
1.2.1 定义

第一节 基本概念

1.1 数据结构

1.1.1 定义

数据对象在计算机中的组织方式和与之相关联的一个操作集,以及实现这些操作的最高效的算法

1.2 算法

1.2.1 定义

算法是一个有限指令集,接受一些输入,产生一些输出,并在有限步骤后终止。

1.2.2 算法复杂度
  1. 空间复杂度 根据算法写成的程序在执行时占用存储单元的长度。
  2. 时间复杂度 根据算法写成的程序在执行时耗费时间的长度
    1.2.3 复杂度的表示法
  3. $T(n)=O(f(n))$表示存在常数$C>0$, $n_0 > 0$,使得当$n \ge n_0$时有$T(n) \le C(f(n))$
  4. $T(n)=\Omega(g(n))$表示存在常数$C>0$,$ n_0 > 0$,使得当$n \ge n_0$时有$T(n) \ge C(g(n))$
  5. $T(n)=\Theta(h(n))$表示同时有$T(n)=O(h(n))$和$T(n)=\Omega(h(n))$
    1.2.4 算法复杂度几个估算方法
  6. 若两段算法分别有复杂度$T_1(n)=O(f_1(n))$和$T_2(n)=O(f_2(n))$,那么两段算法串联的复杂度为$T_1(n)+T_2(n)=max(O(f_1(n)),O(f_2(n)))$,嵌套在一起的复杂度为$T_1(n)\times T_2(n)=O(f_1(n)\times f_2(n))$
  7. 若$T(n)$是关于$n$的$k$阶多项式,那么$T(n)=\Theta(n^k)$
  8. 一个for循环的时间复杂度等于循环次数乘以循环体代码的复杂度
  9. 若干层嵌套循环的时间复杂度等于各层循环次数的乘积再乘以循环体代码的复杂度
  10. if-else结构的复杂度取决于if条件判断复杂度和两个分支部分的复杂度,总体复杂度取三者中最大

    第二节 线性结构

    2.1 线性表的定义和实现

    2.1.1 线性表的定义
    1. 定义

线性表是由同一类型的数据元素构成的有序序列的线性结构。
线性表中元素的个数称为线性表的长度
当一个线性表中没有元素(长度为0)时,称为空表
表的起始位置称为表头,表的结束位置称为表尾

2.抽象数据类型描述

类型名称:线性表
数据对象集:线性表是$n(n\ge 0)$个元素构成的有序序列$(a_1, a_2,\cdots ,a_n)$,其中$a_1$是表的第一个元素(表头),$a_n$是表的最后一个元素(表尾);$a_{i+1}$称为$a_i$的直接后继,$a_{i-1}$为$a_i$的直接前驱;直接前驱和直接后继反映了元素之间一对一的邻接逻辑关系。
操作集:对于一个具体的线性表$L\in List$,一个表示位序的整数i,一个元素$X\in ElementType$,线性表的基本操作主要有:
(1)List MakeEmpty():初始化一个新的空线性表;
(2)ElementType findKth(List L, int i):根据指定的位序i,返回L中相应的元素$a_i$;
(3)Position Find(List L, ElementType X):已知X,返回线性表L中与X相同的第一个元素的位置;若不存在则返回错误信息;
(4)bool Insert(List L, ElementType X, int i):在L的指定位序i前插入一个新元素X;成功则返回true,否则返回false;
(5)bool Delete(List L, int i):从L中删除指定位序i的元素;成功则返回true,否则返回false;
(6)int Length(List L):返回线性表L的长度。

2.1.2 线性表的顺序存储实现
  1. 线性表结构定义和封装
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef int Position;
    // 使用指针来操作线性表,提高效率
    typedef struct LNode * PtrToLNode;
    // 线性表结构包含了存储数据的数组Data和指明表尾位置的Last
    struct LNode {
    ElemenType Data[MAXSIZE];
    Position Last;
    }
    // 将线性表别名定为List
    typedef PtrToLNode List;
  2. 初始化
    1
    2
    3
    4
    5
    6
    7
    8
    List MakeEmpty() {
    List L;
    // 为线性表分配空间
    L = (List) malloc(sizeof(struct LNode));
    // 表内无数据,将表尾位置Last设为-1
    L->Last = -1;
    return L;
    }
  3. 查找
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #define ERROR -1
    Position find(List L, ElemenType X) {
    Position i = 0;
    // 从0开始遍历数组,查找X相等的项
    while (i <= L->Last && L->Data[i] != X) {
    i++;
    }
    // 没有查到则i = L->Last + 1
    if (i > L->Last) return ERROR;
    return i;
    }
  4. 插入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    bool Insert(List L, ElementType X, int i) {
    // 检查数组是否已经填满
    if (L->Last == MAXSIZE - 1) {
    printf("data is full");
    return false;
    }

    // 检查位序i是否合法,在1(表头)到L->Last + 2(表尾后一项)之间
    if (i < 1 || i > L->Last + 2) {
    printf("invalid position");
    return false;
    }

    // 从表尾开始,将每一项向后移动一位
    for (int j = L->Last; j >= i - 1; j--) {
    L->Data[j + 1] = L->Data[j];
    }

    // 将第i位值设为X
    L->Data[i - 1] = X;
    // 修改表长
    L->Last++;
    return true;
    }
  5. 删除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    bool Delete(List L, int i) {
    // 检查位序i是否合法,在1(表头)到L->Last + 1(表尾)之间
    if (i < 1 || i > L->Last + 1) {
    printf("invalid position");
    return false;
    }
    // 从第i + 1位开始,将每一项向前移动一位
    for (int j = i; j <= L->Last; j++) {
    L->Data[j - 1] = L->Data[j];
    }
    // 修改表长
    L->Last--;
    return true;
    }
    2.1.3 线性表的链式存储实现
  6. 线性表结构的定义和封装
    1
    2
    3
    4
    5
    6
    7
    typedef struct LNode * PtrToLNode;
    struct LNode {
    ElementType Data;
    PtrToLNode Next;
    }
    typedef PtrToLNode Position;
    typedef PtrToLNode List;
  7. 求表长
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int Length(List L) {
    Position p;
    int size = 0;
    p = L;
    while(p) {
    p = p->Next;
    size++;
    }
    return size;
    }
  8. 查找
    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
    #define ERROR -1

    ElementType FindKth(List L, int K) {
    Position = p;
    // 从第一位开始查找
    int cnt = 1;
    p = L;
    // 依次遍历,直到表尾或者第K位
    while (p && (cnt < K)) {
    p = p->Next;
    }
    // 如果当前位序为K,说明位数合法,返回p的数据,否则返回错误码
    if (p && (cnt == K)) {
    return p->Data;
    } else {
    return ERROR;
    }
    }

    Position Find(List L, ElementType X) {
    Position p;
    p = L;
    // 从头开始查找数据与给出相符的
    while (p && p->Data != X) {
    p = p->Next;
    }
    // 数据不存在,p指向队尾的Next,即NULL,返回错误码
    if (p) {
    return p;
    } else {
    return ERROR;
    }
    }
  9. 插入
    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
    #defile ERROR NULL
    List Insert(List L, ElementType X, int i) {
    Position tmp, pre;
    tmp = (Position) malloc(sizeof(struct LNode));
    tmp->Data = X;
    if (i == 1) {
    // 表头插入元素
    tmp->Next = L;
    // 将新节点作为表头返回
    return tmp;
    } else {
    int cnt = 1;
    pre = L;
    // 查找原第i - 1位(待插入位置前一位)的元素
    while(pre && (cnt < i - 1)) {
    pre = pre->Next;
    cnt++;
    }
    // 如果没有找到该元素或者位序异常,释放空间,返回错误码
    if (pre == NULL || cnt != i - 1) {
    printf("position error");
    free(tmp);
    return ERROR;
    } else {
    tmp->Next = pre->Next;
    pre->Next = tmp;
    return L;
    }
    }
    }
  10. 删除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    bool Delete(List L, int i) {
    Position tmp, pre;
    int cnt = 0;
    pre = L;
    while (pre && cnt < i - 1) {
    pre = pre->Next;
    cnt++:
    }

    if (pre == NULL || cnt != i - 1 || pre->Next == NULL) {
    printf("invalid position");
    return false;
    } else {
    tmp = pre->Next;
    pre->Next = tmp->Next;
    free(tmp);
    return true;
    }
    }

2.2 堆栈

2.2.1 堆栈的定义
1. 定义

堆栈是具有一定约束的线性表,插入和删除都需要从端点进行,这一端点称之为栈顶

2. 堆栈抽象数据描述

类型名称:堆栈;
数据对象集:一个有0个或多个元素的有穷线性表;
操作集:对一个具体的长度为正整数MaxSize的堆栈$S\in Stack$,记堆栈中任一元素$X\in ElementType$,堆栈的主要操作有:
(1)Stack CreateStack(int MaxSize):生成空堆栈,其最大长度为MaxSize;
(2)bool isFull(Stack S):判断堆栈S是否已满;
(3)bool Push(Stack S, ElementType X):将元素X压入栈。堆栈已满返回false;否则将元素插入到堆栈S的栈顶处并返回true;
(4)bool IsEmpty(Stack S):判断堆栈S是否为空;
(5)ElementType Pop(Stack S):删除并返回栈顶元素。
数据结构与算法
=====

目录

第一节 基本概念
1.1 数据结构
1.1.1 定义
1.2 算法
1.2.1 定义

第一节 基本概念

1.1 数据结构

1.1.1 定义

数据对象在计算机中的组织方式和与之相关联的一个操作集,以及实现这些操作的最高效的算法

1.2 算法

1.2.1 定义

算法是一个有限指令集,接受一些输入,产生一些输出,并在有限步骤后终止。

1.2.2 算法复杂度
  1. 空间复杂度 根据算法写成的程序在执行时占用存储单元的长度。
  2. 时间复杂度 根据算法写成的程序在执行时耗费时间的长度
    1.2.3 复杂度的表示法
  3. $T(n)=O(f(n))$表示存在常数$C>0$, $n_0 > 0$,使得当$n \ge n_0$时有$T(n) \le C(f(n))$
  4. $T(n)=\Omega(g(n))$表示存在常数$C>0$,$ n_0 > 0$,使得当$n \ge n_0$时有$T(n) \ge C(g(n))$
  5. $T(n)=\Theta(h(n))$表示同时有$T(n)=O(h(n))$和$T(n)=\Omega(h(n))$
    1.2.4 算法复杂度几个估算方法
  6. 若两段算法分别有复杂度$T_1(n)=O(f_1(n))$和$T_2(n)=O(f_2(n))$,那么两段算法串联的复杂度为$T_1(n)+T_2(n)=max(O(f_1(n)),O(f_2(n)))$,嵌套在一起的复杂度为$T_1(n)\times T_2(n)=O(f_1(n)\times f_2(n))$
  7. 若$T(n)$是关于$n$的$k$阶多项式,那么$T(n)=\Theta(n^k)$
  8. 一个for循环的时间复杂度等于循环次数乘以循环体代码的复杂度
  9. 若干层嵌套循环的时间复杂度等于各层循环次数的乘积再乘以循环体代码的复杂度
  10. if-else结构的复杂度取决于if条件判断复杂度和两个分支部分的复杂度,总体复杂度取三者中最大

    第二节 线性结构

    2.1 线性表的定义和实现

    2.1.1 线性表的定义
    1. 定义

线性表是由同一类型的数据元素构成的有序序列的线性结构。
线性表中元素的个数称为线性表的长度
当一个线性表中没有元素(长度为0)时,称为空表
表的起始位置称为表头,表的结束位置称为表尾

2.抽象数据类型描述

类型名称:线性表
数据对象集:线性表是$n(n\ge 0)$个元素构成的有序序列$(a_1, a_2,\cdots ,a_n)$,其中$a_1$是表的第一个元素(表头),$a_n$是表的最后一个元素(表尾);$a_{i+1}$称为$a_i$的直接后继,$a_{i-1}$为$a_i$的直接前驱;直接前驱和直接后继反映了元素之间一对一的邻接逻辑关系。
操作集:对于一个具体的线性表$L\in List$,一个表示位序的整数i,一个元素$X\in ElementType$,线性表的基本操作主要有:
(1)List MakeEmpty():初始化一个新的空线性表;
(2)ElementType findKth(List L, int i):根据指定的位序i,返回L中相应的元素$a_i$;
(3)Position Find(List L, ElementType X):已知X,返回线性表L中与X相同的第一个元素的位置;若不存在则返回错误信息;
(4)bool Insert(List L, ElementType X, int i):在L的指定位序i前插入一个新元素X;成功则返回true,否则返回false;
(5)bool Delete(List L, int i):从L中删除指定位序i的元素;成功则返回true,否则返回false;
(6)int Length(List L):返回线性表L的长度。

2.1.2 线性表的顺序存储实现
  1. 线性表结构定义和封装
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef int Position;
    // 使用指针来操作线性表,提高效率
    typedef struct LNode * PtrToLNode;
    // 线性表结构包含了存储数据的数组Data和指明表尾位置的Last
    struct LNode {
    ElemenType Data[MAXSIZE];
    Position Last;
    }
    // 将线性表别名定为List
    typedef PtrToLNode List;
  2. 初始化
    1
    2
    3
    4
    5
    6
    7
    8
    List MakeEmpty() {
    List L;
    // 为线性表分配空间
    L = (List) malloc(sizeof(struct LNode));
    // 表内无数据,将表尾位置Last设为-1
    L->Last = -1;
    return L;
    }
  3. 查找
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #define ERROR -1
    Position find(List L, ElemenType X) {
    Position i = 0;
    // 从0开始遍历数组,查找X相等的项
    while (i <= L->Last && L->Data[i] != X) {
    i++;
    }
    // 没有查到则i = L->Last + 1
    if (i > L->Last) return ERROR;
    return i;
    }
  4. 插入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    bool Insert(List L, ElementType X, int i) {
    // 检查数组是否已经填满
    if (L->Last == MAXSIZE - 1) {
    printf("data is full");
    return false;
    }

    // 检查位序i是否合法,在1(表头)到L->Last + 2(表尾后一项)之间
    if (i < 1 || i > L->Last + 2) {
    printf("invalid position");
    return false;
    }

    // 从表尾开始,将每一项向后移动一位
    for (int j = L->Last; j >= i - 1; j--) {
    L->Data[j + 1] = L->Data[j];
    }

    // 将第i位值设为X
    L->Data[i - 1] = X;
    // 修改表长
    L->Last++;
    return true;
    }
  5. 删除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    bool Delete(List L, int i) {
    // 检查位序i是否合法,在1(表头)到L->Last + 1(表尾)之间
    if (i < 1 || i > L->Last + 1) {
    printf("invalid position");
    return false;
    }
    // 从第i + 1位开始,将每一项向前移动一位
    for (int j = i; j <= L->Last; j++) {
    L->Data[j - 1] = L->Data[j];
    }
    // 修改表长
    L->Last--;
    return true;
    }
    2.1.3 线性表的链式存储实现
  6. 线性表结构的定义和封装
    1
    2
    3
    4
    5
    6
    7
    typedef struct LNode * PtrToLNode;
    struct LNode {
    ElementType Data;
    PtrToLNode Next;
    }
    typedef PtrToLNode Position;
    typedef PtrToLNode List;
  7. 求表长
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int Length(List L) {
    Position p;
    int size = 0;
    p = L;
    while(p) {
    p = p->Next;
    size++;
    }
    return size;
    }
  8. 查找
    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
    #define ERROR -1

    ElementType FindKth(List L, int K) {
    Position = p;
    // 从第一位开始查找
    int cnt = 1;
    p = L;
    // 依次遍历,直到表尾或者第K位
    while (p && (cnt < K)) {
    p = p->Next;
    }
    // 如果当前位序为K,说明位数合法,返回p的数据,否则返回错误码
    if (p && (cnt == K)) {
    return p->Data;
    } else {
    return ERROR;
    }
    }

    Position Find(List L, ElementType X) {
    Position p;
    p = L;
    // 从头开始查找数据与给出相符的
    while (p && p->Data != X) {
    p = p->Next;
    }
    // 数据不存在,p指向队尾的Next,即NULL,返回错误码
    if (p) {
    return p;
    } else {
    return ERROR;
    }
    }
  9. 插入
    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
    #defile ERROR NULL
    List Insert(List L, ElementType X, int i) {
    Position tmp, pre;
    tmp = (Position) malloc(sizeof(struct LNode));
    tmp->Data = X;
    if (i == 1) {
    // 表头插入元素
    tmp->Next = L;
    // 将新节点作为表头返回
    return tmp;
    } else {
    int cnt = 1;
    pre = L;
    // 查找原第i - 1位(待插入位置前一位)的元素
    while(pre && (cnt < i - 1)) {
    pre = pre->Next;
    cnt++;
    }
    // 如果没有找到该元素或者位序异常,释放空间,返回错误码
    if (pre == NULL || cnt != i - 1) {
    printf("position error");
    free(tmp);
    return ERROR;
    } else {
    tmp->Next = pre->Next;
    pre->Next = tmp;
    return L;
    }
    }
    }
  10. 删除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    bool Delete(List L, int i) {
    Position tmp, pre;
    int cnt = 0;
    pre = L;
    while (pre && cnt < i - 1) {
    pre = pre->Next;
    cnt++:
    }

    if (pre == NULL || cnt != i - 1 || pre->Next == NULL) {
    printf("invalid position");
    return false;
    } else {
    tmp = pre->Next;
    pre->Next = tmp->Next;
    free(tmp);
    return true;
    }
    }

2.2 堆栈

2.2.1 堆栈的定义
1. 定义

堆栈是具有一定约束的线性表,插入和删除都需要从端点进行,这一端点称之为栈顶

2. 堆栈抽象数据描述

类型名称:堆栈;
数据对象集:一个有0个或多个元素的有穷线性表;
操作集:对一个具体的长度为正整数MaxSize的堆栈$S\in Stack$,记堆栈中任一元素$X\in ElementType$,堆栈的主要操作有:
(1)Stack CreateStack(int MaxSize):生成空堆栈,其最大长度为MaxSize;
(2)bool isFull(Stack S):判断堆栈S是否已满;
(3)bool Push(Stack S, ElementType X):将元素X压入栈。堆栈已满返回false;否则将元素插入到堆栈S的栈顶处并返回true;
(4)bool IsEmpty(Stack S):判断堆栈S是否为空;
(5)ElementType Pop(Stack S):删除并返回栈顶元素。

Ubuntu18.04 添加开机启动任务

创建服务

1
sudo vi /lib/systemd/system/shadowsocks.service

在打开的文件中输入如下内容:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Shadowsocks
After=network.target

[Service]
ExecStart=/usr/bin/ssserver -c /etc/shadowsocks/config.json

[Install]
WantedBy=multi-user.target

其中ExecStart是服务启动时执行的命令,开机时所有注册的服务都会统一启动。
如果有结束命令,还可以类似的添加ExecStop,在结束服务时执行命令。

启动服务

首先重载所有的服务

1
sudo systemctl daemon-reload

然后启动shadowssocks服务,注意,之前创建的是shadowsocks.service。
这里的service后缀是可以省略的。

1
sudo systemctl start shadowsocks

执行上述命令都是没有输出反馈的,需要执行如下命令查看服务的状态:

1
sudo systemctl status shadowsocks

如果输入类似如下说明服务正常启动了。

1
2
3
4
5
6
7
8
9
10
11
12
shadowsocks.service - Shadowsocks
Loaded: loaded (/lib/systemd/system/shadowsocks.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2018-09-20 06:04:59 UTC; 1s ago
Main PID: 19413 (ssserver)
Tasks: 1 (limit: 507)
CGroup: /system.slice/shadowsocks.service
└─19413 /usr/bin/python /usr/bin/ssserver -c /etc/shadowsocks/config.json

Sep 20 06:04:59 vultr.guest systemd[1]: Started Shadowsocks.
Sep 20 06:04:59 vultr.guest ssserver[19413]: INFO: loading config from /etc/shadowsocks/config.json
Sep 20 06:04:59 vultr.guest ssserver[19413]: 2018-09-20 06:04:59 INFO loading libcrypto from libcrypto.so.1.1
Sep 20 06:04:59 vultr.guest ssserver[19413]: 2018-09-20 06:04:59 INFO starting server at 111:232:232:222:10086

Ubuntu新用户添加

ubuntu新用户添加

前言

本文所述操作在ubuntu18.04环境下进行,其他版本操作相同。
操作需要先切换到root用户,如果是搭建的VPS,初始应该都在root用户,无需其他操作。
示例中的用户名为chen,你可以修改为任意你想要的名称。

创建用户

useradd chen

设定密码

passwd chen

执行上述语句后,需要重复输入两次密码,密码输入时不可见,请注意不要按错。

添加sudo权限

visudo

执行上述命令后,会打开/etc/sudoers文件,编辑器应该是nano。

在文件中找到如下内容

root ALL=(ALL:ALL) ALL

在其下一行仿照输入

chen ALL=(ALL:ALL) ALL

然后按下ctrl + x,在询问是否保存时,输入y并回车即可保存当前的修改。

网络设置

预加载网卡设备

1
ip -o -4 a sh
1
2
3
output:
1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
4: wlan0 inet 192.168.1.149/24 brd 192.168.1.255 scope global wlan0\ valid_lft forever preferred_lft forever

使用正则表达式筛选出网卡设备名

1
(?<=: )\w+(?=    inet)

判断IP不为127.0.0.1

1
(?<=inet )127.0.0.1(?=/)

添加IP

1
ip addr add 192.168.1.197/24 dev wlan0

再次执行

1
ip -o -4 a sh
1
2
3
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
4: wlan0 inet 192.168.1.149/24 brd 192.168.1.255 scope global wlan0\ valid_lft forever preferred_lft forever
4: wlan0 inet 192.168.1.197/24 scope global secondary wlan0\ valid_lft forever preferred_lft forever

筛选出网卡设备名为wlan0的行

1
(?<=: )wlan0(?=    inet)

获取所有的IP,确认IP设定成功

1
(?<=inet )([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])){3}(?=/)

添加route

1
ip route add 192.168.1.1 via default

查看结果

1
ip r sh
1
2
default via 192.168.1.3 dev wlan0
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.150

DHCP

1
2
netcfg wlan0 up dhcp
dhcpcd -U eth1

设置DNS

首先获取对应的设备的dns,不存在则获取net.dns1

1
2
3
4
5
getprop net.wlan0.dns1
getprop net.wlan1.dns2

getprop net.dns1
getprop net.dns2

如果net.wlan0.dns1存在,使用如下命令

1
ndc resolver setnetdns wlan0 8.8.8.8 8.8.4.4
1
2
3
4
ndc resolver flushif wlan0
ndc resolver flushdefaultif
ndc resolver setifdns wlan0 0.0.0.0 8.8.8.8 8.8.4.4
ndc resolver setdefaultif wlan0

树莓派初始化

  1. 从官方源下载raspbian镜像,然后使用USB Image Tools烧写入SD卡中
  2. 打开boot,新建名称为ssh的文件,以便可以通过ssh连接设备
  3. 使用XSehll远程连接树莓派,默认的用户名为pi,默认密码为raspberry
  4. 修改软件源
    修改debian软件源
    1
    sudo vi /etc/apt/sources.list
    1
    2
    deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
    #deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi

修改raspbian的软件源

1
sudo nano /etc/apt/sources.list.d/raspi.list
1
2
deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ stretch main ui
#deb http://archive.raspberrypi.org/debian/ stretch main ui
  1. 修改swap分区
    1
    sudo vi /etc/dphys-swapfile
    修改swap大小为2GB
    1
    CONF_SWAPSIZE=2048
    重启服务以应用修改
    1
    sudo service dphys-swapfile restart