面试题

解释/编译?动态/静态?强/弱?Python 到底是一门怎样的语言?

编译 or 解释?

编译、解释都是指将(与人类亲和的)编程语言翻译成(计算机能够理解的)机器语言(Machine code)的过程。

而两者的区别就在于「翻译时机」的不同,看一个例子:

Emmmmmmmmmmmmm~ 神比喻 !!

没错,编译型语言会将全部源代码一次性翻译完成,最终得到可执行文件,所以其主要特征就是「一次编译,多次执行」。编译型程序的优势在于运行效率奇高,毕竟可执行文件就是一连串可以被计算机直接执行机器指令集。而缺点在于,可移植性差(异构平台的 CPU 指令集不兼容)、大型应用的编译时间较长、而且每次修改源码都要重新编译,所以 debug 体验糟糕。典型的编译型语言有 C/C++,常见于偏底层,执行环境苛刻且追求速度的场景(e.g. 嵌入式、硬件开发、矿工);

反观解释型语言并不会直接将源码翻译成机器码,而是先翻译成中间码,再交由语言自身提供的解释器逐条解释执行,所以解释型语言的主要特征之一就是「边解释,边执行」。由此可见,解释型程序的运行效率会更低一些。而解释器存在的目的是为了提供一个与平台无关的托管运行时环境,使同一个解释型程序能够运行在不同的操作系统之上,这就是解释型型语言的另一大特征「跨平台」。

需要注意的是,Python 因为含有解释器,所以经常会被认作解释型语言。实际上这一论断并不严谨,因为 Python 程序的运行同样需要经历编译的过程。Python 自身也包含了编译器,它会将源码先编译为中间状态的字节码(Bytecode),再由解释器进行解释。如果可以的话,Python 会将这些字节码保存在临时文件 .pyc 中,以避免重复无谓的编译。当然,如果源码被修改了,则需要重新编译,直到下一次修改为止。这么做的原因无非是为了能够在支持跨平台的基础上进一步提升程序的运行效率,也正因如此使 Python 模糊了编译和解释的界限。如果单纯的将 Python 定性为解释型语言,难免会造成理解上的缺失。比如,不了解 .pyc 文件存在的意义。

所以,我更愿意将 Python 定义为一门既有编译又有解释的更高级的编程语言。

动态语言 or 静态语言?

动态、静态指的是编程语言类型系统对数据类型检查的严格程度。

静态类型语言属于严格数据类型检查,在程序编译时(compile time),就需要确定所有变量的数据类型,所以静态类型语言强制要求在使用变量之前事先声明变量的数据类型。因为类型声明机制,静态类型语言的编译器或 IDE 拥有着优秀的代码感知能力,能够更好的辅助程序员开发出复杂且庞大的应用系统程序。典型代表有 C、Java。

int anInt;
char aString[10];
anInt = 1;
aString = {"a","b","c","d","\0”};

动态类型语言则相反,属于非严格数据类型检查。程序在实际运行时(runtime),变量的数据类型才被确定。动态类型语言不需要类型声明,同一个变量可以在不同的位置被赋予各种数据类型。只有当程序执行到某条具体的赋值语句时,变量类型才会由赋值对象的数据类型决定。典型代表就是 Python。因此,Python 程序的开发具有很强的灵活性,同时开发效率也更高。不过,虽然 Python 程序员可以不关注变量的数据类型,但解释器却需要去推断变量的数据类型,这也在一定程序上影响了运行效率。而且数据类型检查不严格,会更加容易埋下不易察觉的 bug。所以,总的来说 Python 更适合于快速开发中小型应用系统。

>>> obj = 123
>>> obj = 'abc'

强类型 or 弱类型?

强、弱类型指的是编译程序时能否容忍隐式的数据类型转换。

弱类型语言能够容忍在程序运行时对变量进行隐式的数据类型转换,是一种几乎可以忽略数据类型的编程语言。可见,弱类型语言是一种类型非安全的编程语言。

例如 JavaScript:

> '1' + 2
'12'

强类型语言则相反,它是类型安全的。变量的数据类型一旦被确定,除非使用强制类型转换,否则其数据类型永远不会被改变。

例如 Python:

>>> '1' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int’ objects

那类型安全具有什么意义呢?

描述类型安全系统的最简单的方法就是描述它的对立面。有的语言(尤其是C和C++)允许做一些非常“不正当”的事情。但在合适的时候,其功能可能会很强大。但是,世界上没有免费的午餐。所谓“合适的时候”实际很少能够遇到。如使用不当,反而极有可能“搬起石头砸自己的脚”。滥用类型系统就属于这种情况。

打个比方,当程序将一个变量当作类型 A 来执行时,却意外的发现这个变量可能是类型 B,也可能什么都不是。但此时的程序可能已经通过了编译,正在运行的阶段。在这样的情形下,就很可能会导致程序崩溃或异常退出的问题。当然了,这里描述的是编程语言的类型安全系统。但很多时候即便编程语言是类型安全的,也可能被实现出类型非安全的应用程序。所以即便 Python 是类型安全的,但开发者仍需时刻谨慎的处理数据类型问题。

总的来说,强类型语言在速度上会稍逊于弱类型语言,但强类型带来的严谨性能够更好的避免许多错误。

最后

当然,我们可以简单的用「Python 是一门动态的强类型解释语言」来回答此次的问题。但我们通过对比编程语言的 编译/解释、动态/静态、强/弱类型 等特性之后应该可以得到更加深刻的理解。

Python 具有非常好的跨平台特性,同一套代码能够在不同的平台上正常的运行; Python

虽然在编译上作出了努力,但同步其他编程语言依旧会慢; Python

编程很灵活、效率很高,为此也牺牲了代码的严谨性,不适合多人协同开发大规模应用程序; Python

虽然是类型安全的编程语言,但因其太多灵活,所以很容易实现出类型非安全的应用程序;

当我们在使用一个工具时,我们首先要做的就是尝试去了解它。

Python 笔试集(3):编译/解释?动态/静态?强/弱?Python 是一门怎样的语言的更多相关文章

  1. Python 笔试集(4):True + True == ?

    目录 目录 前文列表 面试题True Ture 布尔值 布尔类型是特殊的整数类型 前文列表 Python 笔试集:什么时候 i = i + 1 并不等于 i += 1? Python 笔试集(1):关 ...

  2. Python 笔试集(2):你不知道的 Python 整数

    面试题 分别给出下述代码在终端(e.g. IPyhon)中和在程序中的运行结果: a = 256 b = 256 c = 257 d = 257 def foo(): e = 257 f = 257 ...

  3. Python 笔试集:什么时候 i = i + 1 并不等于 i += 1?

    ​​增强型赋值语句是经常被使用到的,因为从各种学习渠道中,我们能够得知 i += 1 的效率往往要比 i = i + 1 更高一些(这里以 += 为例,实际上增强型赋值语句不仅限于此).所以我们会乐此 ...

  4. Python 笔试集(1):关于 Python 链式赋值的坑

    前言 Python 的链式赋值是一种简易型批量赋值语句,一行代码即可为多个变量同时进行赋值. 例如: x = y = z = 1 链式赋值是一种非常优雅的赋值方式,简单.高效且实用.但同时它也是一个危 ...

  5. Python语言、编译解释、动态库静态库、编译过程、头文件

    学习Python这门语言首先要了解 什么是编译与解释,什么是连接,什么是动态库与静态库, 什么是编译: 编译就是先把高级语言设计的程序翻译成二进制的机器语言,然后CPU直接执行机器码就可以了.一把翻译 ...

  6. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  7. Apache静态编译与动态编译详解

    Apache拥有4层结构,从核心到外层的module.而外层的module可以用通过静态和动态两种方式与Apache共同工作.这也就引入下文的“动态”和“静态”两种编译安装方式: 静态编译: 编译的时 ...

  8. python介绍、安装及相关语法、python运维、编译与解释

    1.python介绍 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/)是一种广泛使用的解释型.高级编程.通用型编程语言,由吉多.范罗苏姆创造,第一版发布于1991年.可以视 ...

  9. 运维实践-最新Nginx二进制构建编译lua-nginx-module动态链接Lua脚本访问Redis数据库读取静态资源隐式展现

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 本章目录 目录 0x0n 前言 ...

随机推荐

  1. MySQL第二讲 一一一一 MySQL语句进阶

    通过命令来备份数据库: 通过数据库软件里面的,mysqldump模块来操作,如下: mysqldump -u root db1 > db1.sql -p; //没有-d就是备份的时候:数据表结构 ...

  2. 使用parted 创建一个大于2T的分区

    1.查看现有分区 parted -l fdisk   -l     2.对/dev/sdb分一个区 [root@test ~]# parted /dev/sdb   (parted) mkpart  ...

  3. 关于AP如何获取station的rssi

    最近在研究一个问题:如何通过AP来获取station的rssi. 具体可以拆分为以下三种情况: 1.首先station如果已经连接到AP上,这种情况很容易就能够得到station的RSSI.这里就不讨 ...

  4. vue项目中利用popstate处理页面返回操作

    需求背景:项目中需要做一个返回确认,避免用户误触返回键而退出当前页面. 原理:利用history和浏览器刷新popstate状态 实现: 1.在mounted() 阶段判断并添加popstate事件监 ...

  5. netty学习第5章 netty整合websocket

    学习netty之后,可能都有一个疑问,就是如何选择一个编码.解码器,在netty中的编解码可是和json这种编解码是不一样的,netty的编解码器主要是解决TCP粘包.拆包的问题.netty中有许多自 ...

  6. "东坡肉”

    “东坡肉” 苏东坡成名后,求师的人蜂涌而至,有学书法的,有学文章的.也有这么一个人,人问他学什么?他说:我学的是“东坡肉”呢! 苏东坡会不会煮猪肉?从他咏黄州猪肉“慢著火.少著水.火候足时它自美”的诗 ...

  7. Django 视图层和模板层

    目录 一.网站首页和404页面的路由配置 1. 网站首页路由 2. 404页面 二.Django视图层 1. 小白必会三板斧 (1)HttpResponse (2)render (3)redirect ...

  8. Python 3标准库第三章

    时间过得很快,又是一周过去了,今天感觉迷迷糊糊的,不在状态,然后,下面开始我们的讲解,还是跟大家分享一下我自己的一些想法,第一.怎么讲了,就是各位如果有怀才不遇的想法,我感觉最好不要有这种想法;第二. ...

  9. java实现网页验证码功能_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 本文实例为大家分享了java网页验证码的实现代码,供大家参考,具体内容如下 Servlet: package cn.bd ...

  10. 【NOIP2016提高A组模拟10.15】算循环

    题目 分析 一步步删掉循环, 首先,原式是\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=i}^n\sum_{l=j}^m\sum_{p=i}^k\sum_{q=j}^l1\] 删 ...