likes
comments
collection
share

腾讯面试:用冯诺依曼原理编写猜拳游戏

作者站长头像
站长
· 阅读数 28

前言

这篇文章着重想和大家讲讲,大厂的面试和中小厂的面试差异到底在哪里,真的是知识点大家没有掌握全面吗?还是这其中有多少细节是我们没有认清的?

首先我们回归这道题目,这道题目提到了冯诺依曼原理,在大学期间,我们科班同学应该都学过计算机组成原理、计算机网络、操作系统...这一系列课程,事实上,这一系列课程对我们构建计算机基础至关重要。

冯诺依曼原理

  1. 采用二进制数制:计算机内部的信息表示和运算都采用二进制数字 0 和 1。
  2. 存储程序控制:程序和数据被事先存储在计算机的存储器中,计算机在执行时能自动地、连续地从存储器中依次取出指令并执行。
  3. 计算机硬件由运算器、控制器、存储器、输入设备和输出设备五大部分组成
  • 运算器:负责进行算术和逻辑运算。
  • 控制器:对计算机的各部件进行统一的控制和协调。
  • 存储器:用于存储程序和数据。
  • 输入设备:将外部信息输入到计算机中。
  • 输出设备:将计算机处理的结果输出给用户。

分析题目

既然面试官让我们使用冯诺依曼原理来完成这一简单程序的设计,那么首先猜拳游戏,我们得有人猜拳吧?既然有人猜拳,我们就首先得有输入设备输入我们到底是出拳头还是剪刀还是石头。

  • 通过键盘输入设备拿到用户的输入
  • 后端运行js,访问输入设备stdin
  • 输出设备输出到命令行
    process.stdin.on('data', (buffer) => {
    // buffer 是一个二进制数据 存储和通信的底层是二进制数据
    // console.log(buffer);
    const action = buffer.toString().trim()
    // console.log(action, '------------');

监听用户在标准输入(stdin)(通常是终端)的输入事件。

当用户输入数据时,会触发 data 事件,此时接收到的 buffer 是一个二进制数据。通过 buffer.toString().trim() 将二进制数据转换为字符串,并去除前后的空格,得到用户输入的有效动作 action 。这为后续的游戏逻辑处理提供了用户的输入信息。

  • 接下来就是需要我们转换到业务层了,这边第一个小细节:函数的封装,当代码量大了一些,我们需要将程序封装出去,然后复用,一个是代码的可读性好,一个是程序的可维护性。
/**
 * @func 根据用户输入,输出胜或赢
 * @return win or lose
 */
const game = (action) => {
    const arr = ['rock', 'paper', 'scissors'];
    // 判断输入是否合法
    if (arr.indexOf(action) == -1) {
        throw new Error('请输入正确的指令');
    }
    let computerAction;
    let random = Math.floor(Math.random() * 3);
    computerAction = arr[random];
    console.log('电脑出了:' + computerAction);
    if (computerAction == action) {
        return 0; //平局
    } else if (
        (action == 'rock' && computerAction == 'scissors')
        || (action == 'paper' && computerAction == 'rock')
        || (action == 'scissors' && computerAction == 'paper')) {
        return 1; // 你赢了
    } else {
        return -1;// 你输了
    }

}
  • 第二个细节:代码的可读性,多写注释,方便自己也贡献他人,代码更加美观与可读。
  • 业务层game函数中,我们定义了一个数组,内容为剪刀石头布
  • 细节三:判断用户输入是否合法,一个好的程序应当经得起检验,而不是来了一个错误的数据我们也不给报错,程序直接忽视这些问题继续执行,这样的程序,当业务越来越大一定会出问题。
  • 判断输入是否合法的逻辑是:用户输入的内容是否与我们定义好的剪刀石头布一致,得按规矩办事,否则就不给办,通过indexOf方法可以判断数组中这个值是否存在,如果存在则返回值的下标,如果不存在则返回-1
  • 通过随机生成一个索引值 random 值为0~1,*3以后就变成了0~3,但是这其中会包含小数因此我们可以通过Math.floor方法向下取整得到0-1-2,分别对应数组下标,这样随机获取数组中的剪刀石头布computerAction = arr[random]
  • 最后执行我们的逻辑,判断我们输入的action与随机出拳谁获胜的逻辑。

业务逻辑完成之后,我们回到我们的监听事件,当获胜3局以后就把监听事件结束掉,因此我们可以先定义一个标志winCount

let winCount = 0;
process.stdin.on('data', (buffer) => {
    // buffer 是一个二进制数据 存储和通信的底层是二进制数据
    // console.log(buffer);
    const action = buffer.toString().trim()
    // console.log(action, '------------');
    // 独立随机出拳业务
    const result = game(action)
    if (result == 0) {
        console.log('平局');
    } else if (result == 1) {
        console.log('你赢了');
    } else {
        console.log('你输了');
    }
    if (result == 1) {
        winCount++;
    }
    if (winCount == 3) {
        console.log('恭喜你,你赢了!');
        process.exit();
    }


})
  • 当然,在我编写的这份代码里并没有把所有的情况写全,例如机器人赢的次数,如果机器人赢了3局这个程序也应该结束,我们user赢的次数,大家也可以尽可能的将程序逻辑写的更加丰富。

腾讯面试:用冯诺依曼原理编写猜拳游戏

腾讯面试:用冯诺依曼原理编写猜拳游戏

小结

其实这一整个逻辑过程并不重要,每个游戏每份程序都有自己的业务逻辑,我更想向大家表达的是这里面的各种细节。 例如:

  1. 进入大厂需要具备什么?扎实的计算机基础,理解计算机的底层逻辑、原理
  2. 良好的代码习惯,封装复用函数...代码的可读性...
  3. 严谨的逻辑能力业务能力、程序的健壮性,判断输入是否合法...,如果不合法应该怎么办,直接报错?报错后能否给出提示程序继续向下走?
转载自:https://juejin.cn/post/7368767452614901795
评论
请登录