python 面试题第一弹

1. 如何理解Python中的深浅拷贝

浅拷贝(Shallow Copy)创建一个新的对象,该对象的内容是原始对象的引用。这意味着新对象与原始对象共享相同的内存地址,因此对于可变对象来说,如果修改了其中一个对象,另一个对象也会受到影响。浅拷贝通常使用copy模块的copy()函数或者对象的copy()方法来完成。

下面是一个浅拷贝的示例:

import copyoriginal_list = [1, 2, [3, 4]]
copied_list = copy.copy(original_list)print(original_list)  # [1, 2, [3, 4]]
print(copied_list)  # [1, 2, [3, 4]]# 修改原始列表中的元素
original_list[0] = 10
original_list[2][0] = 30print(original_list)  # [10, 2, [30, 4]]
print(copied_list)  # [1, 2, [30, 4]]

在上面的示例中,copy.copy()函数创建了original_list的浅拷贝copied_list。当我们修改original_list时,copied_list中的嵌套列表也会受到影响。

深拷贝(Deep Copy)创建一个新的对象,该对象的内容是原始对象及其所有嵌套对象的副本。这意味着新对象在内存中是完全独立的,对其中一个对象的修改不会影响另一个对象。深拷贝通常使用copy模块的deepcopy()函数或者对象的deepcopy()方法来完成。

下面是一个深拷贝的示例:

import copyoriginal_list = [1, 2, [3, 4]]
deep_copied_list = copy.deepcopy(original_list)print(original_list)  # [1, 2, [3, 4]]
print(deep_copied_list)  # [1, 2, [3, 4]]# 修改原始列表中的元素
original_list[0] = 10
original_list[2][0] = 30print(original_list)  # [10, 2, [30, 4]]
print(deep_copied_list)  # [1, 2, [3, 4]]

在上面的示例中,copy.deepcopy()函数创建了original_list的深拷贝deep_copied_list。即使我们修改original_listdeep_copied_list中的嵌套列表也不会受到影响。

需要注意的是,深拷贝可能会比浅拷贝更耗费时间和内存,因为它需要递归地复制所有嵌套对象。因此,在处理大型对象或嵌套层级很深的对象时,需要谨慎使用深拷贝。

总结起来,浅拷贝创建一个新对象,该对象与原始对象共享部分内存,而深拷贝创建一个完全独立的新对象,它复制了原始对象及其所有嵌套对象的内容。根据需求选择适当的拷贝方式可以帮助我们正确地处理对象并避免意外的副作用。

2.  谈谈 is 和 == 的区别:

在Python中,is==是用于比较对象的运算符,它们具有不同的功能和用途。

is运算符用于比较两个对象的身份标识,即它们是否指向同一个内存地址。如果两个对象具有相同的身份标识,即它们是同一个对象,那么is运算符返回True;否则,返回False

==运算符用于比较两个对象的值是否相等。它会比较两个对象的内容,而不关心它们是否指向同一个内存地址。如果两个对象的值相等,==运算符返回True;否则,返回False

下面是一个示例,展示了is==运算符的区别:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1print(list1 is list2)  # False,list1和list2不是同一个对象
print(list1 is list3)  # True,list1和list3是同一个对象print(list1 == list2)  # True,list1和list2的值相等

在上面的示例中,list1list2虽然具有相同的值,但它们是不同的对象,因此list1 is list2返回False。另一方面,list1list3指向同一个对象,因此list1 is list3返回True。而list1 == list2返回True,因为它们的值相等。

需要注意的是,对于简单的值类型(如整数、字符串等),is==的结果通常是一致的。但对于可变对象(如列表、字典等),is==的结果可能不同,因为可变对象的身份标识可能相同,但值不同。

总结起来,is运算符用于比较两个对象的身份标识,即它们是否指向同一个内存地址;而==运算符用于比较两个对象的值是否相等。在编写代码时,需要根据具体的需求选择适当的运算符。如果要比较对象的值,应使用==运算符;如果要比较对象的身份标识,应使用is运算符。

3. 说说闭包和装饰器的概念:

**闭包(Closure)**是指在一个函数内部定义的函数,并且内部函数可以访问外部函数的变量。闭包可以捕获和保持外部函数的状态,即使外部函数已经执行完毕,内部函数仍然可以使用那些被捕获的变量。闭包在需要保持某些状态或者提供数据隐藏时非常有用。

下面是一个闭包的例子:

def outer_function(x):def inner_function(y):return x + yreturn inner_functionclosure = outer_function(10)
result = closure(5)
print(result)  # 输出 15

在上面的例子中,outer_function是外部函数,它接受一个参数x并返回一个内部函数inner_function。内部函数inner_function可以访问外部函数outer_function的参数x,即使在outer_function执行完毕后仍然有效。

**装饰器(Decorator)**是一种特殊的闭包,用于修改或增强函数的功能而不修改函数本身的定义。装饰器通常用于添加额外的代码,例如日志记录、性能分析、输入验证等。装饰器可以在不修改原函数代码的情况下,对函数进行包装和扩展。

下面是一个简单的装饰器的例子:

def logger(func):def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")result = func(*args, **kwargs)print(f"Function {func.__name__} executed.")return resultreturn wrapper@logger
def add(a, b):return a + bresult = add(2, 3)
print(result)  # 输出 5

在上面的例子中,logger是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数在调用被装饰的函数之前和之后打印日志信息。

通过使用@logger语法,我们将装饰器应用到add函数上。当调用add函数时,实际上是调用了被装饰后的wrapper函数,从而实现了日志记录的功能增强。

实际应用中,闭包和装饰器有许多用例。以下是一些示例:

  1. 计时器:使用装饰器记录函数的执行时间。
  2. 认证和权限控制:使用装饰器验证用户身份和控制访问权限。
  3. 缓存:使用闭包实现函数的结果缓存,以避免重复计算。
  4. 日志记录:使用装饰器将函数的调用和返回值记录到日志文件中。
  5. 输入验证:使用装饰器对函数的输入参数进行验证和过滤。

4. 用装饰器实现一个日志记录的例子:

def logger(func):def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")print(f"Arguments: {args}, {kwargs}")result = func(*args, **kwargs)print(f"Function {func.__name__} executed.")print(f"Result: {result}")return resultreturn wrapper@logger
def add(a, b):return a + bresult = add(2, 3)

5. 可变对象和不可变对象有哪些:

**不可变对象(Immutable objects)**是指创建后不能被修改的对象。当对不可变对象进行操作时,会创建一个新的对象。以下是一些常见的不可变对象:

  1. **数字(Numbers)**:包括整数(int)、浮点数(float)、复数(complex)等。
  2. **布尔值(Booleans)**:True和False。
  3. **字符串(Strings)**:一旦创建,字符串的值就不能被修改。
  4. **元组(Tuples)**:元组是一种有序且不可变的集合。

以下是不可变对象的一些特点:

  • 不可变对象的值在创建后不能被修改,对其进行操作会创建一个新的对象。
  • 不可变对象在多线程环境下是线程安全的,因为其状态不可变。
  • 不可变对象可以作为字典的键或集合的元素,因为它们的哈希值不会变化。

**可变对象(Mutable objects)**是可以修改的对象,即可以改变对象的值或状态。以下是一些常见的可变对象:

  1. **列表(Lists)**:列表是有序且可变的集合,可以通过索引进行修改。
  2. **字典(Dictionaries)**:字典是无序的键值对集合,可以通过键进行修改。
  3. **集合(Sets)**:集合是无序且唯一的元素集合,可以进行添加、删除等操作。

以下是可变对象的一些特点:

  • 可变对象的值可以在创建后被修改,对其进行操作会直接修改原始对象。
  • 可变对象在多线程环境下需要进行同步操作,以避免并发修改导致的问题。
  • 可变对象不能作为字典的键或集合的元素,因为其值的变化可能导致哈希值的变化。

6. 什么是值传递和引用传递:

**值传递(Pass-by-Value)**是指将实际参数的值复制一份,传递给函数或赋值给新变量。在这种情况下,函数或新变量操作的是复制后的值,对原始变量的修改不会影响到原始值。

**引用传递(Pass-by-Reference)**是指将实际参数的引用或地址传递给函数或赋值给新变量。在这种情况下,函数或新变量操作的是原始变量所在的内存地址,对变量的修改会直接影响到原始值。

在Python中,参数传递是通过引用传递的方式进行的。也就是说,函数或方法的参数传递的是对象的引用,而不是对象本身的副本。这意味着,如果在函数内部对引用的对象进行修改,会影响到原始对象。

下面是一个示例:

def modify_list(lst):lst.append(4)my_list = [1, 2, 3]
modify_list(my_list)
print(my_list)  # 输出 [1, 2, 3, 4]

在上面的例子中,我们定义了一个modify_list函数,它接受一个列表作为参数并向列表中添加一个元素。当我们调用modify_list(my_list)时,实际上是将my_list的引用传递给modify_list函数。在函数内部,我们通过引用对列表进行修改,添加了一个新元素。这导致原始列表my_list也被修改,输出结果为[1, 2, 3, 4]

在实际使用中,我们需要根据需求选择值传递还是引用传递。一般来说,如果希望在函数内部修改原始对象,可以使用引用传递。如果希望保持原始对象不变,可以使用值传递或传递对象的副本。

需要注意的是,在Python中,虽然参数传递是通过引用传递的方式,但对于不可变对象(如整数、字符串、元组),因为其值无法修改,所以表现类似于值传递。而对于可变对象(如列表、字典、集合),因为其值可以修改,所以表现类似于引用传递。

值传递例子:

def modify_value(value):value = value + 1x = 10
modify_value(x)
print(x)  # 输出 10

在上面的例子中,我们定义了一个modify_value函数,它接受一个整数参数value。在函数内部,我们对value进行加1操作。然而,即使在函数内部对value进行了修改,原始变量x的值并没有改变。这是因为整数是不可变对象,函数调用时发生的是值传递,传递的是x的值的副本,而不是x本身

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 731789136,里面有各种测试开发资料和技术可以一起交流哦。

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/225032.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Python的新能源汽车销量分析与预测系统

温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 基于Python的新能源汽车销量分析与预测系统是一个使用Python编程语言和Flask框架开发的系统。它可以帮助用户分析和预测新能源汽车的销量情况。该系统使用了关系数据库进行数据存储,并…

Netty组件基础

Netty入门简介 netty是一个异步、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。 Netty优势 Netty解决了TCP传输问题,如黏包、半包问题,解决了epoll空轮询导致CPU100%的问题。并且Netty对API进行增强&#xf…

结构型模式 | 适配器模式

一、适配器模式 1、原理 适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式主要分为三类:类适配器模式、对象适配器模式、接口…

Redis源码精读:字符串

文章目录 前言代码位置核心类型SDS结构获取sds字符串的元数据的宏获取字符串长度重新设置sds长度创建字符串感悟最后 前言 Redis中实现了sds(simple dynamic string)这种字符串,它比c语言标准库的char*字符串更加实用 代码位置 src/sdc.h …

【算法题】11. 盛最多水的容器

题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。…

如何配置TLSv1.2版本的ssl

1、tomcat配置TLSv1.2版本的ssl 如下图所示&#xff0c;打开tomcat\conf\server.xml文件&#xff0c;进行如下配置&#xff1a; 注意&#xff1a;需要将申请的tomcat版本的ssl认证文件&#xff0c;如server.jks存放到tomcat\conf\ssl_file\目录下。 <Connector port"1…

理解io/nio/netty

一、io io即input/output&#xff0c;输入和输出 1.1 分类 输入流、输出流&#xff08;按数据流向&#xff09; 字节流&#xff08;InputStream/OutputStream&#xff08;细分File/Buffered&#xff09;&#xff09;、字符流(Reader/Writer&#xff08;细分File/Buffered/pu…

FL Studio 21最新版本for mac 21.2.2.3470中文解锁版

FL Studio 21最新版本for mac 21.2.2.3470中文解锁版是最新强大的音乐制作工具。它可以与所有类型的音乐一起创作出令人惊叹的音乐。它提供了一个非常简单且用户友好的集成开发环境&#xff08;IDE&#xff09;来工作。这个完整的音乐工作站是由比利时公司 Image-Line 开发的。…

某音上很火的圣诞树分享

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 效果截图&#xff08;这里不给动态了&#xff0c;某音到处都是了&#xff09;&#xff1a; 源代码&#xff1a; <script src"…

在Android中使用Flow获取网络连接信息

在Android中使用Flow获取网络连接信息 如果你是一名Android开发者&#xff0c;你可能会对这个主题感到有趣。考虑到几乎每个应用程序都需要数据交换&#xff0c;例如刷新动态或上传/下载内容。而互联网连接对此至关重要。但是&#xff0c;当用户的设备离线时&#xff0c;数据如…

Flask+Mysql项目docker-compose部署(Pythondocker-compose详细步骤)

一、前言 环境&#xff1a; Linux、docker、docker-compose、python(Flask)、Mysql 简介&#xff1a; 简单使用Flask框架写的查询Mysql数据接口&#xff0c;使用docker部署&#xff0c;shell脚本启动 优势&#xff1a; 采用docker方式部署更加便于维护&#xff0c;更加简单快…

k8s实战之ELK日志管理

首先查看总体流程 首先创建namespace apiVersion: v1 kind: Namespace metadata:name: kube-logging 一、首先创建es.yaml --- apiVersion: v1 #kubernetes API版本,采用最新版本v1 kind: Service #资源类型定义为Service metadata: name: elasticsearch-logging # …

时间Date

你有没有思考过时间问题&#xff1a; 前端为什么可以直接看见时间格式的数据 后端怎么接受的数据&#xff0c;怎么处理的 一般来说&#xff1a;前端传输来数据都是时间格式的字符串&#xff0c;那么后端需要能够解析时间格式的字符串&#xff0c;归功于JSONFormat ,可以解析…

LED靠近语音声光警示灯

应用范围: 适用于高压线塔、施工工地、铁路道口等危险区域。通过微波感应检测人体行动&#xff0c;触发语音警报&#xff0c;做到提前预警&#xff0c;避免可能发生的危险事故。 产品特点 1:设备采用独立太阳能供电系统&#xff0c;警示灯与语音报警装置均为太阳能独立供电&…

【Linux驱动】最基本的驱动框架 | LED驱动

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;最基本的驱动框架⚽驱动程序框架⚽编程 &#x1f3c0;LED驱动⚽配置GPIO⚽编程…

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.向量加权平均算法4.实验参数设定…

uniapp创建/运行/发布项目

1、产生背景----跨平台应用框架 在移动端各大App盛行的时代&#xff0c;App之间的竞争也更加激烈&#xff0c;他们执着于让一个应用可以做多个事情 所以就应运而生了小程序&#xff0c;微信小程序、支付宝小程序、抖音小程序等等基于App本身的内嵌类程序。 但是各大App他不可…

【ARMv8M Cortex-M33 系列 1 -- SAU 介绍】

文章目录 Cortex-M33 SAU 介绍SAU 的主要功能包括SAU 寄存器配置示例 Cortex-M33 SAU 介绍 在 ARMv8-M 架构中&#xff0c;SAU&#xff08;Security Attribution Unit&#xff09;是安全属性单元&#xff0c;用于配置和管理内存区域的安全属性。SAU 是 ARM TrustZone 技术的一…

JavaScript中的prototype和_proto_的关系是什么

JavaScript中的prototype和_proto_的关系是什么 __proto__ 是 JavaScript 中对象的一个内部属性&#xff0c;它指向该对象的原型。JavaScript 中每个对象都有一个 __proto__ 属性&#xff0c;通过它可以访问对象的原型。prototype 是函数对象特有的属性&#xff0c;每个函数都…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错的问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序&#xff0c;查看库与库的依赖关系&#xff0c;找出出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总&#xff08;专栏文章列表&…