我所理解的计算机(二)

         接下来我说的计算机不是图灵机这些概念计算机,而是我们使用的看得见摸得着的计算机。概念理论是由来已久的,而实际使用中的计算机的发展与制造工艺的发展是紧密联系在一起的。计算机越来越快,越来越好用实际上是半导体技术、数字存储技术、数字通讯技术等发展的结果。计算机技术实际上是在这些基础技术之上长出来的树,给了花盆计算机就会成为盆景,给了院子就会长成大树。当我们只有电子管的时候,我们就只能做成又大又慢的ENIAC(1946)。不过按照需求决定理论,有了计算机技术要发展的需求,其他技术也必然会给出解决方案。这似乎有点玄妙,为了能把文字进行下去,下面我还是回到通俗的表达上来。
         当天才的布尔 [d1] 建立了用二进制表示符号逻辑的体系后,就为整个计算机世界奠定了黑与白两色的基调。与此同时,一旦出现了表示二进制逻辑的天然货币­——半导体元器件,计算机社会就形成了。我们知道半导体元器件可以处在导电或者不导电的两个稳定状态上,而且可以快速的变换状态。前者决定了计算的可能,后者决定了计算的速度。当集成电路出现后,决定性的提升了半导体电路的速度,所以说摩尔定律是计算机工业的决定性规律,现在仍是。
        有了物质基础,接下来是上层建筑。伟大领袖冯.诺依曼 [d2] 建立了一个存储计算的模型,到目前为止实用中的计算机几乎都是照着这个模型做出来的。这个模型就是把程序和数据都以二进制的形式存储在内存中(内存也是硅芯片电路组成),一个叫CPU(中央处理单元)的部件有个本事叫寻址,可以把内存中的二进制数读进来写出去。人们在CPU的硅芯片上设计了半导体电路来实现加减乘除移位这些基本运算,浮点运算等等。这就是图灵机的冯.诺依曼版。当然现在CPU中实现的运算指令要复杂的多,为了提高运行速度(工作频率),指令的实现电路也非常复杂。当我想到我写出的程序就是指挥半导体元器件的不断的状态变换,就会产生审美疲劳,就像把桌上的美食看成碳氢氧,所以程序员们都避免想到这一点,总是一副故作高深的样子。
        程序员面对的终极问题是人和计算机怎样交谈,也就是人机界面。这个问题已经大得像如来佛的手掌了。当年人们为了把写出的程序放到内存中想了很多办法。最初的解决方案是纸带(卡片),人们把程序(二进制的噢)写好,然后在纸带上穿孔,用有孔没孔来代表0101,让读纸带(卡片)机把0101读到内存中,这估计是从打卡上下班受到了启发。那时的计算机主要是面向作业的,一个作业就是一批纸带(卡片)。一个人提交作业时就插入纸带(卡片),一按开始电钮,哗哗的纸带卷动、然后是一排排的指示灯不停闪烁,表示计算进行中,最后的结果要么显示在控制台,要么打在另外的纸带上。为了省纸和环保,后来大家都知道输入输出的方式就进步多了,人们用键盘、鼠标、手写笔输入,也可以用显示器看输出。
        随着外设和提交作业的人越来越多,再加上提交作业的人谁都不想吃亏,不想被加塞插队,控制作业在计算机里运行成了个大问题。一个在计算机历史上注定名垂千古的英雄终于闪亮登场了,那就是操作系统 [d3] 。那时候的操作系统是面向作业的,它是一个比其他作业程序都地位高的程序,它一开始就在计算机内存里占据一块位置,然后接管计算机里所有的设备和资源,从此所有使用计算机的人都要对操作系统低声下气的,计算机和人的地位关系就发生了微妙的变化。(现在知道微软为什么那么牛气了吧)
        另外一件重要的事是出现了高级语言,就是让人容易使用的语言(人总是自以为高级)。人在使用计算机的过程中发现,记性是靠不住的,用0101来写程序是经常出错的,出了错问题是很严重的。懒人们就用更具有自然语言意义的字母符号代替0101编码的指令,数字也改用了经常用来算钱的十进制,然后用特定的程序把它翻译成0101代码,如果在执行前就全部翻译好,这就是编译执行;如果是翻译一段执行一段,这就是解释执行。程序从此就被写成了字母数字的序列,直到现在。而且不断发明的各种不同语法的语言养活了越来越多的程序员,如果计算机只有一种语言,我们也许早已经住在巴别塔里了。当时通行的是汇编和类汇编的各种语言,对现在的大部分程序员来说,都已经是相当于文物的东东了。
         稍晚些时候出现了另一项技术革命:磁存储技术。我们可以用软盘、硬盘、磁带这些介质把数据在不加电的情况下永久存储。这有两个意义:一个是内存是昂贵的东西,因为它要和CPU的速度匹配,不可能做得很大,而磁盘存储要便宜的多,人们可以把原来想都不敢想的大部头的东西用二进制数据的形式存下来;另外一个是不加电的情况下数据不丢失,让人们可以在计算机之间传递数据,使数据具有了相对的独立性,从而促使人们有兴趣把更多的东西转换成数据形式并存储下来。就是看到了人们赶时髦的本性,才有人不断的号召《数字化生存》。其他存储技术,像光存储,始终处于辅助地位,就不多说了。
         这样计算机又多了一个特征――多级存储。内存和外存是一例、CPU的高速缓存和内存是一例、磁盘中的缓存和磁盘也是一例。操作系统又多了一个重要的任务,把数据在多级存储之间捣腾来捣腾去,看上去让计算机有外存那么大的空间、又要有内存那么快的速度。要想梦想成真,人们一段时间内只好就反复的使用有限的一部分数据,据说这叫数据局部性原理。好在大家都很本分,潜意识里都是这么干的,没人故意和操作系统唱对台戏。

  [d1]本部分参考布尔逻辑教材
  [d2]本部分参考计算机系统结构教材。
  [d3]本部分参考操作系统教材
这段代码实现了一个并查集数据结构。并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。它支持两种操作: - 查找(Find):确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。 - 合并(Union):将两个子集合并成同一个集合。 并查集可以用于解决很多实际问题,例如: - 判断无向图中是否有环 - 在图像处理中,判断连通区域 - 在游戏开发中,判断游戏中角色的关系 在这段代码中,类 UnionFindSet 的初始化函数 __init__ 接收两个参数:起始点 start 和结束点 n。接着定义了两个列表 pre 和 rank,用于存储每个节点的父节点和树的深度。其中,pre[i] 表示节点 i 的父节点,如果 pre[i] = i,则 i 为该集合的代表元素。 接下来的函数 init 用于初始化并查集,将每个节点的父节点设置为自身,深度为 1。 函数 find_pre 用于查找节点 x 的代表元素,同时实现了路径压缩的优化,即将查找路径上的所有节点都直接连接到代表元素上,减少查找时间。 函数 is_same 用于判断节点 x 和节点 y 是否在同一个集合中,即是否具有相同的代表元素。 函数 unite 用于合并两个集合,即将 x 所在的集合和 y 所在的集合合并为一个集合。首先查找 x 和 y 的代表元素,如果它们已经在同一个集合中,则直接返回 False。否则,将深度较小的集合连接到深度较大的集合上,并更新代表元素和深度。 最后,函数 is_one 用于判断整个并查集是否只有一个集合。它首先找到起始点的代表元素 temp,然后遍历起始点到结束点之间的所有节点,如果存在任意一个节点的代表元素不等于 temp,则说明存在多个集合,返回 False;否则,所有节点都在同一个集合中,返回 True。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值