热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

面试Python开发的这道题超简单,我却搞砸了!

题图|Shutterstockstudiostoks这道算法题明明超简单……上午10点,在T公司的会议室里,小R正在参加一场他准备了好几天的技术面试。整

题图 | Shutterstock / studiostoks

这道算法题明明超简单……

上午10点,在T公司的会议室里,小R正在参加一场他准备了好几天的技术面试。

整体来说,他在这场面试中的表现还不错。无论坐在小R对面的面试官提出什么问题,他都能侃侃而谈、对答如流。从单体应用聊到微服务,从虚拟机聊到云计算,每一块小R都说得滴水不漏。就在他慢慢认为自己胜券在握,可以通过这家自己憧憬已久的公司面试时,对面的面试官突然说道:“技术问题我问得差不多了。最后有一道编程题,希望你可以做一下。”

说完,面试官低头从包里拿出了一台笔记本电脑,递给了小R。小R有些紧张地接过电脑,发现屏幕上是一道算法题。

题目  冒泡排序算法

请用Python语言实现冒泡排序算法,把较大的数字放在后面。注意:默认所有的偶数都比奇数大。

>>> numbers = [23, 32, 1, 3, 4, 19, 20, 2, 4]
>>> magic_bubble_sort(numbers)
[1, 3, 19, 23, 2, 4, 4, 20, 32]

“冒泡排序,这不是所有排序算法里最简单的一种吗?虽然加了一点儿变化,但看起来没有什么难度啊。”小 R 一边在心里这么想着,一边打开编辑器开始写代码。

五分钟后,他把笔记本递给面试官,说道:“写完了!”

代码清单1-1就是他写的代码。

代码清单1-1   小R写的冒泡排序函数

def magic_bubble_sort(numbers):j = len(numbers) - 1while j > 0:for i in range(j):if numbers[i] % 2 == 0 and numbers[i + 1] % 2 == 1:numbers[i], numbers[i + 1] = numbers[i + 1], numbers[i]continueelif (numbers[i + 1] % 2 == numbers[i] % 2) and numbers[i] > numbers[i + 1]:numbers[i], numbers[i + 1] = numbers[i + 1], numbers[i]continuej -= 1return numbers

这段代码没有任何多余的逻辑,可以通过所有的测试用例。面试官看着小R演示完函数功能后,盯着代码似乎想说点儿什么,但最后只是微微点了点头,说:“好,今天的面试就到这儿吧。有后续面试我再通知你。”

小R高高兴兴地回到家,一心觉得这次面试稳了,可没想到,他后来却再也没接到任何后续面试通知。

1

问题出在哪里?

究竟是哪里出了问题呢?小R思来想去,觉得自己答问题时表现挺好,最有可能出问题的是最后一道编程题,肯定漏掉了什么边界情况没处理。

于是他找到一位有着十年编程经验的前辈小Q,凭着记忆把题目和自己的答案还原给对方看。

“题目大概就是这样,这是我当时写的代码。Q哥,你帮忙看看,我是不是有什么情况没考虑到?”小R问道。

小Q盯着他写的代码,足足两分钟没说一句话。然后突然开口道:“小R啊,你这个函数功能实现得没毛病,就是实在太难看懂了。"

“总共就10行代码。难看懂?怎么会呢?”小R在心里犯起了嘀咕。这时,前辈小Q说道:“这样,你把笔记本给我,我来给你稍微改改这段代码,然后你再看看。”

于是,三分钟后,小Q把把修改过的代码递了过来,如代码清单1-2所示。

代码清单1-2  小Q修改后的冒泡排序函数

def magic_bubble_sort(numbers: List[int]):"""有魔力的冒泡排序算法,默认所有的偶数都比奇数大:param numbers: 需要排序的列表,函数将会直接修改原始列表"""stop_position = len(numbers) - 1while stop_position > 0:for i in range(stop_position):current, next_ = numbers[i], numbers[i + 1] current_is_even, next_is_even = current % 2 == 0, next_ % 2 == 0should_swap = False# 交换位置的两个条件:# - 前面是偶数,后面是奇数# - 前面和后面同为奇数或者偶数,但是前面比后面大if current_is_even and not next_is_even:should_swap = Trueelif current_is_even == next_is_even and current > next_:should_swap = Trueif should_swap:numbers[i], numbers[i + 1] = numbers[i + 1], numbers[i]stop_position -= 1return numbers

①注意:此处变量名是next_而非next,这是因为已经有一个内置函数用了next这个名字。PEP8规定在这种情况下,应该给变量名增加 _ 后缀来避免冲突

小R盯着这段代码,发现它的核心逻辑和之前没有任何不同。但不知为何,这段代码看上去就是比自己写的代码更舒服。小R若有所思,好像一下明白了没通过面试的原因。

故事讲完了。看上去,前辈小Q只是在小R的代码之上做了些“无关痛痒”的改动,但正是这些“无关痛痒”的改动,改善了代码的观感,提升了整个函数的可读性。

2

“无关痛痒”的改动

和小R写的代码相比,前辈小Q的新代码主要进行了以下改进:

  1. 变量名变成了可读的、有意义的名字,比如在旧代码里,“停止位”是无意义的j,新代码里变成了stop_position。

  2. 增加了有意义的临时变量,比如current/next_ 代表前一个/后一个元素、{}_is_even代表元素是否为偶数、should_swap代表是否应该交换元素。

  3. 多了一点儿恰到好处的指引性注释,比如说明交换元素顺序的详细条件。

这些变化让整段代码变得更易读,也让整个算法变得更好理解。所以,哪怕是一段不到10行代码的简单函数,对变量和注释的不同处理方式,也会让代码发生质的变化。

本文摘自《Python工匠:案例、技巧与工程实践》

71688a333d4831f45cf1b1b9a1e49388.png

简介:本书基于广受好评的“Python工匠”系列开源文章。全书从工程实践角度出发,通过剖析核心知识、展示典型案例与总结实用技巧,帮助大家系统进阶Python,写好工程代码,做好实践项目。



推荐阅读
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文深入探讨了 Python 列表切片的基本概念和实际应用,通过具体示例展示了不同切片方式的使用方法及其背后的逻辑。 ... [详细]
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 信用评分卡的Python实现与评估
    本文介绍如何使用Python构建和评估信用评分卡模型,涵盖数据预处理、模型训练及验证指标选择。附带详细代码示例和视频教程链接。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • 探索1000以内的完美数:因数和等于自身
    本文探讨了如何在1000以内找到所有完美数,即一个数的因数(不包括自身)之和等于该数本身。例如,6是一个完美数,因为1 + 2 + 3 = 6。通过编程实现这一过程,可以更好地理解完美数的特性。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 本文介绍了几种不同的编程方法来计算从1到n的自然数之和,包括循环、递归、面向对象以及模板元编程等技术。每种方法都有其特点和适用场景。 ... [详细]
  • 配置Windows操作系统以确保DAW(数字音频工作站)硬件和软件的高效运行可能是一个复杂且令人沮丧的过程。本文提供了一系列专业建议,帮助你优化Windows系统,确保录音和音频处理的流畅性。 ... [详细]
author-avatar
铁骑侠客_685
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有