相关概念

Symbolic links

Symbolic links/soft links可以理解成为一个快捷方式,跟mac GUI右击出来的alias有着很类似的功能,但是比alias要更加的底层一些。Softlink 即可以针对文件也可以针对文件夹进行创建。

通过ln -s target/file/or/dir link/path来创建。我创建了针对文件和文件夹的softlink和alias,通过命令可以观察它们之间的区别。

1
2
3
4
5
6
7
8
9
10
$ ls -lo@
total 3024
-rwxr-xr-x 1 zhengyi 2723 May 24 08:20 build.sh
-rw-r--r--@ 1 zhengyi 257136 May 25 20:49 build.sh.alias
com.apple.FinderInfo 32
lrwxr-xr-x 1 zhengyi 8 May 25 20:49 build.sh.link -> build.sh
drwxr-xr-x 9 zhengyi 306 May 25 20:24 src
-rw-r--r--@ 1 zhengyi 1268908 May 25 20:40 src_alias
com.apple.FinderInfo 32
lrwxr-xr-x 1 zhengyi 4 May 25 20:39 src_link -> src/

我们可以看到softlink是通过文件信息来识别的,而alias是通过拓展属性来进行实现的,也就是说alias只有在apple 的Finder下有用,在其他地方他就是一个普通的文件。

如果我们链接到一个目录的话,alias因为是一个文件自然不能够cd进去,而softlink是可以cd进去的。

Hard link

与softlink相对应,与softlink不同,hardlink不是一个“快捷方式”,而是一个真实存在的文件。文件可以理解成磁盘上一块内存,而我们在终端和GUI看到的“文件”只是指向了那块内存,所以我们可以有多个”文件”指向同一块内存。这就是hardlink干的事情。hardlink是不允许针对一个目录创建的,因为这样会破坏文件系统的结构。

常用参数

-f - 将覆盖目标文件,并不做提示。
-n - 不覆盖目标文件。
-r - 这个是历史版本的递归拷贝,不推荐使用。
-R - 如果源文件是一个目录的话,递归拷贝到目标路径。如果源文件以/结尾,那么源文件夹里的内容将被拷贝到目标路径,如果不指定则是拷贝整个文件夹。
-H - 与-R配合使用,保持原有的softlink。
-P - 与-R配合使用,不保持原有的softlink,这个是递归拷贝的时候默认的选项。
-v - 与-R配合使用,打印出所有被拷贝的文件。
-p - 将保护原始文件的修改时间、访问时间、flie flag,文件模式等信息。

具体场景

拷贝单个文件

1
cp file1.txt ../file2.txt

拷贝多个文件

1
cp file1.txt file2.cpp file3.cs test/src

拷贝符合某个文件名规则的文件

cp支持简单的通配符。

1
cp *.zip package

拷贝整个目录,包括子目录,并维持文件的修改时间不变

1
cp -RpH dir1 dir2/src

基本用法

ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]

ls 后面可以跟0~N个参数,最后可以跟0~N个文件名。

文件名支持通配符,可以进行简单的文件名搜索。如果匹配到目录的话,会将目录中的子项目一同打印出来。

相关概念

通配符规则

* (星号通配符)

匹配0~N个任意字符。

?(问号通配符)

匹配1个任意unicode字符。

[char] (方括号通配符)

匹配1个方括号内任意的一个字符。

括号中的字母可以使用POSIX 字符集(POSIX Character Classes),包含以下几种。我只列出了认为比较常用的,详见http://man7.org/linux/man-pages/man7/glob.7.html

表达式 解释
[a-z] 小写a到z
[A-Z] 大写a到z
[0-9] 数字0到9
[:alnum:] Alphanumeric字符,表示拉丁文和阿拉伯数字[4]
[:alpha:] Alphabetic characters,拉丁文
[:digit:] 数字
[:upper:] 大写的拉丁文
[:lower:] 小写的拉丁文
[:blank:] ASCII 空格或制表符
[:space:] ASCII 空格

使用方法

[[:alpha:]]*,匹配以字母开头的字符串。

[!char](方括号通配符)

通过在第一位加!表示匹配不包含方括号之内的字符

常用功能

-A - 列出目录下除了...以外的所有文件。
-a - 列出目录下所有文件,包括目录以.开头的文件。
-d - 仅打印出目录名字,不去打印内部的文件。
-l - 打印长格式,包含
-G - 彩色输出。
-p - 如果为目录,在显示名称后面打印一个’/‘
-r - 根据目前输出默认的排序逆序。
-O - 打印出File Flag

长格式

I            II  III      IV       V  VI           VII
drwxr-xr-x   9   zhengyi  group   306 May 24 08:24 .
drwxr-xr-x  42   zhengyi  group  1428 May 23 23:20 ..
-rw-r--r--@  1   zhengyi  group  6148 May 24 08:24 .DS_Store
-rwxr-xr-x   1   zhengyi  group  2723 May 24 08:20 build.sh
-rw-r--r--   1   zhengyi  group   883 May 24 08:19 db.json
-rw-r--r--   1   zhengyi  group  2281 May 24 08:20 gen.py
drwxr-xr-x   2   zhengyi  group    68 May 24 08:18 lib
drwxr-xr-x   7   zhengyi  group   238 May 24 08:25 src
drwxr-xr-x   4   zhengyi  group   136 May 24 08:18 tests

I:文件权限信息,详见下图。如果有@符号,表示这个文件有一些拓展属性,可以通过添加-@参数查阅,也可以使用xattr工具来查看具体信息[1]
II:链接计数(link count),包括hard linkssymbolic links,还有目录引用。当前目录的.会引用自己,同时它的所有的子目录都会持有一个..指向当前目录。这就导致了目录的链接计数往往比较大。
III:owner name
IV:owner group
V:文件大小,单位为字节
VI:最后修改日期
VII:文件名

Access right in the first column
[2]

具体案例

设置默认的别名(alias)

个人喜好将输出搞的彩色一点,比较明显能看出文件的类别

alias ls='ls -G'

列出文件夹下所有的子文件夹

ls -d */

按照最后修改时间排序

ls -l -t -T (新修改的在前)
ls -l -t -T -r(老修改的在前)

根据文件大小排序

ls -l -S (从大到小)

参考资料

  1. “ls” on Mac and extended file attributes
  2. permission gif
  3. Wildcard - 1
  4. Wildcard - 2
  5. Alphanumeric - Wikipedia

阅读更多

Mac/Linux 命令学习

干嘛要学命令

切换到mac下工作有一段时间了,难免要在终端中做一下操作,目前掌握的一些比较简单的命令行有时已经难以驾驭一些比较复杂的操作了。有必要系统得过一遍主要的一些命令。

除了装逼意外,命令行还在有很多好处:

  1. 打字的速度和准确性远远高于鼠标,频繁的切换鼠标和键盘是一件挺麻烦的事情。
  2. 命令行可以写成脚本自动化一些操作,懒人的福音。
  3. 在一些服务器的环境下只能使用命令行。

如何学命令

Learning by doing 是最好的方式,特别是对这种实用性的东西,不动动手是绝对不行的。我觉得学习命令行比较好的方式是:

  1. 通读一遍man,知道一个命令能够做的事情,即使记不住也没关系,至少知道可以做,等需要的时候再看具体的细节也不迟。终端下的man不方便阅读的话可以通过Dash等工具来阅读。
  2. 对于平时可能用到的,自己动手敲一遍看看效果。
  3. 设想几个可能比较常用的场景,然后利用命令来完成这些任务。以后碰到这几个场景的时候可以查阅回忆。

第三点其实是借鉴了tldr(too long don’t read)具,可以理解成是一个简化版的man。

Mac 10.3+ 系统下默认的shell是bash[1],大部分命令的效果和linux下面相同,某一些命令的具体参数和行为有所差异。

小技巧

每日一贴

目录操作

文件操作

文本操作/过滤器

  • sort
  • uniq
  • grep - 2016年6月6号
  • fmt
  • pr
  • head
  • tail
  • tr
  • sed
  • awk

调试

  • dtruss

其他

  • xargs

相关概念

参考资料

  1. What are the differences between using the terminal on a mac vs linux?

  2. Linux Command

引子

今天读完了《精进》这本书,可以说在读的过程中确实领悟到了很多作者想要表达的一些观点。也有一些自己的思考,也学到了一些新的知识点,也有一些醍醐灌顶的时刻。但是当我合上这本书的时候,我问自己这本书讲了什么主要的观点?我竟回想不起多少内容。

有种极度恐惧的感觉,因为自以为花了一些时间认真阅读了这本书,在读书的过程中也做了一些简单的笔记,并把读书过程中的一些想法记录了下来。但是读完却发现所记住的东西甚少,或者说可以提取出来的东西甚少。也许这些知识在大脑中的某一个地方待着,但是我无法通过这本书与其联系起来从而提取出来。

当我慌的时候,我去上网进行了搜索了“如何读书 有效”,“读书 容易忘”。对于搜索到的结果也只是匆匆地进行了阅读,寄希望于能够从中找到一个两个好的办法能够帮助我获得更好的阅读效果。

这个行为明显是不明智的,去搜索关于如何阅读一本书的资料没问题,但是在这个觉得慌张的时候别人的观点往往不能够很好地帮助到你。特别是你抱着一个很功利的心态去试图获取一个复杂问题的简单解决方案的时候,往往不能够得到一个好结果。

反思

这个时候应该做的就是想现在这样,安静的进行思考。因为对于自己阅读中的问题,自己其实是最清楚的,可以观察自己的阅读行为来找出一个适合自己的方法。即使找不到也可以想一个可行的方案去做。能够想到这个层面,从某种角度上说明了这本书的阅读有一定的效果,作者的某一些观点虽不能够完全的表达出来,但也已经对我的想法产生了影响。也许即使你想不起来这本书讲了哪些具体的东西也没关系,可能你已经将这些观点用自己的方式记住了,在将来的某个时间点碰到某个问题的时候能够提取出来。

那么这个问题的关键就从如何在阅读完一本书以后想起来这本书的具体内容,变成了如何将作者的观点转化成自己的想法。那么阅读中的思考就变得非常的关键,有思考才能将自己已有的知识与其发生联系。

阅读的方法

我觉得阅读的时候可以尝试的阅读方法有一下几种:

  1. 初次阅读的时候,最好带有目的性的去阅读。即希望从书中获得什么知识,希望作者帮助你解决那些困惑。带着疑问去读会让你更加容易把读到的知识和已有的知识进行联系。
  2. 序和前言最好要读,接着就是目录。要在读之前对于章节的结构有一个大概的认识。
  3. 阅读的过程中不要过多的进行标注重点,适当的在读到有感悟的时候在书上做笔记。阅读的时候备好纸笔,当有一些想法从大脑中迸发出来的时候,及时的记录下来,然后回去继续阅读。
  4. 读的时候如果走神的话马上停止阅读,走神的阅读纯属浪费时间。
  5. 频繁的对自己读到的文字进行简单的总结,特别是在每节、每章之后,想想作者想表达的是什么?作者前后文之间的逻辑。
  6. 有条件的话,在阅读完一章以后在脱离书本的情况下回想一下这一章讲了什么,有什么知识点以及之间的联系。可以画图、写字、形式不限。
  7. 如果喜欢可以跳着读。
  8. 读完全本,合上书本,极力回想。然后去重新翻一下书本/每章做的笔记,做一下思维导图。
  9. 如果有必要快速重读一遍,在觉得重要的章节进行深度阅读。我觉得重读最好不要在读完一遍之后马上进行,而是隔上一段时间再进行。这会有更好的效果。
  10. 重复5~10。

阅读的作用

顺便理一理下关于阅读作用的想法

  1. 纯属娱乐。
  2. 希望作者能够帮助解决某个疑问、问题。
  3. 希望从书中汲取某一个领域的知识。
  4. 在阅读的过程中进行思考进而产生新的想法、疑问等。
  5. 可以看到到更多不一样的世界和可能性。

Coursera经典课程Learning how to learn第二周学习笔记。

第二周所有内容都是围绕着Chunking这个概念所展开的,chunk这个单词中文为组块,感觉没有英文来的形象。

下面回顾几个我认为比较重要的点。

什么是Chunk及其作用

Chunk可以理解成某一个知识在你大脑中形成的一个记忆块,这个记忆块是对于一些具体的知识进行压缩过的一个结果。课程中将这个chunk比喻为一个压缩文件,我倒是认为这个chunk理解成某一些具体知识的概要/精华更加的妥当。

当你把一些复杂的知识压缩成一个相对较小的概念的时候,你就可以思考更多的问题。举个实际的例子,就是当你需要选择一个排序算法的时候,你考虑的是各个排序算法的特征、优缺点、局限性。而这些信息我认为就是一个具体排序算法的chunk,当你需要实现某一个算法的时候你只需要顺着这个chunk往下思考一下,或者推理一下就可以把具体的算法细节推理出来了。我认为只有你对一个排序算法有深刻的理解以后才会产生这种chunk,否则这些优缺点对于你来说并不会显得那么的自然。

正如上面的例子中看到的,chunk最大的作用就是可以允许你在一个更高对问题进行思考而不需要在意一些细节。当一些小的chunk进行重新整合的时候你可能就会得到一个更高层次的chunk,从而可以帮助你从更高的层面去考虑问题。这个就是思考问题的高度。

如何形成一个chunk

以下几个步骤可以帮助形成一个chunk:

  1. 高度集中注意力的情况下进行学习。(focused attention)
  2. 理解问题。(understanding of the basic idea)
  3. 刻意练习。(practice)
  4. 注意知识的上下文,而非仅仅关注知识点本身。(sense of big picture)

这几个步骤应该都不会陌生,这里特别强调一下最后两个的重要性。做练习是测试自己是不是真的理解的一个重要途径。对于一些特殊的领域比如编程,自己写一遍代码绝对是会对问题的理解程度上一个台阶的。前提是你要合上材料,靠自己的理解和记忆写一个出来,这能够帮助你重新思考和推理一遍这个过程。

最后一个是说要注意只是的上下文,这个更多的是帮助我们把这个知识放在一个更大的层面去考虑,将其与其他的一些已有的知识进行比较、联系从而增加这个知识的理解深度。

几种错误的学习方法

课程中提到了几个比较错误的学习方法,这些学习方法往往会让学习者产生一种自己已经掌握了这些知识的错觉。这几个方法包括:

  • 在课本上划出很多很多的重点
  • 反复的去读一段材料
  • 学习完以后做一个概念导图

这些方法其实更多的是在形式层面进行重复和巩固的,而不是从思维上进行巩固。

集中高效的学习方法

应对上面错误的方法,下面这些方法可以帮助我们更好地学习掌握一门知识。

  • 在学习完一段材料以后,在不看笔记和材料的情况下尽可能的去回想学过的知识,在脑子里过一遍自己记住的一些知识点。尽力回顾完以后,再去巩固那些你已经忘记或不确定的知识点。反复几次。
  • 在不同的地方回想会帮助你摆脱一些环境上的暗示。
  • 着重去练习那些自己不熟悉的知识点,而不是反复做那些已经会的练习。
  • Interleaving learning。这个概念是说在学习一个领域的知识的时候,可以选择多个知识点交替的学习。这样会让你拥有更高的学习效率,虽然说学习者本身可能没发觉。比如说,学习羽毛球的时候,不需要说学习完发球以后再学习扣杀,可以学一段时间发球,然后去学扣杀,接着再回来学发球。这会让你能够在不同点之间的经验共享。

关于思维导图(个人观点)

上面的错误的学习方法中提到了一个concept mapping的东西,这个我觉得跟思维导图很像。思维导图看上去是一个帮助记忆的方法,但是我觉得如果用得不对的话其实也是错误的。

我觉得正确的方法是在看完一本书,或学习完一段知识以后。脱离开来材料,靠脑子回想知识点以及知识点之间的联系,然后借助思维导图这个工具把这些联系个表达出来。这就是上面我所说的回想的那个过程,只是说把脑子里的“chunk”通过思维导图的形式表达出来而已。思维导图中各个点之间的联系可以跟书本上的联系不一样,但是一定是要你脑子里真实的联系,否则的话下次你看到这个思维导图就不能够快速回想起这些内容。

几个问题

依然有以下几个问题没有得到很好的答案。

  1. 如何克服思维定势?
  2. 如何利用好diffuse mode?

Learning how to learn week 2 mindmap