松本行弘的程序世界

读书 更新时间: 2019-08-04 @ 07:40:52 创建时间: 2019-08-01 @ 07:42:55 浏览数: 153 净访问: 133 By: skyrover

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议


最近一两个月都在看这本书,这本书是因为对Ruby感兴趣,在多抓鱼上搜索Ruby的时候看到的,看到是Ruby作者松本行弘的书,于是就买来拜读一下。

总体来说,这本书写的不错,当然对我这种非科班出身而言,从总体角度来介绍整个计算机和编程世界的这类作品我还是蛮感兴趣的,因为这些内容可以补充我的知识面。这本书涉及的方面也是很广的,并且最重要的是书中涵盖了作者这种大师级的人物对编程的理解,而我通过读这本书,也加深了这些概念的理解,获益匪浅。不足的地方也有不少,比如重复性内容有点多,不够深入等等

面向对象

这一章我觉得是写的最好的一章,可能是以前我对面向对象理解不够充分吧。

面向对象有几个特点

  • 多态性

所谓多态性就是可以把不同种类的东西当成同一种东西来处理,比如不论什么车都有开门的方法,这就是根据数据类型来做合适的处理(调用合适的方法)。这样可以让程序只关注要处理什么,而不是如何去处理。所以当有新的数据类型需要处理,那么只要简单的追加对应类型的方法就可以了。不需要改动之前的程序,这样就使得程序有良好的扩展性。

  • 抽象

抽象是计算机科学中的根基,从逻辑电路到CPU,内存,到操作系统等等,都是在一层一层的抽象。这里推荐一个视频:计算机科学速成课,这个课程完美的诠释了计算机科学是如何进行一层层抽象的。

结构化编程的出现就是对程序运行流程的一种抽象,其中主要有循环,分支,顺序这几个控制流程来实现结构化编程,同时引入函数对重复进行的部分进行抽象。

但是对于有着复杂数据的程序来说,结构化编程是不能有效降低程序复杂性的,想一想一堆数据通过函数传来传去就有点心烦,所以面向对象编程就是为了对抗数据复杂性的。

也就是说数据和对应数据的处理方法组合起来对应之前结构化编程中的函数抽象,将数据和其处理方法的细节封装起来,不需要关心是怎么处理的,只需要关系能做什么,这样程序处理的数据就不是很概念性的东西,而是一个具体的对象。

  • 继承

为了避免重复,出现了继承,相同的方法可以通过类的继承实现。这里还有一种方法是原型,比如JS中就是用的原型。

继承这里有一个问题作者讲的比较深入,就是如何处理多重继承的问题,多重继承会导致类的继承关系复杂,优先顺序模糊,功能冲突。解决办法在Java里是interface(接口),在Ruby里是Mix-in,不过在Python里既支持多重继承,也支持Mix-in。

继承有两种含义,一种是外观的继承,也就是类中有哪些方法,支持哪些操作,另一种是实现的继承,就是类中都用了什么数据结构和方法,Java中对实现的继承使用extends,外观的继承是implements来指定接口。extends继承一个父类,所以类的继承是单一的,implements可以指定多个接口,接口规定了要怎样处理该对象。

对于动态语言只需要解决实现的多重继承,使用了Mix-in的方法。

后面就是介绍了下动态语言的Duck Type,元编程等,这个Python是比较类似的。

程序块

这个是Ruby中的特色功能,感觉比较屌,应该会在实际编程中大幅提高编程效率吧。这里就不多说了,想要提升Ruby编程技能的可以详细体会下。

ary.each {|x| puts x}

# 两种方式使用传递过来的块
# 块参数

def each(&block)
    i = 0
    while i < self.size
        block.call(self.[i])
        i += 1
    end
end

# 使用yield
def each()
    i = 0
    while i < self.size
        yield self[i]
        i += 1
    end
end

这里有个概念叫做内部迭代器和外部迭代器,Ruby这种将各个元素的处理逻辑传递给容器类的方法,然后在方法中对容器类中每个元素调用指定的处理逻辑称为内部迭代器方式。而在C++中是用别的类对象来循环处理容器的元素,这种方式就叫做外部迭代器方式。

设计模式

设计模式这个东西只是给经常用到的编程范式起了个名字,但是起名字这个事情意义重大,方便流传与学习。对于动态语言来说,很多设计模式都是自然而然的,不需要特意的去使用,有的已经被写入了库中,直接调用即可,比如单例模式等。

这块其实比较费解,因为设计模式这种东西一般都是应用在实际中,突然来个生硬的例子来看有点难受,还是在实际中慢慢体会吧。

ajax

这块其实非常基础,JS的基础知识。

MVC 和 Ruby on Rails

MVC 模型 视图 控制器,模型就是信息,但是不包含如何展示数据,视图就是处理模型数据如何在窗口中进行展示,控制器就是对从用户的输入,知道如何调用视图和模型的东西。

这个东西也是一种抽象,将不同功能的东西分开,降低耦合,提高扩展性。

后面介绍猴子补丁以及在RoR上的应用,RoR简直让人大为咂舌啊,很开放很灵活!

文字编码

这块之前已经做过介绍了:字符集和编码,这本书这里介绍的很细致,可以看看。

正则表达式

正则表达式就是我的噩梦,工作中真的是很多正则,看的头疼!

书中介绍的比较少,想细致了解可以看看精通正则表达式这本书~后面我准备看完之后写一篇正则表达式掌握这些就够了,帮助大家逃离苦海~

整数和浮点小数

这应该是最基本的东西了,在上大一的时候就仔细研究过,但是这东西比较抽象,所以容易忘记。讲解这块比较详细的是CSAPP中的第2章了。

这块比较有意思的是讲解了公开密钥加密的算法,比较朴素的素数算法。用公钥加密的字符串只有用私钥才能解读,用私钥加密的内容只有用公钥才能解读。所以用公钥加密,可以实现认证和加密。

对于p=3,q=11(均为素数),对于下面的(pq, e)就是公钥,(pq, d)就是私钥

pq = p * q
k = n * (p - 1) * (q - 1) + 1
e, d = 能使得 e * d = k 的任意整数

下面是加密程序,实际中也是将文本先变为整数数组,然后再开始加密

def rsa(pq, k, mesg)
    mesg.collect(|x|
        x ** k % pq
    )
end

orig = [7, 13, 17, 24]
encode = rsa(33, 3, orig)
# [13, 19, 29, 30]
decode = rsa(33, 7, orig)
# [7, 13, 17, 24]

这块涉及比较多的数学问题,可以参考:RSA算法原理

高速执行和并行处理

高速执行

主要讲了如何进行性能优化,性能优化的原则,后面讲了并行编程的一些方法。

首先性能优化是需要针对系统瓶颈的地方,这样才更有效,否则在只占20%的时间的地方优化,即使提升50%的性能,总体性能也提高不多,导致事倍功半。

选择合适的算法和数据结构这是性能改善的第一考虑要素,现在面试的人很多都是对算法一点都不了解,写的代码自然不会考虑性能问题,只想着完成任务就好了,并不会选择合适的算法和数据结构。我觉得算法这东西很有用,不仅是让人思维变得更加锐利,还会让人写出漂亮而且高效的代码。

之前写过点如何对Python程序进行性能分析,结合图像化的方法更能提高效率:CSAPP-优化程序性能

作者总结了四个进行高速优化的要点:

  • 削减对象
    • 降低生成成本,降低垃圾收集的压力
    • 减少方法调用
  • 使用立即值
  • 利用C语言
  • 采用合适的数据结构

并行编程

常规的线程,进程模型,以及会造成的问题,数据完整性的丧失(并发读写),死锁(互相争夺资源)

这里作者提到了线程为什么叫线程,类似于缝衣服的线,一会穿这里,一会穿那里,所以得名,有意思。

解决办法有使用锁来实现对资源的独占,同时包含有二级互斥的问题。另外一种方法是使用队列来协调线程,也被称为生产者消费者模型。

最后作者介绍了Actor模型,Actor就是仅通过消息进行通信的实体,并且向Actor发送消息,不等待结果是一种异步方式。类似演员表演,将戏剧继续下去。Erlang中,Actor Model是其基本。介绍Actor模型的一篇文章:十分钟带你了解Actor模型

程序安全性

软件漏洞主要有下面几个

  • DOS攻击
  • 信息泄露
  • 权限夺取
  • 权限升格

常见攻击方式有下面几种

  • 缓冲区溢出
  • 整数溢出
  • 跨站点脚本攻击(XSS)
  • SQL注入
  • 跨站点伪造请求(CSRF)

缓冲区溢出和整数溢出一般在C语言中,内存分配需要用户明确进行的可能会发生,在高级语言中,基本上是不需要关心的。

SQL注入,Shell注入和XSS攻击原理差不多,所以需要将外部输入转义,或者采用由外部间接赋予参数的方式进行:

INSERT INTO Students
    ('姓', '名')
    VALUES (?, ?)

CSRF问题主要防范措施就是会话ID中不光要包含cookie,还要附加能够证明这是正确请求的信息。比如附加token,检查HTTP请求来源(Referer),以及频繁认证。

另外的攻击方式是社会工程,比较原始的手段。。

后面讲了Ruby中的异常处理原则~

用程序处理时刻与时间

世界上时区的原点位置在英国伦敦格林尼治天文台,以此为基准的时间为格林尼治标准时间GMT。还有一个世界协调时间UTC,两者差异在于GMT是观察地球旋转来计算,UTC是根据原子时钟来计算。

另外有一个夏令时DST,因为到了夏天日照时间变长,比如现在是夏季,早上不到6点钟太阳就起来了,而我们早上10点才上班~夏令时规则就是一定期内时钟拨快一小时,但是编程上处理这种情况就比较麻烦。

和Python类似,Ruby也有对应的时间库来处理日期和时间,比如Time类Date类DateTime类,里面详细用法可以参考文档。

2038年问题,是指32位系统最大容纳到2038年的时间戳,时间戳是以1970年1月1日凌晨0时所经过的时间来表示时刻。

关于数据的持久化

这块介绍了Ruby的Marshal模块,Yaml的特征和处理方法,以及XML技术的优劣之处。XML的代替产物,JSON,YAML,Binary Yaml,Protocol Buffer

函数式编程

这块其实或多或少有接触,但是完全用函数式编程的语言却没有深入看过,书里介绍了Lisp,S式记法,反正还是很不习惯,23333

还有Haskell,听名字感觉比较吊,还有Erlang,因为它选择了函数式编程,没有赋值,不改变数据,所以Erlang强于并行计算。

Ruby的函数式编程和Python很像。

后面讲了自动生成代码的一些应用。

内存管理与垃圾收集

C/C++是程序员手动进行管理内存,所以很容易会出现内存方面的问题,所以出现了内存自动管理的功能,有下面几种方法:

  • 引用计数(可能有循环引用)
  • 标记和扫除方式(给被引用的对象加上标记,没有标记的就被清除了,循环引用就会被消除)
  • 标记和紧缩方式(主要是将活着的对象几种到了一个地方,将内存访问几种到了一个局部区域)
  • 复制方式(将活着的对象移动到新空间,旧空间弃之不用)

还有以下:

  • 分代垃圾收集(新对象更容易成为垃圾)
  • 保守垃圾收集
  • 增量垃圾收集(垃圾收集和程序同时运行)
  • 并行垃圾收集(写屏蔽来维护当前状态)
  • 位图标志

后面讲了如何用C语言扩展Ruby,这块没有仔细看了,因为一般也不怎么用到,以后再详细研究吧。

开源=开园许可证+软件


点赞走一波😏


评论

提交评论
skyrover
2019-08-22 @ 12:32:50 中国 陕西 西安

测试评论邮箱提醒系统

Linux:-Other Chrome:73.0.3683