哈工大软件构造实验一个人心得(2020春季)
写在前头:
这是本人在完成实验一过程中,对遇到问题的总结、反思和心得。由于本人水平有限,难免有不全面或不准确的记录,欢迎读者批评指正。
写此博客的初衷是为了混分和给自己根据每次的实验进度留作学习记录,可能对读者来说未必有良好的阅读体验,毕竟不是将特定的问题提炼出来发布在独立的博客中。但愿这份阅读能让你有所收获。
文章目录
1. git在实验中的使用
git是应用十分广泛的版本控制工具,可以方便地管理工作,分享进度,整合项目等。
1.1 git的命令小结
git add, git commit 和git status都是最最最基础的命令,要使用git就几乎离不开他们。
工作中最实用的是git add -u命令。
git对仓库里的每个文件都有追踪,记录他们的去向。对于那些在仓库中从未出现过的文件,git仓库不会记录他们的改变。对于第一次要推送到暂存区的文件,必须要用git add命令一点点提交。但是一旦commit了这个文件,这个文件就被记录,直到你用rm 命令将其从仓库中删除(删除文件其实也是一种对仓库的修改,会保存在staged暂存区,提交后生效)都会一直记录它的改变。使用git add -u可以快速地检查已经追踪的文件是否发生变化,如果变化则将改变的文件提交到暂存区。
使用git clone将指定url的远程仓库克隆到当前目录下,可以输入参数来改变生成的默认目录名。
如果想要让版本回滚,那么必须知道对应的commit序列号,或者至少知道一部分。此时git log命令就发挥了作用,这条命令将使得该仓库的版本日志显示到终端窗口上。找到对应commit的id,然后用git reset <commit id>命令来回滚到那个版本。如果你让版本回滚到过去的某个版本,此时再git log时这个版本之后的那些commit不会显示。如果你又想要回滚到那些commit,你还可以用git reflog查看命令历史,这个历史包括你的回滚操作。
1.2 与GitHub关联的远程仓库有关的教训
由于是事后才想到记录,所以没能及时记录截图🤬但是教训是真实且深刻的。
如果已经在本地创建了一个git仓库,并且连接并推送到了某个远程仓库,而又突然发现这个仓库的内容很乱很不舒服,或者要改动很多文件,删除很多文件,又懒得用git将需要调整的文件一个个操作,也许会想:可不可以本地再新建一个本地仓库,将其与远程仓库关联,然后推送上去做一个心新的commit和push?我当时就是这么想的。结果很糟糕:git会发现你试图将一个与原本完全不同的仓库推送上去。
假设我尝试先将一个新的空的本地仓库git init 后与远程仓库关联,并尝试推送。其结果是git发现仓库中原本的文件追踪在这个新的本地仓库中都不复存在了,这就使得git不能轻易地这样操作。补救的办法是,将那个远程仓库先pull下来,在此基础上进行修改再提交。也可以在 push时加上-f参数表示强制push,但并不推荐总是忽略人家好心好意设定的规则。
1.3 GitHub的使用知识小总结
虽然GitHub由于众所周知的原因不能方便地访问,但是GitHub成熟的体系,强大的功能和丰富的资源都让它难以替代。
提交SSH公钥到服务器
GitHub支持使用SSH key的连接。只要确保项目的持有者有和你的SSH私钥配对的SSH公钥,你就可以方便快捷地使用SSH的方式连接远程仓库,再也不用体验每次push都要输入账号密码的痛苦。
SSH key用来实现远程客户端登录的机制可以简单概括为:
-
客户端发出登录请求,当然需要给出要登陆的账号的用户名和你的IP
-
服务器查看该用户名下是否有公钥,如果有,将一个特定字符串使用公钥加密后发送给客户端
-
客户端接收到加密的字符串后,使用本地的私钥解密,得到字符串,将其发送给服务器
-
服务器接收确认字符串,如果匹配,则登录成功,将授权信息发送给客户端
所以要使用SSH的前提是,你在自己的电脑上生成了一对SSH公钥和私钥,然后网页登录到GitHub上把公钥放到账户中。
在git bash中输入 ~/.ssh看看有没有这样的密钥,因为有可能你的电脑上已经配置过SSH key了,那样的话不妨直接拿来用。
如果没有的话,使用ssh-keygen -t rsa -C <你的git配置邮箱>
其实关于邮箱这一点,我发现网上关于GitHub SSH key配置的教程都是使用github注册邮箱生成SSH key,但是按理来说,也可以使用其他方法生成SSH key。
连接远程仓库
实验中要推送代码到老师在GitHub classroom上设定的远程私有仓库。设定的Deadline是对于远程仓库而言的,如果你已经在本地完成了任务,也提交到了代码仓库,但是在deadline之前没有把修改提交上去,那就悲剧了。老师只能看到你在deadline之前提交的版本还没有完成任务。
要提交到远程仓库,首先要确保那个远程仓库已经存在。以GitHub为例,注册帐号之后可以新建一个私有的代码仓库
1.4 .gitignore
本地仓库文件夹可能有许多东西是不想提交到仓库中的,比如idea的配置文件、代码的可执行文件等等。如果想要体会git add -a的简便又不想加入没用的内容,使用.gitignore是很好的选择。这是一个记录git默认忽视的文件,加入到这个文件中的文件不会git add -a考虑到。
2. 探索Java:Arrays.sort的玄机
Java是使用人数相当多的面向对象式的编程语言。要想了解一门语言,就不得不从点滴开始记录,了解其实现细节,尤其是对于其中常用而不常被人所了解的部分。
看Java教材提到,Arrays.sort()对实现了comparable接口的对象可以起到高效的排序作用,就想着找机会看一看Java源码中对排序的实现。(以int类型为例)
从前总听说“Java官方的sort实现都是快排”,没想到Arrays.sort()先是调用了另一个方法。
这个排序不得了,有6个参数。再查看这个方法的注释:
参数前三个好理解,分别是要排序的数组,待排序元素的起始位置和结束位置。剩下的参数分别是一个工作数组,按我的理解,这个是提供给方法用来霍霍进行排序操作的额外空间,还提供了工作数组上留给当前方法霍霍使用的空间的起始位置和空间大小。再看方法的简介,原来这是为归并排序准备的方法,难怪需要给出4,5,6号参数了,毕竟归并排序就是要用额外空间的。
方法一开始就先对length做了个判断,
if (right - left < QUICKSORT_THRESHOLD) {
sort(a, left, right, true);
return;
}
这个QUICKSORT_THRESHOLD 的常量在DualPivotQuicksort类中定义为286,从常量的名字不难看出,这是一个用来区分如何使用排序方法的阈值。当数组长度小于286,就调用sort的另一个实现。我想286这个数字应该是无数计算机科学家、资深软件工程师经过理论分析和实践验证得出的吧,也许他们认为286是一个合适的分界点,比这个数字再大就使用归并排序更合适。
且看这个4个参数的sort方法的注释:
还多了一个布尔类型的参数,表示当前排序的部分是否是排序范围中最左的一块。
这个方法的实现,一开始又是熟悉的域值:
if (length < INSERTION_SORT_THRESHOLD) {
if (leftmost) {
/*
* Traditional (without sentinel) insertion sort,
* optimized for server VM, is used in case of
* the leftmost part.
*/
for (int i = left, j = i; i < right; j = ++i) {
char ai = a[i + 1];
while (ai < a[j]) {
a[j + 1] = a[j];