zoukankan      html  css  js  c++  java
  • 计算机是怎么跑起来的?

    01

    在学习工作中,经常会遇到些让我脑子短路无法回血的问题?

    • 你去评估下这项目需要几台机器能维持稳定性,CPU要几核,内存要多大?
    • X模块偶发出现内存飙升的情况,你追查下原因顺便想想如何优化?

    瞬间,鸦雀无声甚至气氛一度及其尴尬。作为一个CURD男孩,写代码就是一把梭复制粘贴,那能管那么宽?仔细一想,我也是学过计算机组成原理、操作系统原理的男孩,岂能说怂就怂?

    这时,冯·诺依曼、寄存器、内存、二进制、补码这些词忽隐忽现的飘过,就像一堆杂乱无章的思绪挤地铁一样挤入我的脑海。然而,我发现这跟上面的问题并没有丝毫联系,放佛我有一把方天画戟却切不动一盘菜的感觉,并没有什么用。

    我相信,大多数同学在熟练编写业务代码后,会在出现一些复杂问题后被委以重任,这就非常考验大家的基本功了。

    于是,我趁疫情在家时间充裕,花了一些时间阅读书籍和思考,尝试再去总结下计算机的基础知识。

    02

    首先,我先从计算机的三大原则开始说起。

    1. 是什么?计算机是执行输入、运算、输出的机器

    计算机通路.png

    计算机本质上就是一台机器,机器的工作模式:接收指令(输入)、理解指令(运算)、做出动作(输出)。工作模式很简单,关键是计算机如何理解指令的呢?

    举个例子:在一个阳光明媚的早上,你对你对象说:不去上班行不行?你对象娇滴滴的回答:不去上班你养我啊?

    针对这桥段,你仔细想想你对象脑子里是怎么流转的?

    • 输入:声音(汉语)
    • 理解:
      • 接收声信号
      • 分析声信号是鸟语、英语、日语还是汉语?
      • 从脑库存(内存)中抽取积累的信息(学习所得),自我翻译理解
    • 输出:表情(娇滴滴) + 声音(汉语)

    其实,计算机也有三大基础元件。

    • CPU(处理器):负责解释、执行程序。
    • 内存:负责存储程序和数据。
    • I/O(Input/Output):负责将计算机和外部设备(周边设备)连接在一起。

    简单说,I/O就相当于五官跟大自然连接的器官,内存就相当于你的脑库存(脑知识库),CPU就相当于你的脑神经中枢。

    2. 怎么交流?计算机只能理解数字

    不同人种,不同的生物,有不同的语言。机器也不例外,它也有独特的语言,你只有跟它说数字才能理解。

    你可能质疑道:放屁,我明明在我的浏览器用搜索引擎搜索关键字「靓仔」,它给我输出「博主照片」,它明明可理解中文。

    其实,这功劳就要归功于程序,程序充当了中间翻译官。比如,我们人类本身是无法识别语言的,有些人上知天文下知地理,而有些人却只会牛逼和卧槽。这一切,取决于我们的脑库存的知识,这些知识会把外界的信息进行翻译让大脑能够理解。

    于是,计算机中的内存是程序的载体,计算机只能理解数字,那么程序就必须被翻译成数字才能在计算机中运行。 程序要想运行起来,它将经历:程序 -> 编译(翻译)-> 机器语言。

    这时候,你可能会想:程序到底是什么东西,能解释清楚吗?

    3. 程序是什么?指令和数据的集合

    程序就像是我们脑库存中的知识库一样,数据相当于人的记忆,指令相当于人的逻辑。

    举个例子:

    例子1: 1 + 1 = 2
    1是数据,+运算是指令
    
    例子2:
    int i = 1; // 数据
    int j = 0; // 数据
    
    // 指令:顺序、条件、循环
    if (i > 0) {
        j = i + i;
    } else {
        j = i - i;
    }
    
    

    03

    通过叙述,大概解释清楚了计算机的硬核元件是CPU、内存、I/O,程序的硬核内容是数据、指令,程序存储在内存中供CPU读取执行运算。

    那么,我们用Java、C还是Php写程序,到底在写什么?

    本质上,写程序就是在输入初始值(申请内存),执行运算(顺序、条件、循环),输出预期值(写入内存)。

    流程图.jpg

    但是,我们知道内存是连续的,顺序执行是顺理成章的被计算机理解,条件/循环执行呢?于是,就出现跳转指令,用于跳转到指定的程序块。
    内存跳转图.jpg

    基于内存约束,数据也就是连续存储在内存中。但是,人类对世界的需求是千奇百怪的,更不是纯线性结构的。同时,我们又无法去改变内存的结构。

    于是,出现了很多的数据结构。

    • 线性:链表、堆、栈
    • 树状:二叉树
    • 图状:邻接矩阵、邻接表、逆邻接表、十字链表

    那么,这些数据结构有什么用?本质上来说,是为了适应各种运算方式从而找到最优解也就是算法,我认为「数据结构」是为「算法」服务的,这样才能更好的运转。

    简单说,程序就是「数据 + 指令」线性存储在内存中供CPU调遣,CPU运算就是在执行顺序、条件、循环的运算逻辑。为了满足现实世界的诉求,人类为了更好让机器服务,于是研究出了各种各样的运算法则(算法),算法需要特殊的存储结构(数据结构),这样在现实世界与机器就友好相处了。

    04

    我们常听资深程序员说:不要去争执学什么语言了,学透一门语言,学习其他语言是很容易的?

    通过上面分析,你仔细想想学习编程语言的过程?

    • 第一课:数据类型(int、long、char、指针、bool)
    • 第二课:运算符(+-*/)、控制流程(顺序、条件、循环)
    • 第三课:数组、结构体、类
    • 第四课:集合
    • 第五课:文件、网络(I/O)
    • 第六课:并发编程(CPU)
    • 第七课:内存管理(内存)

    其实,学习一门编程语言的逻辑是非常简单的,你想你按这个逻辑去学习一门新编程语言也可以轻松上手,主要关注不同语言的差异。

    1. 学习程序基础结构「数据 + 指令」。于是,先学习数据类型,运算方式、控制流程、数组、结构体、类。
    2. 为了简化我们的使用成本,于是必然会有很多可复用的集合「数据结构 + 算法」,list、map、set一定会与你相遇,只不过是穿什么大裤衩罢了。
    3. 网络编程、文件处理,就是计算机跟外界接触的器官,输入/输出罢了。
    4. CPU是执行运算的大脑,为了更好的榨干CPU,那就必然会并发编程,至于怎么并就取决于计算机有几核。
    5. 内存管理就像仓库管理,你要有进有出。那么,内存你申请了不释放,必然会出现飙升直到仓库饱满挂掉。不同的是,内存管理是一项基本工作也是很复杂的事情,不同语言可能会推出自动回收内存的机制,也有像C++这种需手动回收的机制。

    这样,我们理清楚了计算机硬件跟我们写的程序在宏观上的一个关系。于是,我们回到最初的问题。

    问题1: 你去评估下这项目需要几台机器能维持稳定性,CPU要几核,内存要多大?

    根据监控峰值QPS,根据不同QPS状况统计CPU和内存的占用情况,根据实际情况给个折中值就好。

    问题2: X模块偶发出现内存飙升的情况,你追查下原因顺便想想如何优化?

    这就是个内存管理问题,主要去review内存申请和销毁的程序逻辑,重点看是否有申请不释放的逻辑,辅之以工具,那就有解决办法了。

    总而言之,有时候并不是碰到的问题的有多难,而是如何去思考定位关键问题,辅之以工具,不断实验和调试,最终从根本上解决问题。而不是,胡子眉毛一把抓,或怒气冲冠大喊尼玛狗逼,或惊慌失措叨叨凉了凉了。相信自己,脑子在思考,我们就能赢。

  • 相关阅读:
    「日常训练」Single-use Stones (CFR476D2D)
    「日常训练」Greedy Arkady (CFR476D2C)
    「Haskell 学习」二 类型和函数(上)
    「学习记录」《数值分析》第二章计算实习题(Python语言)
    「日常训练」Alena And The Heater (CFR466D2D)
    Dubbo 消费者
    Dubbo 暴露服务
    Rpc
    git fail to push some refs....
    Spring Cloud (6)config 客户端配置 与GitHub通信
  • 原文地址:https://www.cnblogs.com/qiuyong/p/12291589.html
Copyright © 2011-2022 走看看