赞
踩
目录
学习编程有两门基础课程,即数据结构和算法。数据结构中网络公开课中评价一直居高不下的就是UCBerckley的数据结构了。数据结构是CS入门的内功心法。就像九阳神功,掌握了内功心法,张无忌再去学习乾坤大魔移,太极拳法等等就能很快的融会贯通。内功不足直接学一些招式可以很快的看到效果。就像梅超风九阴白骨爪,白蟒鞭法摧心掌名震江湖,但内力不足则后劲不足。但这一门伯克利的Data Structure就相当于上卷的九阳神功,主修内力。虽然修炼需要的时间长,却十分值得。
网上传的帖子“3个月学会JAVA,月薪3000到1万!”,“想要转码,这样刷题就对了!”。“我就是普通人,这样学JAVA,3个月跳槽大厂”。让你忍不住点进去看,有些很坑人。朋友们,在错误的道路上行走,你觉得走得很快,此时快就是慢。学习编程不在于用多久学会了java,python。而是在于在对的路上持续行走,在重要的路上扎实推进。这个时候,慢就是快。幂律法则中提出自然界的一大规律呈现二八分布,成甲在《好好学习》中提到将80%的精力投入到此门技术前20%重要的知识上学习,效率是最高的。而“数据结构”就是编程这门技术的前20%最重要的部分。
CS61B主要用java编写,前面几节课课讲述java的语法和用法。后面开始进入数据结构部分,数组,链表,二叉树,图,搜索,排序。其中一部分 与普林斯顿的神课 Algorithms 有重复部分,但普林斯顿的算法课更深一些,跟注重算法的思想的探究。如果是小白,入门编程,先修这一门是不错的选择。
注重实践。这门课的作业和项目很棒。
2020的版本的内容更加丰富,项目有4个,后两个大的project做完后收获很大。一是将A*,Tries,Priority Queue,Map,HashTable 多个数据结构和复杂的搜索算法融合在一起的BearMap。你会实现伯克利校园大小的谷歌地图,完成地图查询,道路搜索,路径指引。 第二个大的project是 设计一个游戏Build your Own World,这个项目不需要fancy的数据结构和算法,主要锻炼你handle比较大的项目的能力。Lab每次任务比较琐粹了,共有13个。 Homwork有两个,一个是basic java synax,一个是Disjoint Set结构的延伸题目。
完全免费。
本课程有很多版本,如果你想要使用本课程自动评分系统的话,可以选择2018spring的版本跟着学,因为只有这一年的邀请码公开在了github上面。如果你觉得自己就可以写测试代码,推荐你学更近一期的课程。我开始学的是2014年版本,还是在黑板上手输入的那种,环境搭建没有lab支持自己花费了很多的时间。后来发现了2020 Fall版本,因为疫情的大家都是网课,所以在网络上可以找到非常非常全面的资料。关于lab,homework和project每个步骤怎么做非常详细。是我最爱的版本。
开始学习Java的基础的时候,可以看《My First Head Java》,通俗易懂,幽默风趣,就像看小说一样,每天翻几页。后来讲解数据结构的时候,最有效率的课本当然是Josh自己在github是哪个写的课本啦。链接放在这里。老师推荐的看的书是这个Data Structure。看了一段时间Josh自己编的书,学到后面的数据结构的时候就感觉不够用了,讲的比较浅。我就看了红宝书4版《Alogrithms 4th》里面的代码都是用Java实现的,不是伪码,很容易理解。课程的后半段和《算法》课有一部分重叠,我就是看算法4th这本书的。
每周大约10小时,3个小时视频可按讲义,4个小时写作业,2-3小时左右看《my first head java》和课程自己变得e-textbook。我是完全小白,什么编程语言都不会,学的比较慢,我用了4个月才学完这一门课。
上完这门课你会学到什么呢?
这门课是用Java学习数据结构。数据结构的存储方式两种“数组”和“链表”。这是数据结构的源头,是数据结构大厦最基础的两块基石。其他的数据结构知识这两种基础数据结构的变种而已。比如说“Stack”,“Queue”可以用链表可以用数组,数组实现就存在扩容的问题,链表实现就需要更多的内存来存放指针。用数组结构实现堆和栈的API我们可以选用ArrayList,用链表实现的话我们可以选用LinkedList。这门课中作业用数组和链表两个数据结构实现双端队列就是一个非常好的作业。
[树]这种结构,用数组来实现就是[堆],一个完全的二叉树;如果用链表实现就是最常见的二叉树,因为不一定是完全二叉树,所以我们需要指针指向子节点。从次延伸出红黑树,KD-Tree(一次很好的大作业),B Tree,BPS Tree(project3随机地图会用到)
[图]这种结构,用数组实现就是邻接矩阵。可以很快速的判断临边。但是如果边比较稀疏的话相对会浪费掉一大部分空间。此时用链表实现,就是邻接链表。虽然效率会慢一些,但节约了大量的空间。
[哈希表] 就是通过一个散列函数将key银蛇到一个大的数组里面。对于解决哈希表冲突的方法,可以用数组结构,也可以用链表结构。lineat probing 法需要数组的特性,占用空间少,只是删除的时候需要重新排序,以便连续寻址。seperate chain法需要链表的特性,同一个key接一个链表,操作简单。但需要而外的空间存储指针。
以上就是这门课中涉及到的数据结构了,或许你会感叹,万事皆是链表啊。这也就是为什么Josh会用两个章节的内容讲解链表吧。
我们学了数据结构,应用的操作基本就是四个 “增删查改”。所有的数据结构都是根据数据的特性设计,按照最终目的,选择最优的的方式去实现“增删查改”这几项操作的。
如何高效的去增删查改,也就是访问,就是应用数据结构的重点了。
数组是线性结构,他的访问框架:
- traverse(int[] arraylist){
- for(int i=0; i<arraylist.length; i++){
- print(arraylist[i]);
- }
- }
链表是非线性的结构,访问的框架有两种,一种是用递归,一种是用迭代。
- class ListNode{
- int val;
- ListNode next;
- }
-
- traverse(ListNode head){//迭代
- for(ListNode p= head; p != null; p=p.next){
- print(p.val);
- }
- }
- traverse(ListNode head){//递归
- if(head == null) return;
- print(head.val);
- traverse(head.next);
- }
-
我们学习完数组和链表后,就进入了二叉树的学习。可以看到,二叉树的遍历就是典型的非线性的递归结构。因为除了Heap堆这种结构,二叉树的实现我们是用链表实现的。
- class TreeNode{
- int val;
- TreeNode left, right;
- }
-
- traverse(TreeNode root){
- if(root == null) return;
- traverse(root.left);
- traverse(root.right);
- }
树的遍历的结构就是链表递归遍历的延伸,我们再看一下图的遍历的结构:
- class TreeNode{
- int val;
- TreeNode[] children
- }
-
- void traverse(TreeNode root){
- if(root == null ) return;
- for(TreeNode child : root.children){
- travere(child);
- }
你有没有发现这个结构特别的眼熟?不就是树遍历的升级版吗?
这套课程的好处就是他是一个自底而上的阶梯型的结构,他不仅仅是介绍了数据结构,也教授了他的应用框架。所谓去leetcode刷题,就是在明白这些框架的基础上,更具题目要求去套用罢了。有了这些框架,你再去学《算法》这门课时,就会感到水到渠成了。动态规划,二分法,回溯这些思想就是在这些框架的基础上的拓展和延伸了。
学习一门新的语言就像叫一个新朋友,想要教好这个朋友,脚要了解朋友的性格。一门语言就是有各种特性组成的。我们常听说Java是编译型语言,Python是解释型语言。那Java又用什么特性呢?
语言1 = [特性1, 特性2, 特性3]
语言2 = [特性1, 特性2, 特性3]
比如Java,java = [继承,封装,多态] 我们将一门语言拆分成几个特性去学习,学习效率也随之增高。特别是如果你会了其他的语言的情况下。比如一个在python中的概念Higher Order Function,即函数可以作为参数传入另外一个函数。在Java 8中也可以实现,只是方法上是运用了接口。这样 语言1 + 语言2 = [特性1] 的学习方法,让我们更高效的学习一中心的语言。 比如Java中的Static Type Checking,开始总是觉得很麻烦,因为葡萄红是动态类型的不需要检查。java则要求吧每个类型写得很清楚。慢慢觉得这是Java再帮你减少工作量呢,在程序运行前编译器就代你检查了静态类型,可以从开头就避免许多错误。
我的听讲的学习方式学习吸收效率才5%,看书的学习效率是10%。我们也可以看到,如果你把每次的作业发布在网站上教授大家,学习吸收率可以达到90%呢。可惜当时偷懒不知道这个以教为学的方法,学过之后,就在懒得输出以前的作业了。
我觉得我以前学习的时候抬不重视课本,喜欢看别人总结,参考书学习走了很多弯路。本质上是我的投机取巧心里吧,但实际上这样弯路更多。因为那些二手资料是别人咀嚼过的支离破碎的。一手资料虽然冗余繁杂,不比二手资料好消化,但也是质量最高的。我会将它想象成一本武侠小说,天下武功唯快不破,引文原版的书就是内功心法,以一招敌万千招式的内功修炼秘籍。我把他放在我最容易看到的地方,睡前翻几页,像读睡前故事一样,我的身体里有一种东西在萌发的感觉。他好像打通了我的奇经八脉,游走全身穴道。我了解到了一切原来皆有链表而来,哈希表是以空间换时间,图就是前面链表哈希表优先队列的集合体啊。
这里分享一个熔断读书法,读书的每一张每一节我们不是花同样的精力去看的,遇到让你产生感触的,让你特别以获得就停下来,熔断。去思考,同样的道理还能用到什么地方?回想自己的经历和学识去推导,解释。而不是去简单的复述作者的要点。罗振宇说他学习新知识就像缝扣子,将新内容缝到自己的知识体系上面。所以朋友们,读书最重要不是去复述教学大纲,而是接缝,结合自己的神经回路,运用知识转换的力量,将新概念缝在自己的体系上。我们班大神上课就不记录笔记,我当时还不屑一顾。现在想来,我才是哪个愚蠢的人。人家记录的重点是将新概念用转换的力量将其缝进自己旧的知识体中,逐渐充实自己的知识圈。我只是复述别人的知识框架,并没有装订到我的脑子里。「《刻意练习》一书中提出的一个理论正好可以解释这个现象。我们将知识比作一个圈的话,内圈我们掌握的知识称为舒适区,中圈为拉伸区,外圈为困难区。人的认知是无法跳跃区域发展的,只能在现有的基础上一点一点的向外扩展。」让我们疑惑,触动的地方就是处于我们拉伸区的知识,在这个区域里面学习,我们的进步就是最快的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。