面试题

解释/编译?动态/静态?强/弱?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. ping命令的七种用法

    能不能讲下ping命令的使用,其实对于命令的使用我们之前提到过一些,但对ping命令没有过多讲解,一般我们用的都是它的基本功能,今天我们来详细看下ping命令详细使用. 一.ping基本使用详解 在网 ...

  2. 依据系统语言、设备、url 重定向对应页面

    1. 思路 获取浏览器语言.页面名称.区分手机端与电脑 根据特定方式命名 html 文件,然后独立文件,重定向 eg: - root -  gap.html     gap -    index.ht ...

  3. KVM虚拟化网卡管理

    brctl常用命令 查看当前虚拟网桥状态 brctl show 添加一个网桥 addbr 删除一个网桥 delbr 添加网口 addif 删除网口 delif VALN LAN 表示 Local Ar ...

  4. w、who、last、lastbon、lastlog显示登录命令用法

    一.w 显示已登录用户信息和用户正在执行命令 1.命令功能 w可以显示已登录系统的用户,并显示用户正在执行的命令 2.语法格式 w option user 选项说明 选项 选项说明 -h 不显示前两行 ...

  5. 【writeup】is_numeric函数矛盾运用

    最近在BugkuCTF平台刷题,遇到‘矛盾’http://120.24.86.145:8002/get/index1.php,感觉蛮有意思的,记录下思路 目标代码如下: $num=$_GET['num ...

  6. Redis在centos上面的安装

    一.安装redis 第一步:下载redis安装包 wget http://download.redis.io/releases/redis-4.0.6.tar.gz [root@iZwz991stxd ...

  7. ActiveMQ与Spring / SpringBoot 整合(四)

    1. 对 Spring 的整合 1.1 所需jar 包 <!-- activeMQ jms 的支持 --> <dependency> <groupId>org.sp ...

  8. Maven工程构建

    Maven 相关术语: 本地资源库:用来存储项目的依赖库,默认的文件夹是 “.m2” 目录 中央存储库: 用来下载所有项目的依赖库的默认位置 Maven pom.xml: 项目对象模型(Project ...

  9. linux系统下导出MySQL文件

    1.配置:从centOS6.5系统,MySQL数据库 2.导出.sql文件的命令: mysqldump -uroot -h116.228.90.147 -P18006 -p aimo > /ho ...

  10. xgboost使用细节

    from http://blog.csdn.net/zc02051126/article/details/46771793 在Python中使用XGBoost 下面将介绍XGBoost的Python模 ...