victory的博客

长安一片月,万户捣衣声

0%

c++二级指针

  • 普通变量作为形参

    在函数中采用普通变量接收实参传递的变量,对变量的操作是对实参拷贝值的操作,不会改变原有变量的值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include<iostream>

    using namespace std;

    void change_value(int a){
    a = 10;
    }

    int main(){
    int a = 10;
    cout << "before changed,a=" << a << endl;//输出:before changed,a=10
    change_value(a);
    cout << "after changed,a=" << a << endl;//输出:after changed,a=10
    return 0;
    }
  • 指针变量作为形参

    由上可知,普通变量作为形参时,对变量的操作其实是对拷贝值的操作,不会改变原来变量的值,若要改变原来变量的值,可采用指针变量作为形参。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include<iostream>

    using namespace std;

    void change_value(int *p){
    *p = 20;
    }

    int main(){
    int a = 10;

    cout << "before changed,a=" << a << endl;//输出:before changed,a=10
    change_value(&a);
    cout << "after changed,a=" << a << endl;//输出:after changed,a=20

    return 0;
    }
  • 二级指针作为形参

    以上是通过函数修改普通变量的值,若要对指针变量的指向进行修改,则需要使用二级指针来实现。

    首先在函数中,采用指针变量作为形参接收实参传递的指针,示例代码如下,由代码输出结果可知,用指针变量作为形参不能够修改原来指针的指向。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include<iostream>

    using namespace std;

    void change_value(int *p){
    p = new int(20);
    }

    int main(){
    int a = 10;
    int *p = &a;

    cout << "before changed,*p=" << *p << endl;//before changed,*p=10
    change_value(p);
    cout << "after changed,*p=" << *p << endl;//after changed,*p=10

    return 0;
    }

    以下代码是二级指针作为形参的示例代码,由代码输出可知,二级指针作为形参时可以修改原来指针变量的指向。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include<iostream>

    using namespace std;

    void change_value(int **p){
    *p = new int(20);
    }

    int main(){
    int a = 10;
    int *p = &a;
    int **pp = &p;
    cout << "before changed,*p" << *p << endl;
    change_value(pp);
    cout << "before changed,*p" << *p << endl;
    cout << "after changed,**pp" << **pp << endl;

    return 0;
    }

此外,二级指针还常与结构体、数组一起使用,二级指针搭配结构体/数组的使用将在后续补充 !

C++指针与引用

学习c++时,很容易混淆指针和引用的用法,以及对指针与引用的使用存在些许疑惑,下面通过示例代码说明指针和引用的区别。

  • 指针与引用的区别?
  1. 定义和性质不同

指针是一个变量,其存储的是一个地址,该地址指向内存的一个存储单元;举例,张三的身份证看做一个指针,这个指针指向了张三,张三的妈妈夸奖了身份证不等于张三的妈妈夸奖了张三。

引用是一个变量的别名,跟原来的变量实质上是同一个东西,类似于日常生活中“小名”的意思,例如张三的小名叫毛蛋,张三与毛蛋都指的是张三这个人,张三的妈妈夸奖了张三等于张三的妈妈夸奖了毛蛋。

1
2
3
int a = 996;
int *p = &a; // p是指针, &在此是求地址运算
int &r = a; // r是引用, &在此起标识作用

上面定义了一个整型变量 a,p 是一个指针变量,p 的值是变量 a 的地址;

而引用 r,是 a 的一个别名,在内存中 r 和 a 占有同一个存储单元。

阅读全文 »

shell脚本

  • shell脚本可将环境变量添加、依赖安装、二进制文件执行等命令包含在一个后缀为.sh的文本文件中,从而便于对应用的自动化运维

  • 常见的shell脚本语法

    1. 向窗口输出文本
    1
    echo "hello world"
    1. for loop
    1
    2
    3
    for file in `ls /etc`;do
    echo $file
    done
    1. 变量定义以及使用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      # 输出变量内容
      word="this is a string!"
      echo $word
      echo "word变量的内容是${word}。"

      # 只读变量
      my_name="liao sheng li"
      readonly my_name
      echo $my_name
      my_name="sheng li" # ./test.sh:行20: my_name:只读变量

      # 删除变量
      username="zhang san"
      echo $username
      unset username
      echo $suername # 不会输出内容
    2. shell字符串

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      # 输出字符串
      echo "hello" # 双引号方式表示字符串
      echo 'hello' # 单引号方式表示字符串
      echo hello # 不使用引号方式

      # 拼接字符串
      echo "hello,"world"!"
      echo 'hello,'world'!'

      # 获取字符串长度
      string="hello"
      echo "字符串的长度为:${#string}"
      echo "字符串的长度为:${#string[0]}"

      # 提取子字符串
      string1="the sky is blue!"
      echo ${string1:4:3}

      # 查找子字符串
      string2="this is a long string!"
      echo `expr index "$string2" is`
  1. 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
    # 定义数组
    arr1=(1 2 3 4 5 6 7 8 9 10)

    # 读取数组
    echo ${arr1}
    elem1=${arr1[0]} # 输出下表为0时的数组元素
    echo $elem1
    echo ${arr1[@]} #输出数组所有元素

    # 获取数组的长度
    echo ${#arr1[@]} # 输出数组长度
    echo ${#arr1[*]} # 输出数组长度
    echo ${#arr1[0]} #输出下表为0的数组元素的长度

    # 关联数组
    declare -A site1=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
    echo ${site1["google"]}
    echo ${site1[@]}
    declare -A site2
    site2["google"]="www.google.com"
    site2["runoob"]="www.runoob.com"
    site2["taobao"]="www.taobao.com"
    echo ${site2["taobao"]}
    echo ${site2[*]}
    1. shell注释
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 这是一个单行注释

    : <<COMMENT
    这是
    一个
    多行注释!
    COMMENT

    : '
    这是一个
    多行注释
    '
  2. 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
    echo "此处执行shell脚本的命令为./test.sh 1 2 3"
    echo "执行的文件名:$0"
    echo "执行的文件名:$1"
    echo "执行的文件名:$2"
    echo "执行的文件名:$3"
    : '
    执行结果:
    执行的文件名:./test.sh
    执行的文件名:1
    执行的文件名:2
    执行的文件名:3
    '
    # 处理参数的集中特殊字符
    echo $# # 输出传递给脚本的参数个数,执行脚本./test.sh 1 2 3输出3
    echo $* # 以单个字符串显示所有传递个脚本的参数就,执行脚本./test.sh 1 2 3输出1 2 3
    echo $$ # 输出脚本运行的当前进行ID号
    echo $@ # 与$*相同
    echo $-
    echo $? #显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误

    # $*与$@的区别
    # $*
    for i in "$*"; do
    echo $i
    done
    # $@
    for i in "$@"; do
    echo $i
    done
  3. 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
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    # 算数运算符
    a=10
    b=20
    val=`expr $a + $b`
    echo "a + b : $val"
    val=`expr $a - $b`
    echo "a - b : $val"
    val=`expr $a \* $b`
    echo "a * b : $val"
    val=`expr $b / $a`
    echo "b / a : $val"
    val=`expr $b % $a`
    echo "b % a : $val"
    if [ $a == $b ]
    then
    echo "a 等于 b"
    fi
    if [ $a != $b ]
    then
    echo "a 不等于 b"
    fi

    # 关系运算符
    a=10
    b=20
    if [ $a -eq $b ] # 判断两个数字的值是否相等
    then
    echo "$a -eq $b : a 等于 b"
    else
    echo "$a -eq $b: a 不等于 b"
    fi
    if [ $a -ne $b ] # 判断两个数字的值是否不相等
    then
    echo "$a -ne $b: a 不等于 b"
    else
    echo "$a -ne $b : a 等于 b"
    fi
    if [ $a -gt $b ] # 判断一个数字是否大于另一个数字
    then
    echo "$a -gt $b: a 大于 b"
    else
    echo "$a -gt $b: a 不大于 b"
    fi
    if [ $a -lt $b ] # 判断一个数字是否小于另一个数字
    then
    echo "$a -lt $b: a 小于 b"
    else
    echo "$a -lt $b: a 不小于 b"
    fi
    if [ $a -ge $b ] # 判断一个数字是否大于小于另一个数字
    then
    echo "$a -ge $b: a 大于或等于 b"
    else
    echo "$a -ge $b: a 小于 b"
    fi
    if [ $a -le $b ] # 判断一个数字是否小于等于另一个数字
    then
    echo "$a -le $b: a 小于或等于 b"
    else
    echo "$a -le $b: a 大于 b"
    fi

    # 布尔运算符
    a=10
    b=20
    if [ $a != $b ] # 非
    then
    echo "$a != $b : a 不等于 b"
    else
    echo "$a == $b: a 等于 b"
    fi
    if [ $a -lt 100 -a $b -gt 15 ] # 与
    then
    echo "$a 小于 100 且 $b 大于 15 : 返回 true"
    else
    echo "$a 小于 100 且 $b 大于 15 : 返回 false"
    fi
    if [ $a -lt 100 -o $b -gt 100 ] # 或
    then
    echo "$a 小于 100 或 $b 大于 100 : 返回 true"
    else
    echo "$a 小于 100 或 $b 大于 100 : 返回 false"
    fi
    if [ $a -lt 5 -o $b -gt 100 ]
    then
    echo "$a 小于 5 或 $b 大于 100 : 返回 true"
    else
    echo "$a 小于 5 或 $b 大于 100 : 返回 false"
    fi

    # 逻辑运算符
    a=10
    b=20
    if [[ $a -lt 100 && $b -gt 100 ]] # 逻辑与
    then
    echo "返回 true"
    else
    echo "返回 false"
    fi
    if [[ $a -lt 100 || $b -gt 100 ]] # 逻辑或
    then
    echo "返回 true"
    else
    echo "返回 false"
    fi

    # 字符串运算符
    a="abc"
    b="efg"
    if [ $a = $b ] # 判断字符串是否相等
    then
    echo "$a = $b : a 等于 b"
    else
    echo "$a = $b: a 不等于 b"
    fi
    if [ $a != $b ] # 判断字符串是否不相等
    then
    echo "$a != $b : a 不等于 b"
    else
    echo "$a != $b: a 等于 b"
    fi
    if [ -z $a ] # 判断字符串长度是否为0
    then
    echo "-z $a : 字符串长度为 0"
    else
    echo "-z $a : 字符串长度不为 0"
    fi
    if [ -n "$a" ] # 判断字符串长度是否不为0
    then
    echo "-n $a : 字符串长度不为 0"
    else
    echo "-n $a : 字符串长度为 0"
    fi
    if [ $a ] # 判断字符串是否为空
    then
    echo "$a : 字符串不为空"
    else
    echo "$a : 字符串为空"
    fi
    echo ""

    # 文件测试运算符
    file="./test.sh"
    if [ -r $file ] # 判断文件是否可读
    then
    echo "文件可读"
    else
    echo "文件不可读"
    fi
    if [ -w $file ] # 判断文件是否可写
    then
    echo "文件可写"
    else
    echo "文件不可写"
    fi
    if [ -x $file ] # 判断文件是否可执行
    then
    echo "文件可执行"
    else
    echo "文件不可执行"
    fi
    if [ -f $file ] # 判断文件是普通文件还是特殊文件
    then
    echo "文件为普通文件"
    else
    echo "文件为特殊文件"
    fi
    if [ -d $file ] # 判断文件是不是一个目录
    then
    echo "文件是个目录"
    else
    echo "文件不是个目录"
    fi
    if [ -s $file ] # 判断文件是否为空
    then
    echo "文件不为空"
    else
    echo "文件为空"
    fi
    if [ -e $file ] # 判断文件是否存在
    then
    echo "文件存在"
    else
    echo "文件不存在"
    fi
  4. shell echo命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 显示普通字符串
    echo "\"显示转义字符\""

    # 显示变量
    read name # read 命令从标准输入中读取一行并赋值给name变量
    echo "$name is one kind of color"

    # 显示换行
    echo -e "hello\n" # -e开启转义
    echo "world"

    # 显示不换行
    echo -e "OK! \c" # \c不换行
    echo "It is a test"

    # 原样输出字符串
    echo '$name\"'

    # 显示命令执行结果
    echo `date`
  5. shell printf命令

    1
    2
    3
    4
    5
    6
    7
    echo "hello"
    printf "hello\n"

    printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
    printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
    printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
    printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
  6. test 命令

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
# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
# 数值测试
num1=100
num2=100
if test $[num1] -eq $[num2] # 代码中的 [] 执行基本的算数运算
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi

# 字符串测试
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi

# 文件测试
if test -e ./test.sh
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
  1. 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
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    # 条件
    # 使用[...] 作为判断语句
    a=10
    b=20
    if [ $a == $b ]
    then
    echo "a 等于 b"
    elif [ $a -gt $b ]
    then
    echo "a 大于 b"
    elif [ $a -lt $b ]
    then
    echo "a 小于 b"
    else
    echo "没有符合的条件"
    fi
    # 使用 ((...)) 作为判断语句,大于和小于可以直接使用 > 和 <
    a=10
    b=20
    if (( $a == $b ))
    then
    echo "a 等于 b"
    elif (( $a > $b ))
    then
    echo "a 大于 b"
    elif (( $a < $b ))
    then
    echo "a 小于 b"
    else
    echo "没有符合的条件"
    fi

    # 循环
    # for循环
    for loop in 1 2 3 4 5
    do
    echo "The value is: $loop"
    done

    # while循环
    int=1
    while(( $int<=5 ))
    do
    echo $int
    let "int++" # Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
    done
    : '
    无限循环
    while :
    do
    command
    done

    while true
    do
    command
    done

    for (( ; ; ))
    '

    # until循环
    a=0
    until [ ! $a -lt 10 ]
    do
    echo $a
    a=`expr $a + 1`
    done

    # case多选择语句
    echo '输入 1 到 4 之间的数字:'
    echo '你输入的数字为:'
    read aNum
    case $aNum in
    1) echo '你选择了 1'
    ;;
    2) echo '你选择了 2'
    ;;
    3) echo '你选择了 3'
    ;;
    4) echo '你选择了 4'
    ;;
    *) echo '你没有输入 1 到 4 之间的数字'
    ;;
    esac

    # 跳出循环
    # break
    while :
    do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
    1|2|3|4|5) echo "你输入的数字为 $aNum!"
    ;;
    *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
    break
    ;;
    esac
    done

    # continue
    : '
    while :
    do
    echo -n "输入 1 到 5 之间的数字: "
    read aNum
    case $aNum in
    1|2|3|4|5) echo "你输入的数字为 $aNum!"
    ;;
    *) echo "你输入的数字不是 1 到 5 之间的!"
    continue
    echo "游戏结束"
    ;;
    esac
    done
    '
  2. 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
    # 无返回值函数
    demoFun(){
    echo "这是我的第一个 shell 函数!"
    }
    echo "-----函数开始执行-----"
    demoFun
    echo "-----函数执行完毕-----"

    # 有返回值函数
    funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"

    # 函数参数
    funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
  3. 输入/输出重定向

    1
    echo 'print("hello")' > hello.py
  4. shell文件包含

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    : '
    shell 脚本中可以包含外部脚本

    语法格式:
    . filename # 注意点号(.)和文件名中间有一空格



    source filename
    '

构建工具CMake

  • 软件构建

    • 自动完成代码编译、链接、打包的整个过程
  • C和C++程序的构建工具-Cmake

  • Cmake的安装

  • gcc/clang编译工具安装(cmake不自带编译工具)

  • 示例代码 main.cpp

    1
    2
    3
    4
    5
    #include<iostream>
    int main(){
    std::cout << "hello,world" << std::endl;
    return 0;
    }
  • 创建CMakeLists.txt文件

    1
    2
    3
    4
    5
    cmake_minimum_required(VERSION 3.10)

    project(Example)

    add_executable(Example main.cpp)
  • 配置项目

    1
    cmake -S . -B build
  • 构建项目

    1
    cmake --build build

    构建完成后生成Example可执行文件,如下图所示:

  • 执行可执行文件

    1
    2
    3
    - cd ./build/
    ./Example
    # 输出hello,world

编译和链接

  • 通过一个代码示例理解编译与链接的过程

    1. 安装gcc

      1
      sudo apt-get install build-essential
    2. 编写示例代码

      main.c

      1
      2
      3
      4
      5
      6
      7
      8
      9
      #include<stdio.h>

      int add(int a, int b);

      int main(){
      printf("hello,world!\n");
      int result = add(5,5);
      return 0;
      }

      math.c

      1
      2
      3
      int add(int a, int b){
      return a + b;
      }
    3. 编译示例代码的两个文件main.c和math.c,得到对应的目标文件(Object File)main.o和math.o

      注:目标文件是二进制文件,文件格式是ELF(Executable and Linkable Format),ELF格式是linux下所有可执行文件的通用格式。

      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
      gcc -c main.c
      gcc -c math.c

      file main.o
      #main.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), #not stripped

      readelf -h main.o
      ELF Header:
      Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
      Class: ELF64
      Data: 2's complement, little endian
      Version: 1 (current)
      OS/ABI: UNIX - System V
      ABI Version: 0
      Type: REL (Relocatable file)
      Machine: Advanced Micro Devices X86-64
      Version: 0x1
      Entry point address: 0x0
      Start of program headers: 0 (bytes into file)
      Start of section headers: 672 (bytes into file)
      Flags: 0x0
      Size of this header: 64 (bytes)
      Size of program headers: 0 (bytes)
      Number of program headers: 0
      Size of section headers: 64 (bytes)
      Number of section headers: 14
      Section header string table index: 13
      1
      2
      3
      readelf -S main.o
      # .text 代码区域
      # .data 数据区域

      objdump -s -d main.o

      -d:将代码段反汇编

      -s:将代码段反汇编的同时,将反汇编代码和源代码交替显示,编译时需要给出- g,即需要调试信息。

      右侧汇编指令中有两个call指令,既主函数中对printf和add的调用,从机器码可以看出跳转地址为0,需要在后续根据重定位表更新到printf和add的实际地址。

      objdump -r main.o

      查看两个函数调用的信息(地址偏移量、类型和值)

    4. 链接

      链接调用的函数机器码并组装为可执行文件main

    1
    gcc main.o math.o -o main
    1. 执行可执行文件main
    1
    2
    ./main
    # 输出hello,world
  • 通过makefile来进行编译链接步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    all: main

    main: main.o math.o
    gcc main.o math.o -o main

    main.o: main.c
    gcc -c main.c

    math.o: math.c
    gcc -c math.c

    clean:
    rm main main.o math.o
    1
    make main             

我的想法 2023.7.15

  • Theme: 让技术有用

  • 我的想法

    • 增加gitee的使用频率,系统学习某个技术并将学习过程或经验推送到gitee

    • 时常维护自己的代码仓库以及个人博客

    • 开发小工具/有用的功能,在gitee建立仓库

    • 在建仓和维护仓库的同时,深入掌握git技术

    • 希望在一年后能够有一个成熟的代码仓库(主题待定)

    • 学习人工智能技术,并注意新技术的体验(例如yolo目标检测这样的技术)

Docker的安装及常用命令

  • Docker是什么?Docker的作用?

    • Docker是一个开源的应用容器引擎,基于Go语言开发,可以让开发者打包应用以及依赖包到容器中,然后发布到任何linux机器上,在移植应用时不需要重新搭建环境和导入依赖,具备强大的可移植性。与虚拟机有所区别,虚拟机虚拟出一套硬件并在其上搭建环境并部署应用,而docker通过将应用与依赖打包,从而达到可移植、快速部署的目的。
  • Docker安装

    ubuntu环境下Docker安装教程

  • 常用镜像(image)操作

    • 查找镜像

      1
      docker search image_name
    • 获取镜像

      1
      docker pull image_name
    • 列出镜像列表

      1
      docker images # 或docker image ls
    • 删除镜像

      1
      docker rmi image_name
  • 常用容器(container)操作

    • 查看正在运行的容器

      1
      2
      docker ps -a
      docker ps -q#只输出容器id
    • 启动容器

      1
      docker run -itd --name container_name image_name /bin/bash
      • -i:交互式操作
      • -t:终端
      • -d:docker服务在后台运行,启动后不会进入容器
    • 交互方式进入容器

      1
      docker exec -it container_id /bin/bash
    • 将主机内容复制到容器中

      1
      docker cp file_name container_id:/path/directory
    • 启动已停止容器

      1
      docker start conatainer_id
    • 停止容器

      1
      docker stop container_id
    • 重启容器

      1
      docker restart container_id
    • 删除容器

      1
      docker rm container_id
    • 导出和导入容器

      1
      2
      3
      docker export container_id > xxx.tar # 导出容器

      docker import - image_name:image_tag # 根据镜像导入容器
    • 清理所有处于终止状态的容器

      1
      docker container prune

135.分发糖果

题目描述

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:
1)每个孩子至少分配到 1 个糖果。
2)相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:
输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。

示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。

题目链接

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
def candy(self, ratings: List[int]) -> int:
n = len(ratings)
left = [0] * n
for i in range(n):
if i > 0 and ratings[i] > ratings[i - 1]:
left[i] = left[i - 1] + 1
else:
left[i] = 1

right = ret = 0
for i in range(n - 1, -1, -1):
if i < n - 1 and ratings[i] > ratings[i + 1]:
right += 1
else:
right = 1
ret += max(left[i], right)

return ret