计算机科学导论学习笔记

Lecture 1
1. 中心思想:计算机有无与伦比的计算速度和存储容量,但它自身仍然有某些局限性。计算机的计算能力是通过基本计算和我们在此基础上增加的计算构成的,因此要有好的算法思维,能够把问题描述为算法,让计算机解决。
所有的问题都可以被转化为包含数字和公式的数学问题解决。

2. 知识的类型
要搞清什么是计算,先搞清什么是知识,知识分两种:声明式知识和命令式知识,前者仅仅告诉我们一个结论,而后者就像一个菜单,告诉我们如何得到这个结论,它包含“测试,计算和循环”三个基本元素。
任何时候不要使用问题说明以外的额外信息来解决问题,不要认为自己比问题懂得多。

3. 计算架构
固定程序计算机:比如计算器,专门用于解线性方程的计算机
存储程序计算机:将指令存储起来用于计算
图灵完备:只需要6种基本运算就能完成任何计算任务

4. 编程语言特点
基本组成结构
语法和语义:语法是外在结构,语义是内部含义
静态语义是指语法上正确的句子具有某种意义
常见错误:
1)语法错误
2)静态语义错误,比如2.3/‘abc’
3)得不到正确结果

Lecture 2
1. 高级编程语言有两种:编译型和解释型
编译型语言用编译器将代码编译成低级指令然后执行,速度快但查错麻烦;解释型语言将代码翻译成内部数据结构,然后解释器将每一步骤翻译成低级指令执行,速度慢但查错容易。

Lecture 3:逐次逼近法和分半搜索
逐次逼近法就是传说中的牛顿方法(Newton-Raphson),用于解一元n次方程的根,比如最简单的p(x) = x^2 - k,p(x)=0即k的平方根,牛顿方法说的是若g是根的近似值,那么g-p(g)/p'(g)则是一个更好的近似。
产生猜测值的三种方法:
穷举法,折半查找法和牛顿方法

Lecture 5:递归
函数是解决计算问题的重要基础工具,解决计算问题的模式有两种:迭代式和递归式。迭代式一次计算一步,通过使用变量保存计算的中间状态来计算结果;递归则是将一个问题化归为一个更简单或者更小的相同问题来计算结果。
递归算法由基本情况和归纳步骤组成,可以用数学归纳法作为工具验证程序正确性;有的递归算法归纳步不止一个,比如汉诺塔算法;有的递归算法基本情况不止一个,比如菲波拉契数列。
递归式解决计算问题有一个重要思想是“分治思想”,它解决问题的思路是将一个问题拆分为规模更小的子问题,然后综合子问题的解得到原始问题的答案,分治适用于子问题没有重叠的情况;另一种重要思想是“动态规划”,同样也是分解成子问题,但此时子问题可能会有重叠。

Leture 6
一等公民具有如下性质:1)具有类型;2)能够作为复合数据类型的元素;3)能够出现在表达式中(赋值和函数参数)
对Problem Set3的一些思考:
    计算机科学的核心能力之一,就是将问题描述转化为算法的能力,这是在实际工作中非常有用的一种技能。这一步先解决“做什么”的问题,然后才是解决“怎么做”的问题。
    实际工作中的需求信息常常是不明确的,有时候需求方自己都搞不清楚想干嘛,这个时候工程师还要帮助他们梳理,让需求方透过表面现象弄清楚真实意图——“自己想要的到底是什么”,这需要的是沟通和交流的能力,工程师不能埋头于代码,必须学会沟通技能。谁说工程师只会写代码,不会跟人打交道?不会跟人打交道的工程师不是好工程师!
    一份定义良好的需求应该有清晰无歧义的说明,最好包括需求规格说明(功能性需求+非功能性需求)和测试用例(场景),这样能给工程师节约不少时间,可惜的是项目忙起来的时候根本做不到,极端情况下,产品经理就甩给你一张图,让你“看图说话”——业务逻辑该怎么处理,自己看着办。所以呢,还是回到刚才的命题上,即工程师,必须能说会道,不能当闷葫芦。

Leture 7
中心问题:怎样调试代码?
    首先,在编写代码的时候,一定要编写良好的文档,来说明代码的作用,期望的输入输出;其次要能编写易于调试的代码,即可以分别进行独立调试的组件。
    学习编写测试集,将输入值空间划分为不同的子集,使得每一种输入值都只落在一个子集中。每个子集中取一个元素构成测试集,例如输入值是整型,那么就可以按正数,负数和0划分。
    测试方法有三种:随机测试,黑盒测试和玻璃盒测试。随机测试即认为测试的次数越多代码正确的概率越大;黑盒测试看不到代码实现,仅能通过代码文档说明来测试,进行黑盒测试的时候,注意取值要照顾到一般值和极端值,比如数值就可以考虑很大,很小和一般的;比如列表可以考虑空列表,含一个元素列表和含多个元素列表;玻璃盒测试是在看得到代码实现的情况下进行测试,那么就要注意路径完备——测试集能够覆盖到所有的路径,对于if语句,要能涵盖所有情况,对循环,要测试不循环,循环一次和循环多次三种情况,递归也是一样(不递归,递归一次,递归多次),同样也要注意边界值的选取。
    进行测试的时候,应该按照先unit testing后integration testing循环往复的方式,单元测试确保了每个模块工作是否正常,而集成测试则确保整个系统工作正常。每次修改代码后,要把之前跑过的测试重跑一遍,以保证修改的代码没有影响原先工作正常的代码。做测试时需要用到的两类代码为Drivers和Stubs,Drivers设置运行环境,使用预定义的输入序列调用待测试代码,然后报告运行结果;Stubs则用于模拟待测试代码将要用到的,但还没来得及实现的那部分代码。

Lecture 8 异常与断言
    当代码中出现错误和异常情况的时候,我们就可以用exceptions机制去处理它们。一般来说,错误发生在代码中,比如不小心除以0,比如传入的参数有问题;而异常通常发生在运行时,比如文件打不开了,网络无法访问了,这两种情况都可以用exceptions去处理,这样我们就可以集中精力编写代码的主要逻辑,而把错误和异常处理放到另一边,保持代码的清晰,易理解和易维护,这是exceptions作为流控制机制的一种巨大作用。良好的代码风格应该让正常代码逻辑和错误处理保持距离。
    断言assert主要用于defensive programming,在函数输入和输出上建立对pre-condition和post-condition的检查。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值