几道题目:Git、Linux、密码和正则

给前东家的小伙伴们出的题一共两套,这第二啪主要内容是 git、linux、密码和正则。

另外由于前一啪被前东家的大佬 @HUGE 表示「不要讲故事」,因此这一啪没有过多预设的情景,更加简洁一些。

Git:如何开始

题目 1

特别萌萌哒的 $天骄 要在本地新创建一个 git 仓库「read-card」,他应该:

题目 2

特别善于协作的 $天骄 要从服务器上拉取一个 git 仓库「read-card」,他应该:

解答

使用 Git 来管理一个项目时,无非三种情况:

  1. 项目已经存在于服务器
  2. 项目在本地已经开发了一部分
  3. 项目尚未开始

克隆

对于第 1 种情况,项目已经存在于服务器,对应的是题目 2 中的情形。

这时候,我们需要从服务器上把既有项目「复制」到本地进行开发,这个过程称为「克隆」,对应的命令是 clone,语法主干如下:

git clone <repository> [<directory>]

如果只提供远程仓库路径 repository,那么会在当前路径下新建一个和远程仓库所在位置同名的子文件夹,并将仓库内容克隆到其中。也可以指定目标文件夹 directory 来将 git 仓库的内容克隆到特定文件夹中。

初始化

剩下两种情况对应的操作都是与服务器无关的,对应的是题目 1 中的情形。

在本地新建一个仓库时,无论当前路径下是否已有文件,都可以执行「初始化」 init 命令,语法主干如下:

git init [directory]

直接执行 git init 后,当前路径下会创建一个 .git 文件夹,里面包含了 git 仓库的信息。如果指定文件夹参数 directory,那么会在这个文件夹中创建 .git 文件夹。

因此,如果要让一个已经存在的 git 仓库脱离 git 管理,直接在项目根目录删除 .git 文件夹即可。

此时如果项目已经在开发中,那么可以继续执行 add 命令来把文件添加到仓库中。

彩蛋

题目 1:init 后都没跟仓库名,容易被首先排除
题目 2:唯一一个带着远程地址的,真·送分

Linux:删除我自己

题目 1

特别喜欢 Linux 的 $天骄 在终端中输入了下面的命令:

cd ~/sanko
rm -rf .

这个命令的执行结果是:

  • sanko 文件夹整个被删除了
  • sanko 文件夹下的所有内容被删除了,但是 sanko 文件夹本身没有被删除
  • sanko 文件夹下的文件被删除了,但是子文件夹和 sanko 文件夹本身没有被删除
  • 系统报错,执行失败

题目 2

特别喜欢 Linux 的 $天骄 在终端中输入了下面的命令:

rm -rf sanko

这个命令中,-r 代表(这是一道英文送分题):

  • Attempt to remove the file hierarchy rooted in each file argument.
  • Attempt to remove the files without prompting for confirmation, regardless of the file’s permissions.
  • Attempt to remove directories as well as other types of files.
  • Attempt to undelete the named files.

解答

曾有前同事在虚拟机中尝试执行:

rm -rf /

执行后我们发现,除了部分文件删除失败外,系统中的文件基本全部被删除了,同时系统也逐渐变得不稳定。

这个命令常用来删除文件夹,其中 rm 是一个删除程序,-r 参数用来递归删除子文件夹中的内容,-f 参数可以跳过人工确认而直接删除所有文件。

无法删除

对题目 1 中直接删除当前工作目录的做法,rm 程序给出的提示是:

rm: refusing to remove “.” or “..” directory: skipping “.”

总之,执行失败,没有删除任何文件。

难以理解

题目 2 显然是一道送分题。这几个句子的含义和出处分别是:

英文 译文 (谷歌翻译) 人话版本 出处
Attempt to remove the file hierarchy rooted in each file argument. 尝试删除以每个文件参数为根的文件层次结构。 递归删除子文件夹中的内容 rm 的 -r 选项,即 –recursive
Attempt to remove the files without prompting for confirmation, regardless of the file’s permissions. 无论文件的权限如何,都尝试删除文件而不提示确认。 强制删除 rm 的 -f 选项,即 –force
Attempt to remove directories as well as other types of files. 尝试删除目录以及其他类型的文件。 即使没有指定 -r 选项,也把空文件夹一并删除 rm 的 -d 选项,即 –dir
Attempt to undelete the named files. 尝试取消删除指定的文件。 (不要管我) macOS 系统中 rm 的 -W 选项

彩蛋

题目 1:与那么三大段最终结果相比,结果大概不像是执行失败
题目 2:这个题目出得好啊,即使确切知道 -r 的含义,由于都没有提到 recursive 一词,依然不容易选对。事实上这个描述来自 macOS 上的 rm 命令手册,但不影响解题

Linux:遇见 Vi

题目 1

特别喜欢 Linux 的 $天骄 自然喜欢高端大气上档次的 vi 编辑器,改完代码之后保存并退出编辑器的正确方式是:

  • 输入 :wq 回车
  • 按 Ctrl+C
  • 按 Ctrl+Z
  • 输入 :quit 回车

题目 2

特别喜欢 Linux 的 $天骄 自然喜欢高端大气上档次的 vi 编辑器,查看代码时向下滚动一行应该按:

  • 字母 n
  • 字母 j
  • 字母 l
  • 右方括号 ]

解答

有人说,如果想在键盘上敲出一个随机字符串,那么就让一个新手程序员来尝试退出 Vi 吧。

不过 Vi 的基本操作同样也使用在了 manlessgit 等其他 Linux 命令中,甚至应用到了 Gmail 等众多的网页产品中。

要保存并退出一个文件,首先按 ESC 键确保进入到命令模式并清除既有命令,之后输入 :wq 并回车即可,含义是 write 与 quit。选项 D 中的命令 :quit 等价于 :q,没有保存、只有退出,当文件修改过后执行会失败。

要移动光标,基本操作是使用 h j k l 四个按键。这里向下移动一行应该使用 j

彩蛋

一本正经地讲,Ctrl+C 和 Ctrl+Z 毕竟也多多少少有「退出」的功能在,这是正儿八经的干扰项。
但是拿右方括号翻页,这真的不是中文输入法!

Linux:常用命令

题目 1

特别喜欢 Linux 的 $天骄 想在当前目录下新建一个空白文件 sanko.txt,他可以:

  • touch sanko.txt
  • less sanko.txt
  • new sanko.txt
  • cat sanko.txt

题目 2

特别喜欢 Linux 的 $天骄 想要重命名文件 a.txtb.txt,他可以使用下面哪个命令(多选):

  • mv a.txt b.txt
  • cp a.txt b.txt
  • rename a.txt b.txt
  • duplicate a.txt b.txt

题目 3

特别喜欢 Linux 的 $天骄 想要在文件 a.txt 后面加个署名,他可以:

  • echo “sanko” => a.txt
  • echo “sanko” -> a.txt
  • echo “sanko” >> a.txt
  • echo “sanko” > a.txt

解答

touch 一个不存在的文件,可以创建指定文件名的空文件。

less 可以用来以文本方式读取文件,more 也可以。

不存在 new 命令。

cat 也是用来读文本的,但会直接全文打印出来。

mv 意为「移动」,但是非常灵活:mv 文件到原目录则相当于重命名;目标为目录时意为移动到目录下,否则就是移动成为该文件。

cp 意为「复制」,同样非常灵活,源和目标都可以是文件或文件夹。

rename 可以批量重命名,题目 2 也可以用 rename 来实现:

rename a b a.txt

表示把 a.txt 中的 a 替换成 b

不存在 duplicate 命令。

>>> 是重定向操作,可以把左边的输出重定向到右边的文件中。> 是覆盖,而 >> 是在文件末尾添加。

重定向时不存在 ->=> 符号。

彩蛋

为了效果,生生造出了 newduplicate 这些命令,更是牛逼哄哄地造出了 ->=> 符号。

加密、摘要和编码

题目 1

特别痴情的 $天骄 今天听说了 base64 算法,他给女票写了封小情书,然后使用 base64 算法把情书变成了一页天书。 $天骄 的女票收到天书后:

  • 能够直接得到情书原文
  • 需要 $天骄 的密钥才可以得到原文
  • 无论如何不能得到情书原文

题目 2

特别痴情的 $天骄 今天听说了 sha1 算法,他给女票写了封小情书,然后使用 sha1 算法把情书变成了一页天书。 $天骄 的女票收到天书后:

  • 能够直接得到情书原文
  • 需要 $天骄 的密钥才可以得到原文
  • 无论如何不能得到情书原文

题目 3

特别痴情的 $天骄 今天听说了 aes 算法,他给女票写了封小情书,然后使用 aes 算法把情书变成了一页天书。 $天骄 的女票收到天书后:

  • 能够直接得到情书原文
  • 需要 $天骄 的密钥才可以得到原文
  • 无论如何不能得到情书原文

解答

加密算法

英文叫 Cypher,别名密码算法,一定是有一个对应的解密算法的,并且这两个算法必须使用匹配的密钥才可以正常运作。

这个密钥可以是一样的(对称加密),也可以是不同的(不对称加密),前者典型如 AES,后者典型如 RSA。

情书称为原文,天书称为密文,所谓加密,必能解密,但必须有密钥,否则极难解开。

摘要算法

英文叫 Hash,又称散列函数,音译哈希算法,常见如 MD5、SHA1。

情书称为消息,天书称为摘要,所谓摘要,就是从消息文本中提取一部分,能代表消息原始文本,又比原始文本简短得多。

既然是摘要,自然不能复原,只能用作识别。收发双方核对摘要,女票可以检查情书有没有被别人掉包。

编码算法

英文叫 Encoding,Base64 是其中一种,它提供了使用 ASCII 字符编码二进制数据流的方案。

使用 64 种 ASCII 字符,令二进制的字节流也可以在仅支持文本的通信协议中传输。所谓编码,就是换了一种形式存在,通过解码,立刻就得到还原。

经过编码,人类肉眼不能直接读取,也就提供了一些「保密」的趣味。

彩蛋

狗粮收好不谢。

正则表达式:文件名

题目 1

特别爱动脑筋的 $天骄 拿到了一段文本:

iwant_123564.txt_556688.txt

他用正则表达式:

\d\d\d{4}.txt$

能够只把 556688.txt 匹配出来吗?

  • 不能

题目 2

特别爱动脑筋的 $天骄 拿到了一段文本:

iwant_.txt_556688.txt

他用正则表达式:

[0-9]*\.txt

能够只把 556688.txt 匹配出来吗?

  • 不能

解答

分析一下题目 1 中的正则式:

\d\d\d{4}.txt$

\d 表示数字,与 [0-9] 等价。\d\d 是两个数字,\d{4} 是 4 个数字,共 6 个数字。. 表明任意字符,$匹配文本结束。

连起来,就是:

6个数字 + 1个任意字符 + txt 而后文本结束

原始文本中,556688.txt 符合前面的匹配规则,并且是唯一符合的。

不能

分析题目 2 中的正则式:

[0-9]*\.txt

[0-9] 表示 0-9 之间的任意单个字符,星号 * 表示任意个前面的字符,\ 是转移符号,\. 表示明确的小数点。

连起来,就是:

任意个 0-9 之间的数字 + 小数点 + txt

这里星号表示的「任意个」,是 0 个、1 个或多个。

在原始文本中,有两个子串符合要求。一个是 556688.txt,6个数字,还有一个是 .txt,0个数字。

彩蛋

这题来自于我在处理一系列文件重命名时的替换过程。
题目 1 中,有人会觉得 . 必须写成 \.,其实不必,小数点本身也是「任意字符」之一。
题目 2 中,星号代表的数量是 0 以上,而加号用来代表 1 以上的数量。