《计算机是怎样跑起来的》读书笔记

前言

《计算机是怎样跑起来的》是日本作者矢泽久雄的著作。这本书我已经是第3遍看了,每次看都会有些不同的感受。这本书浅显易懂,涉及计算机的底层、内存、CPU、汇编、编程语言、网络、数据库等方面,是一本用于科普的好书。每次看,对某一些章节会有新的体会。故记录下来,以后有新的感受再补充进来。

1 计算机的三大原则

  1. 计算机是执行输入、运算、输出的机器
  2. 关注输入、计算和输出过程
  3. 程序是指令和数据的集合
  4. 对计算机而言,一切交流都是数值
  5. 计算机的处理方式有时与人们的思维方式不同
  6. 程序员要学会和计算机做朋友,学会交流

2 试着制造一台计算机吧

微型计算机的底层硬件:CPU、内存、IO

3 体验一次手工编程

汇编语言和机器语言、汇编语言和硬件的交互、了解汇编能帮助我们更好的知道计算机是如何运行代码的,从而写出更加高效的代码。

4 程序像河水一样流动着

  1. 流程图(Flow Chart)
  2. 三种流程分支:顺序执行、条件(选择)分支、循环
  3. 结构化程序设计
  4. 在高级编程语言代码中不使用跳转语句,但高级语言转为机器语言后,因为硬件的限制,机器语言还是会存在跳转语句。
  5. 通过画流程图来思考算法(输入、计算、输出):初始化处理、循环处理、收尾处理。
  6. 中断处理和事件驱动

5 与算法成为好朋友的七个要点

5.1 算法中解决问题的步骤是明确且有限的

5.2 计算机不靠直觉而是机械地解决问题

  1. 计算机只负责算,不会动任何脑筋;
  2. 要求步骤可以直接转化为代码。
  3. 实例:求最大公约数–>辗转相除法
    代码实现:
def GCD_1(a, b):
    """辗转相除法求a, b的最大公约数
    思路:用两个数中较大的数减去较小的数(步骤),重复上述步骤,直到两个数的值相等(步骤终止)。
    如果最终这两个数相同,那么这个数就是最大公约数。
    """
    while a != b:
        if a > b:
            a -= b
        else:
            b -= a
    return b

def GCD_2(a, b):
    """辗转相除法求a, b的最大公约数
    思路:以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。
    ⒈ 令r为a/b所得余数(0≤r<b)
    若 r= 0,算法结束;b 即为答案。
    ⒉ 互换:置 a←b,b←r,并返回第一步。
    """
    while a != 0:
        a, b = b % a, a
    return b

if __name__ == '__main__':
    print("欢迎体验求解最大公约数")
    while True:
        a = int(input('请输入第一个数:'))
        b = int(input('请输入第二个数:'))
        # ans = GCD_1(a, b)
        ans = GCD_2(a, b)
        print(f'{a}和{b}的最大公约数为:{ans}')
        flag = input('请问还需要继续体验吗?如果继续,请输入"Y",否则输入"N":')
        while True:
            if flag in ['Y', 'N']:
                break
            else:
                flag = input('输入有误,如果继续,请输入"Y",否则输入"N":')
        if flag == 'Y':
            continue
        else:
            break

【待思考讨论】GCD_1和GCD_2哪个更快?计算机是如何计算除法和乘法的?(参考B站计算机科学速成课40讲)

5.3 了解并应用典型算法

【主要的典型算法】

名称 用途
辗转相除法 求解最大公约数
埃拉托斯特尼筛法 判定素数
顺序查找 检索数据
二分查找 检索数据
哈希查找 检索数据
冒泡查找 数据排序
快速排序 数据排序

【先思考算法,再去应用典型算法】
例如:如何求解最小公倍数?
方法:用两个数的乘积除以这两个整数的最大公约数。这给我们启示,一定要先思考,然后再去应用典型算法。不是所有的业务场景都可以通过典型算法解决,但是,很多情况下都可以把业务归类到某个典型算法上加以解决!

5.4. 利用计算机的处理速度

  1. 案例一:判定素数
def is_prime_1(num):
    """判断正整数num是否是素数
    思路:利用定义来判断。如果在2-num间,没有能被num整除的数,说明num素数
    """
    for i in range(2, num):
        if num % i == 0:
            return False
    return True

def is_prime_2(num):
    """判断正整数num是否是素数
    思路:利用定义来判断。如果在2-sqrt(num)+1间,没有能被num整除的数,说明num素数
    """
    n = int(num ** 0.5) + 1 # 保证能遍历到平方根,x^2 = num.
    for i in range(2, n):
        if num % i == 0:
            return False
    return True

if __name__ == '__main__':
    print("欢迎体验判断一个正整数是否为素数")
    while True:
        num = int(input('请输入正整数:'))
        # ans = is_prime_1(num)
        ans = is_prime_2(num)
        print(f'{num}是一个素数:{ans}')
        flag = input('请问还需要继续体验吗?如果继续,请输入"Y",否则输入"N":')
        while True:
            if flag in ['Y', 'N']:
                break
            else:
                flag = input('输入有误,如果继续,请输入"Y",否则输入"N":')
        if flag == 'Y':
            continue
        else:
            break
  1. 案例二:鸡兔同笼问题
def ji_tu(num, feet):
    """求解鸡兔同笼问题"""
    flag = False
    for x in range(1, num+1): # 鸡的数目
        for y in range(1, num+1): # 兔子的数目
            total_num = x + y
            feet_num = 2*x + 4*y
            if total_num == num and feet_num == feet:
                print(f'符合要求的解是:鸡有:{x}只,兔子有:{y}只!')
                flag = True
    if not flag:
        print('没有找到符合要求的解!')

if __name__ == '__main__':
    num = int(input('请输入鸡和兔子的总数:'))
    feet = int(input('请输入鸡和兔子的总计脚数:'))
    ji_tu(num, feet)

5.5. 使用编程技巧提升程序执行速度

编程中加入一些技巧,在处理大数据时,可以极大的缩短处理时间。比如判断素数,用待判定的数除以小于等于它的平方根的所有正整数,处理时间就会缩短。
【经典案例】
哨兵法:多用在线性搜索等算法中。通过哨兵,可以减少不必要的处理。见下图,哨兵法非常的巧妙!

5.6. 找出数字间的规律

所有的信息都可以用数字表示,因此为了构造算法,经常会利用到存在于数字间的规律。
经典例子:判定石头剪刀布游戏胜负的算法
如果把石头、剪刀、布分别用数字0、1、2表示,把玩家A做出的手势用变量A表示,玩家B做出的手势用变量B表示,那么变量A和B所存储的值就是这三个数中的某一个。请以此判断玩家A和B的输赢。
算法一:枚举法,那么需要枚举3X3 = 9种组合
代码实现

def game_1(A, B):
    """判定石头剪刀布游戏获胜"""
    if (A == 0) and (B == 0):
        print('平局')
    elif (A == 0) and (B == 1):
        print('玩家A获胜')
    elif (A == 0) and (B == 2):
        print('玩家B获胜')
    elif (A == 1) and (B == 0):
        print('玩家B获胜')
    elif (A == 1) and (B == 1):
        print('平局')
    elif (A == 1) and (B == 2):
        print('玩家A获胜')
    elif (A == 2) and (B == 0):
        print('玩家A获胜')
    elif (A == 2) and (B == 1):
        print('玩家B获胜')
    elif (A == 2) and (B == 2):
        print('平局')
    else:
        print('输入有误')

if __name__ == '__main__':
    print('欢迎来到猜拳游戏T_T')
    while True:
        A = int(input('请输入A玩家的手势,0、1、2分别代表石头、剪刀、布:'))
        B = int(input('请输入B玩家的手势,0、1、2分别代表石头、剪刀、布:'))
        game_1(A, B)
        flag = input('是否继续游戏?是请输入"Y",否请输入"N":')
        while True:
            if flag in ['Y', 'N']:
                break
            else:
                flag = input('输入有误,如果继续,请输入"Y",否则输入"N":')
        if flag == 'Y':
            continue
        else:
            break

可以看到上面这种方法代码非常长而且枯燥,因此我们可以加入一些技巧,通过数字的规律来简单判断胜者。规律如下:

  1. 如果变量A和B相等就是平局。
  2. 如果B+1除以3得到的余数与变量A相等就是“玩家B获胜”。
  3. 其余情况都是“玩家A获胜”。
    代码实现:
def game_2(A, B):
    """优化后猜拳游戏"""
    if A == B:
        print('平局')
    elif (B + 1) % 3 == A:
        print('玩家B获胜')
    else:
        print('玩家A获胜')

if __name__ == '__main__':
    print('欢迎来到猜拳游戏T_T')
    while True:
        A = int(input('请输入A玩家的手势,0、1、2分别代表石头、剪刀、布:'))
        B = int(input('请输入B玩家的手势,0、1、2分别代表石头、剪刀、布:'))
        # game_1(A, B)
        game_2(A, B)
        flag = input('是否继续游戏?是请输入"Y",否请输入"N":')
        while True:
            if flag in ['Y', 'N']:
                break
            else:
                flag = input('输入有误,如果继续,请输入"Y",否则输入"N":')
        if flag == 'Y':
            continue
        else:
            break

5.7. 先在纸上思考算法

拿到题目现在纸上用文字或者图来描述解决问题的步骤,而不要立刻开始编写代码。

6 与数据结构成为好朋友的七个要点

  1. 了解内存和变量的关系
  2. 了解作为数据结构基础的数组
  3. 了解数组的应用——作为典型算法的数据结构
  4. 了解并掌握典型数据结构的类型和概念
  5. 了解栈和队列的实现方法
  6. 了解结构体的组成
  7. 了解链表和二叉树的实现方法

7 成为会面向对象编程的程序员吧

  1. 面向对象编程
  2. 对OOP的多种理解方法
  3. 观点1:面向对象编程通过把组件拼接到一起构建程序
  4. 观点2:面向对象编程能够提升提升程序的开发效率和可维护性
  5. 观点3:面向对象编程是适用于大型程序的开发方法
  6. 观点4:面向对象编程就是在为现实世界建模
  7. 观点5:面向编程可以借助UML设计程序
  8. 观点6:面向对象编程通过在对象间传递消息驱动程序
  9. 观点7:在面向对象编程中使用继承、封装和多态
  10. 类和对象的区别
  11. 类的三种使用方法
  12. 在Java和.NET中有关OOP的知识不能少

8 一用就会的数据库

数据库是数据的基地
数据文件、DBMS和数据库应用程序
设计数据库
通过拆表和整理数据实现规范化
用主键和外键建立关系
索引能够提升数据检索速度
设计用户界面
向DBMS发送CRUD操作的SQL语句
事务控制也可以交给DBMS处理

9 通过七个简单的实验理解TCP/IP网络

实验1:查看网卡的MAC地址
通过win+R打开运行搜索框,然后输入cmd,在cmd中输入命令:ipconfig /all。
实验2:查看计算机的IP地址
cmd中输入:ipconfig /all。
实验3:了解DHCP服务器的作用
实验4:路由器是数据传输过程中的指路人
cmd中输入:route print。
实验5:查看路由器的路由过程
cmd中输入:tracert www.baidu.com
实验6:DNS服务器可以把主机解析成IP地址
cmd中输入:nslookup–>用于查看DNS服务器
实验7:查看IP地址和MAC地址的对应关系
cmd中输入:arp -a
TCP的作用及TCP/IP网络的层级模式

10 试着加密数据吧

错开字符编码的加密方式
秘钥越长,解密越困难
适用于互联网的公开秘钥加密技术
数字签名可以证明数据的发送者是谁

11 XML究竟是什么

XML是可扩展的标记语言
XML是元语言
XML可以为信息赋予意义
XML是通用的数据交换格式
可以为XML标签设定命名空间
可以严格定义XML的文档结构
用于解析XML的组件
XML可用于各种各样的领域

12 SE负责监管计算机系统的构建

SE是自始至终参与系统开发过程的工程师
SE未必担任过程序员
系统开发过程的规范
各个阶段的工作内容及文档
所谓设计,就是拆解
面向对象法简化了系统维护工作
技术能力和沟通能力
IT不等于引进计算机
计算机系统的成功与失败
大幅提升设备利用率的多机备份

后记:
我从本硕药学零基础转行计算机,自学路上,走过很多弯路,也庆幸自己喜欢记笔记,把知识点进行总结,帮助自己成功实现转行。
如果想和我一起交流学习,欢迎大家关注我的微信公众号No Bug编程笔记,通过扫描下方二维码或者搜索NoBugNotes关注。这个公众号主要是分享和记录自己学习编程的笔记,如:C – > Python – > Java等,后续还会分享自己面试以及职场上的成长心得。
在这里插入图片描述

发布了128 篇原创文章 · 获赞 157 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_27283619/article/details/102944996