首页 > 技术文章 > Linux学习笔记

henry829 2021-01-20 16:22 原文

环境搭建

安装VM

https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html

在虚拟机上安装CentOS7

  1. 下载https://www.centos.org/download/ X86_64标准版

  2. 按照教程安装linux https://blog.csdn.net/babyxue/article/details/80970526

  3. 创建root管理员和sa用户

阿里云服务器

  1. 使用putty或者xshell远程连接阿里云

  2. 连接到服务器之后,需要搭建环境

    使用宝塔面板

    yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh

    安装教程 https://www.bt.cn/bbs/thread-19376-1-1.html

    下载完毕后就可以得到一个地址,用户名和密码

    放入网站进行访问

    war直接丢到tomcat即可

    jar直接用java -jar执行即可访问

Linux系统

关机

在linux大多用在服务器上,很少遇到关机的操作

关机的指令为:shutdown

 

 

 

sync  # 将数据由内存同步到硬盘中
shutdown # 关机指令
shutdown -h 10 # 在10分钟之后关机
shutdown -h now # 立马关机
shutdown -h 12:20 # 在12:20关机
shutdown -r now  # 系统立马重启
shutdown -r 10   # 系统10分钟之后重启
reboot # 重启等同于 shutdown -r now
halt # 关闭系统  等同于shutdown -h now 和 poweroff

不管是重启系统还是关闭系统,首先要允许sync指令,将内存的数据写到磁盘中

 

系统目录结构

一切皆文件

根目录/,所有的文件都挂载在这个节点下

基本目录介绍:

 

 

常用的基本命令

目录管理

  • 绝对路径:路径的全称

  • 相对路径:相对于某个文件夹的路径

cd:切换目录命令

cd .. :返回上一级

cd xx:进入到xx目录(绝对路径以/开头,相对路径是对于当前目录如何找)

 

 

 

 

ls:列出目录

ls -a :查看全部的文件,包括隐藏文件

ls -l:列出所有的文件,包括文件的属性和权限,不会显示隐藏的文件

ls -al:组合使用两个

 

 

 

 

pwd显示当前用户所在的目录

 

 

mkdir 创建一个目录

mkdir -p t1/t2 :创建多层级目录

 

rmdir 删除目录

rmdir -p t1/t2 删除多层目录

rmdir仅能删除空的目录,如果下面存在文件,需要先删除文件

 

cp 复制文件或者目录

cp 文件 路径:拷贝文件到指定目录

 

复制同一份文件到相同位置,可以选择覆盖y或者放弃n

 

 

rm 移除文件或者目录

-f 忽略不存在的文件,不会出现警告,强制删除

-r 递归删除目录

-i 互动,删除会询问

 

 

mv 移动文件或者目录 重命名文件夹或者文件

-f 强制

-u 只替换已经更新过的文件

 

改文件或者文件夹名字

 

 

基本属性

Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定

 

第一个字符代表这个文件是目录、文件或者链接文件等

  • d:目录

  • -:文件

  • l:链接文档

接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合,其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)

第0位确定文件类型,第1-3位确定属主(该文件的所有者)拥有该文件的权限。第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限

第一列root,表示属主,谁创建的

第二列root,表示属组,用户组

修改文件属性

1、chgrp:更改文件属组

chgrp [-R] 属组名 文件名

-R:递归更改文件属组,就是在更改某个目录文件的属组时,如果加上-R的参数,那么该目录下的所有文件的属组都会更改。

 

 

2、chown:更改文件属主,也可以同时更改文件属组

chown [–R] 属主名 文件名
chown [-R] 属主名:属组名 文件名

3、chmod:更改文件的属性

chmod [-R] xyz 文件或目录

Linux文件属性有两种设置方法,一种是数字(常用),一种是符号

Linux文件的基本权限就有九个,分别是owner/group/others三种身份各有自己的read/write/execute权限

r:4     w:2      x:1

每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的

  • owner = rwx = 4+2+1 = 7

  • group = rwx = 4+2+1 = 7

  • others= --- = 0+0+0 = 0

    chmod 770 filename

文件内容查看

Linux系统使用以下命令查看文件的内容

  • cat 由第一行开始显示文件内容

  • tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写!

     

     

  • nl 显示的时候,顺道输出行号!

     

     

  • more 一页一页的显示文件内容(空格表示翻页,enter代表向下看一行)

     

     

  • less 与 more 类似,但是比 more 更好的是,他可以往前翻页!(上下键,q退出,查找字符串使用/+要查询的字符串向下查询,向上查询使用?+要查询的字符串,n或者N继续搜寻查找)

  • head 只看头几行,通过-n参数

     

     

  • tail 只看尾巴几行,-n参数

     

     

网络配置目录:cd /etc/sysconfig/network-scripts(Centos7)

 

 

ifconfig命令查看网络配置

 

 

 

Linux链接

Linux的链接分为两种,硬链接和软链接

硬链接:类似于复制一份

软连接:类似快捷方式,删除源文件,快捷方式也访问不了

创建链接ln 命令

touch创建文件

echo 输入字符串

[root@izuf6hm75axg2u4zfbcctoz home]# touch f1   # 创建一个f1文件
[root@izuf6hm75axg2u4zfbcctoz home]# ls
admin                 apache-tomcat-8.5.47-windows-x64.zip  redis      t2
apache-tomcat-8.5.47  f1                                    staragent  www
[root@izuf6hm75axg2u4zfbcctoz home]# ln f1 f2   # 创建一个硬链接f2
[root@izuf6hm75axg2u4zfbcctoz home]# ls
admin                                 f1     staragent
apache-tomcat-8.5.47                  f2     t2
apache-tomcat-8.5.47-windows-x64.zip  redis  www
[root@izuf6hm75axg2u4zfbcctoz home]# ln -s f1 f3  # 创建一个软连接f3
[root@izuf6hm75axg2u4zfbcctoz home]# ls
admin                                 f1  redis      www
apache-tomcat-8.5.47                  f2  staragent
apache-tomcat-8.5.47-windows-x64.zip  f3  t2
[root@izuf6hm75axg2u4zfbcctoz home]# ls -l
total 11932
drwx------ 3 admin admin     4096 Jan 19 16:04 admin
drwxr-xr-x 9 root  root      4096 Oct  7  2019 apache-tomcat-8.5.47
-rw-r--r-- 1 root  root  12190192 Jan 20 11:07 apache-tomcat-8.5.47-windows-x64.zip
-rw-r--r-- 2 root  root         0 Jan 21 12:07 f1
-rw-r--r-- 2 root  root         0 Jan 21 12:07 f2
lrwxrwxrwx 1 root  root         2 Jan 21 12:07 f3 -> f1
drwx------ 2 redis redis     4096 Jan 19 21:16 redis
drwxr-x--- 9 root  root      4096 Aug 24  2017 staragent
drwxr-xr-x 2 root  root      4096 Jan 20 16:10 t2
dr-xr-x--- 4 www   www       4096 Jan  5  2018 www
[root@izuf6hm75axg2u4zfbcctoz home]# echo "henry good" >>f1  #给f1写入
[root@izuf6hm75axg2u4zfbcctoz home]# cat f1
henry good
[root@izuf6hm75axg2u4zfbcctoz home]# cat f2
henry good
[root@izuf6hm75axg2u4zfbcctoz home]# cat f3
henry good
[root@izuf6hm75axg2u4zfbcctoz home]# 
 

删除f1,查看f2和f3

[root@izuf6hm75axg2u4zfbcctoz home]# rm -f f1
[root@izuf6hm75axg2u4zfbcctoz home]# ls
admin                                 f2     staragent
apache-tomcat-8.5.47                  f3     t2
apache-tomcat-8.5.47-windows-x64.zip  redis  www
[root@izuf6hm75axg2u4zfbcctoz home]# cat f2
henry good
[root@izuf6hm75axg2u4zfbcctoz home]# cat f3
cat: f3: No such file or directory
[root@izuf6hm75axg2u4zfbcctoz home]# 

  

 

Vim编辑器

Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富

三种使用模式

基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode)输入模式(Insert mode)底线命令模式(Last line mode)

命令模式

用户启动vim,进入了命令模式

  • i 切换到输入模式,以输入字符。

  • x 删除当前光标所在处的字符。

  • : 切换到底线命令模式,以在最底一行输入命令。

 

 

输入模式

在命令模式下按下i就进入了输入模式。

在输入模式中,可以使用以下按键:

  • 字符按键以及Shift组合,输入字符

  • ENTER,回车键,换行

  • BACK SPACE,退格键,删除光标前一个字符

  • DEL,删除键,删除光标后一个字符

  • 方向键,在文本中移动光标

  • HOME/END,移动光标到行首/行尾

  • Page Up/Page Down,上/下翻页

  • Insert,切换光标为输入/替换模式,光标将变成竖线/下划线

  • ESC,退出输入模式,切换到命令模式

底线输入模式

在命令模式下按下:(英文冒号)就进入了底线命令模式

在底线命令模式中,基本的命令有(已经省略了冒号):

  • q 退出程序

  • w 保存文件

按ESC键可随时退出底线命令模式

 

 

流程

vim 文件名 ,输入i编辑,编写完成后退出编辑模式esc,输入:进入底线命令模式,wq保存退出

Vim 按键说明

移动光标的方法 
h 或 向左箭头键(←) 光标向左移动一个字符
j 或 向下箭头键(↓) 光标向下移动一个字符
k 或 向上箭头键(↑) 光标向上移动一个字符
l 或 向右箭头键(→) 光标向右移动一个字符
[Ctrl] + [f] 屏幕『向下』移动一页,相当于 [Page Down]按键 (常用)
[Ctrl] + [b] 屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用)
[Ctrl] + [d] 屏幕『向下』移动半页
[Ctrl] + [u] 屏幕『向上』移动半页
+ 光标移动到非空格符的下一行
- 光标移动到非空格符的上一行
n< space> 那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一行的 n 个字符。
0 或功能键[Home] 这是数字『 0 』:移动到这一行的最前面字符处 (常用)
$ 或功能键[End] 移动到这一行的最后面字符处(常用)
H 光标移动到这个屏幕的最上方那一行的第一个字符
M 光标移动到这个屏幕的中央那一行的第一个字符
L 光标移动到这个屏幕的最下方那一行的第一个字符
G 移动到这个档案的最后一行(常用)
nG n 为数字。移动到这个档案的第 n 行。例如 20G 则会移动到这个档案的第 20 行(可配合 :set nu)
gg 移动到这个档案的第一行,相当于 1G 啊!(常用)
n< Enter> n 为数字。光标向下移动 n 行(常用)

 

搜索替换 
/word 向光标之下寻找一个名称为 word 的字符串。例如要在档案内搜寻 vbird 这个字符串,就输入 /vbird 即可!(常用)
?word 向光标之上寻找一个字符串名称为 word 的字符串。
n 这个 n 是英文按键。代表重复前一个搜寻的动作。举例来说, 如果刚刚我们执行 /vbird 去向下搜寻 vbird 这个字符串,则按下 n 后,会向下继续搜寻下一个名称为 vbird 的字符串。如果是执行 ?vbird 的话,那么按下 n 则会向上继续搜寻名称为 vbird 的字符串!
N 这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。例如 /vbird 后,按下 N 则表示『向上』搜寻 vbird 。

 

指令行的储存、离开等指令 
:w 将编辑的数据写入硬盘档案中(常用)
:w! 若文件属性为『只读』时,强制写入该档案。不过,到底能不能写入, 还是跟你对该档案的档案权限有关啊!
:q 离开 vi (常用)
:q! 若曾修改过档案,又不想储存,使用 ! 为强制离开不储存档案。
注意一下啊,那个惊叹号 (!) 在 vi 当中,常常具有『强制』的意思~  
:wq 储存后离开,若为 :wq! 则为强制储存后离开
:set nu显示行号,设定之后,会在每一行的前缀显示该行的行号
:set nonu 与 set nu 相反,为取消行号!

 

账号管理

用户账号的管理工作主要涉及到用户账号的添加、修改和删除

添加用户账号就是在系统中创建一个新账号,然后为新账号分配用户号、用户组、主目录和登录Shell等资源

添加账号 useradd

useradd 选项 用户名

参数说明:

  • 选项 :

    • -c comment 指定一段注释性描述。

    • -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。

    • -g 用户组 指定用户所属的用户组。

    • -G 用户组,用户组 指定用户所属的附加组。

    • -m 使用者目录如不存在则自动建立。

    • -s Shell文件 指定用户的登录Shell。

    • -u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。

  • 用户名 :

    • 指定新账号的登录名

[root@izuf6hm75axg2u4zfbcctoz home]# useradd -m henr

增加用户账号就是在/etc/passwd文件中为新用户增加一条记录,同时更新其他系统文件如/etc/shadow, /etc/group等

 

 

删除用户

userdel -r 用户名 删除用户时候将他的目录一并删除

 

 

修改用户usermod

usermod -d /home/233 henr

修改之后查看配置文件 cat /etc/passwd

切换用户

1.切换用户的命令为:su username 【username是你的用户名哦】

2.从普通用户切换到root用户,还可以使用命令:sudo su

3.在终端输入exit或logout或使用快捷方式ctrl+d,可以退回到原来用户,其实ctrl+d也是执行的exit命令

4.在切换用户时,如果想在切换用户之后使用新用户的工作环境,可以在su和username之间加-,例如:【su - root】

$表示普通用户

#表示超级用户,也就是root用户

 

root 当前用户 主机名 #表示root用户名

修改主机名,然后重新连接

hostname 名称

用户密码设置

[root@henry home]# useradd -m zhang
[root@henry home]# ls
admin                                 redis      www
apache-tomcat-8.5.47                  staragent  zhang
apache-tomcat-8.5.47-windows-x64.zip  t2
[root@henry home]# passwd zhang
Changing password for user zhang.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.

 

root用户设置密码

passwd username
新密码
确认密码

普通用户

passwd
旧密码
新密码
确认密码

 

锁定账户

passwd -l zhang  # 锁定zhang
passwd -d zhang  # 将zhang的密码清空,并锁定

锁定之后就不能登录了

 

用户组管理

每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理

用户组的管理涉及用户组的添加、删除和修改。组的增加、删除和修改实际上就是对/etc/group文件的更新

增加一个新的用户组groupadd

 

可以指定用户组的id group -g xx groupname

 

 

删除用户组 groupdel

[root@henry /]# groupdel newhen
[root@henry /]# cat /etc/group

 

修改用户组的权限信息和名字

[root@henry /]# groupmod -g 9419 -n xy1 xy2
[root@henry /]# cat /etc/group

修改xy2的id为9419 name为xy1

 

用户切换组

# 登录当前的用户
$ newgrp 组名

一般来说是在创建用户时候,useradd指定-G用户组

 

/etc/passwd

[root@henry /]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell

登录口令,真正加密后的密码存在 /etc/shadow中

 

磁盘管理

df 列出文件系统整体的磁盘使用量

df [-ahikHTm] [目录或文件名]

选项与参数:

  • -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;

  • -k :以 KBytes 的容量显示各文件系统;

  • -m :以 MBytes 的容量显示各文件系统;

  • -h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;

  • -H :以 M=1000K 取代 M=1024K 的进位方式;

  • -T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;

  • -i :不用硬盘容量,而以 inode 的数量来显示

 

 

# 将 /etc 底下的可用的磁盘容量以易读的容量格式显示
[root@henry home]# df -h /etc
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  8.7G   29G  24% /

du 检查磁盘空间的使用量

du [-ahskm] 文件或目录名称

 

选项与参数:

  • -a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。

  • -h :以人们较易读的容量格式 (G/M) 显示;

  • -s :列出总量而已,而不列出每个各别的目录占用容量;

  • -S :不包括子目录下的总计,与 -s 有点差别。

  • -k :以 KBytes 列出容量显示;

  • -m :以 MBytes 列出容量显示;

# 检查根目录底下每个目录所占用的容量
[root@henry home]# du -sm /*
5312    /usr #  系统初期最大
456     /var
2307    /www


磁盘挂载与卸除

挂载:mount

 

 

卸载:umount [-fn] 装置文件名或挂载点

选项与参数:

  • -f :强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;

  • -n :不升级 /etc/mtab 情况下卸除。

umount /dev/kuangshen

 

进程管理

什么是进程

  1. 在Linux中,每一个程序都是有自己的一个进程,每个进程都有一个id号

  2. 进程有两种存在方式:前台和后台

  3. 一般的话服务都是后台运行的,基本的程序都是前台运行的

命令

ps 查看当前系统中正在执行的各种进程信息

ps -xx

  • -a 显示当前终端运行的进程信息(一个)

  • -u 以用户的信息显示进程

  • -x 显示后台运行进程的参数

# ps -aux 查看所有进程
ps -aux|grep mysql
ps -aux|grep redis


# | 叫做管道符
# grep查看文件中符合条件的
[root@henry home]# ps -aux|grep mysql
root      7949  0.0  0.0 113264  1604 ?        S    Jan19   0:00 /bin/sh /www/server/mysql/bin/mysqld_safe --datadir=/www/server/data --pid-file=/www/server/data/izuf6hm75axg2u4zfbcctoz.pid
mysql     8553  0.0  9.5 1015196 180656 ?      Sl   Jan19   1:07 /www/server/mysql/bin/mysqld --basedir=/www/server/mysql --datadir=/www/server/data --plugin-dir=/www/server/mysql/lib/plugin --user=mysql --log-error=izuf6hm75axg2u4zfbcctoz.err --open-files-limit=65535 --pid-file=/www/server/data/izuf6hm75axg2u4zfbcctoz.pid --socket=/tmp/mysql.sock --port=3306
root     21808  0.0  0.0 112660   976 pts/0    R+   11:41   0:00 grep --color=auto mysql
[root@henry home]# 
 

ps -ef 可以查看到父进程的信息

ps -ef|grep mysql 


# 看父进程一般可以通过目录结构树来查看
pstree -pu
# -p 显示父id
# -u 显示用户组

 

 

结束进程

kill -9 进程的id

 

环境安装

 

JDK安装(rpm)

  1. 下载JDK rpm https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

  2. 安装java环境

    # 检测系统是否存在java环境 java -version
    # 如果有的话需要卸载
    rpm -qa|grep jdk # 检测信息
    rpm -e --nodeps xx
    ​
    # 卸载完毕后可安装Jdk
    rpm -ivh rpm包

     

    检查

    [root@localhost /]# java -version
    openjdk version "1.8.0_181"
    OpenJDK Runtime Environment (build 1.8.0_181-b13)
    OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
    [root@localhost /]# rpm -qa|grep jdk
    copy-jdk-configs-3.3-10.el7_5.noarch
    java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64
    java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el7.x86_64
    [root@localhost /]# rpm -e --nodeps java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64
    [root@localhost /]# rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el7.x86_64
    [root@localhost /]# java -version
    -bash: /usr/bin/java: No such file or directory

    安装

    [root@localhost home]# rpm -ivh jdk-8u281-linux-x64.rpm 

     

     

配置环境变量

vim /etc/profile

在文件最后面增加java的配置

JAVA_HOME-/usr/java/jdk1.8.0_281-amd64
CLASSPATH=%JAVA_HOME%/lib;%JAVA_HOME%/jre/lib
PATH=$JAVA_HOME/bin;$JAVA_HOME/jre/bin
export PATH CLASSPATH JAVA_HOME

之后可以部署项目,首先需要放行端口

# 查看已开启的端口
[root@localhost home]# firewall-cmd --list-ports
# 开启8080端口
[root@localhost home]# firewall-cmd --zone=public --add-port=8080/tcp --permanent
[root@localhost home]# service firewalld restart
[root@localhost home]# firewall-cmd --list-ports
8080/tcp
[root@localhost home]# java -jar helloSpringboot.jar

 

Tomcat安装(解压)

war包需要放到tomcat中运行

  1. 下载tomcat apache-tomcat-8.5.61.tar.gz

  2. 解压缩这个文件

    tar -zxvf apache-tomcat-8.5.61.tar.gz

     

  3. 启动tomcat ./xxx.sh 脚本

    startup.sh  # 启动tomcat
    shutdown.sh # 关闭tomcat

     

     

确保Linux的防火墙端口是开启的,如果是阿里云,需要保证阿里云的安全组策略是开放的

# 查看firewall服务状态
systemctl status firewalld
​
# 开启、重启、关闭、firewalld.service服务
# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
​
# 查看防火墙规则
firewall-cmd --list-all    # 查看全部信息
firewall-cmd --list-ports  # 只看端口信息
​
# 开启端口
开端口命令:firewall-cmd --zone=public --add-port=80/tcp --permanent
重启防火墙:systemctl restart firewalld.service

 

 

Docker(yum安装)

安装手册:https://docs.docker.com/engine/install/centos/

在Linux执行,一定要联网,yum在线安装

安装

  1. 检测Centos 7

    [root@localhost bin]# cat /etc/redhat-release
    CentOS Linux release 7.6.1810 (Core) 
  2. 安装准备环境

    yum -y install 包名 # y表示所有的提示为y
    yum -y install gcc
    yum -y install gcc-c++
  3. 卸载旧版本

    yum remove docker \
              docker-client \
              docker-client-latest \
              docker-common \
              docker-latest \
              docker-latest-logrotate \
              docker-logrotate \
              docker-engine
  4. 安装软件包

    yum install -y yum-utils device-mapper-persistent-data lvm2
  5. 设置镜像仓库

    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  6. 更新yum软件包索引

    yum makecache fast
  7. 安装Docker CE

    yum -y install docker-ce docker-ce-cli containerd.io
  8. 启动docker

    systemctl start docker
  9. 测试

    docker version
    ​
    docker run hello-world
    ​
    docker images

     

     

推荐阅读