Python笔记8 函数

本文详细介绍了Python中的函数使用,包括位置传递、关键词传递、默认值参数、传递列表、任意数量的实参及关键词实参。此外,还讲解了函数库的调用方式,如import、from...import等不同导入方法,以及如何避免命名冲突。内容深入浅出,适合Python初学者和进阶者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、函数

函数是程序中一个个小小的功能模块,可以有输入和输出,输入过程中通常会将实参值赋给形参,形参在函数体内参与运算

def function_name(parameter1, parameter2):
    statement1
    statement2
    return something_or_nothing

① 传递实参

1. 位置传递

按照函数定义的形参顺序,在调用时依次输入实参变量

def add(number1, number2):
    sum = number1 + number2
    return sum

a = 3
b = 5
print(add(a, b))

2. 关键词传递

无需按照顺序输入实参变量

def pet(type, whos):
    print(type + " is " +whos + "'s pet.")

pet(whos = "Herman", type = "dog")
dog is Herman's pet.

3. 默认值

当为函数形参设置默认值时,可以省略它的实参传递,但是要注意,有默认值的需要放在没有默认值的形参后面,当需要为这个有默认值的形参设置参数时,采用关键词传递方式或位置传递,默认值的函数形参同样遵循位置传递的顺序

def pet(typename, whos="Herman"):
    print(typename + " is " + whos + "'s pet.")


pet("dog")
pet(whos="Bob", typename="cat")
dog is Herman's pet.
cat is Bob's pet.

② 传递列表

当传递列表时,同复制列表不可以直接使用list_new = list 一样,因为会使得新旧变量均指向同一个列表,因此当传递列表时,在函数体内对形式列表变量的操作也会影响到实际的列表,当需要保留原列表时,可以使用切片表示法,在向函数传递时,给函数传递一个列表的完全切片(复制品)

function_name(list_name[:])
def juice(food):
    while food:
        add_in_food = food.pop()
        print("Add " + add_in_food + " into juice")
        if food:
            print(str(food) + " remain in function")
        else:
            print("nothing in the food")


fruits = ['apple', 'orange', 'banana']
juice(fruits[:])
print(fruits)

③ 传递任意数量的实参

在形参名前加星号,让Python创建一个名为形参名的空元组,并将收到的所有值装入元组(不可修改的列表)
如果某个形参要接纳任意数量的实参,应该将其放在形参顺序的最后,将会在满足完全函数所有的无默认值参数、有默认值参数后,开始将剩下的值填入元组并存于最后一个形参变量中

def food(username, *pet_names):
	print(username + " has " + str(pet_names))


food("herman", "tomato", "banana")
herman has ('tomato', 'banana')

④ 使用任意数量的关键词实参

当需要向函数传递不定数量的键-值对时,可以在形参前添加双星号,使这个形参的形式为字典,将会把满足完前面参数剩下的关键词参数名及其对应的值,以键值对的形式存入字典

def person_info(name, **user_infos):
    profile = {}
    profile['name'] = name
    for key, value in user_infos.items():
        profile[key] = value
    return profile


herman_profile = person_info("herman", school= "ABC_School", age=18)
print(herman_profile)
{'name': 'herman', 'school': 'ABC_School', 'age': 18}

二、函数的库(模块)与库的调用

① 函数库的封装

在python中,函数的库以.py文件的形式存储,在函数库文件中只有函数

② 函数库的调用

当目录相同时可以这样调用

1. 调用整个库

import的本质是将代码copy到此处,在使用库内函数时,只需要在函数前加上库名并带一个点

import module_name
module_name.function()

2. 调用库中某些函数

直接调用库内某些函数时,使用函数时无需再带上库名

from module_name import function_name_1, function_name_2
function()

3. 为库指定别名

使用关键字as

import module_name as nickname
nickname.function()

4. 为库内函数指定别名

直接调用库内某些函数时,使用函数时无需再带上库名

from module_name import function_name as fn
fn()

5. 导入模块所有函数

通常不使用,因为容易和本文件内已经命名好的函数重名导致报错

from module_name import *
<think>嗯,用户现在想要的是面试题问题及答案。之前已经给过他们一个Java架构师面试题的梳理,现在他们可能想要更具体的题目和对应的答案。我需要分析他们的需求,看看他们是不是在准备面试,需要实际的例子来练习。 首先,用户之前的请求是关于Java架构师面试题的介绍,现在则是直接要求“面试题问题及答案”,可能希望得到更详细的问题和解答示例。他们可能已经在准备面试,需要具体的题目来测试自己的知识,或者作为复习材料。 接下来,我需要确保回答的结构清晰,问题分类合理,答案准确。根据之前的回答,用户可能期望类似的分类,比如Java核心、系统设计、数据库等,每个部分都有几个典型问题和答案。 还要注意用户提到的系统级指令,比如使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$。需要检查答案中的技术术语是否有正确的格式,例如在讲解Snowflake算法时,确保公式用$$包裹。 另外,用户希望用中文回答,所以所有内容都需要用中文表达,避免术语混淆。同时,答案要真实可靠,可能需要参考常见的面试题和权威解答,避免错误信息。 可能还需要考虑用户是否需要更深入的问题,或者更基础的题目,但根据之前的交互,用户关注的是架构师级别的面试题,所以问题应该偏向高级主题,如分布式系统、微服务、性能优化等。 需要确保每个问题都有简洁但完整的答案,例如在解释CAP理论时,要明确各个原则的含义和实际应用。同时,示例问题解答部分要具体,比如分布式ID生成的三种方法,用LaTeX公式展示Snowflake算法,这样更直观。 最后,检查是否有遗漏的重要主题,比如框架相关的问题(Spring、Spring Boot)、设计模式、JVM调优等,确保覆盖Java架构师面试的核心领域。同时,开放性问题如项目经验和技术趋势也不能少,帮助用户全面准备。</think>以下是一些典型的 **Java架构师面试题及参考答案**,涵盖核心知识点和设计场景,帮助您针对性准备: --- ### **一、Java核心与JVM** **1. 如何解决`OutOfMemoryError`问题?** - **分析步骤**: 1. 使用`jstat`或VisualVM监控堆内存变化 2. 通过`-XX:+HeapDumpOnOutOfMemoryError`生成堆转储文件 3. 用MAT工具分析大对象(如内存泄漏的集合类) - **常见原因**:未关闭的数据库连接、静态集合长期持有对象、大文件未流式读取 **2. `synchronized`和`ReentrantLock`的区别?** - **锁机制**:`synchronized`是JVM层面的隐式锁;`ReentrantLock`是API层面的显式锁 - **功能对比**: - `ReentrantLock`支持公平锁、可中断锁、多条件变量 - `synchronized`自动释放锁,代码更简洁 --- ### **二、分布式系统** **1. 如何实现分布式锁?** - **方案1(Redis)**: ```java // 使用SET命令+过期时间(防止死锁) String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime); if ("OK".equals(result)) { // 获取锁成功 } ``` - **方案2(ZooKeeper)**:通过创建临时有序节点实现,Watch机制监听节点删除事件 **2. 解释CAP理论并举例** - **定义**: - **C(一致性)**:所有节点数据一致 - **A(可用性)**:每次请求都能获得响应 - **P(分区容忍性)**:网络分区时系统仍能运行 - **取舍案例**: - **CP系统**:ZooKeeper(选举期间拒绝写入) - **AP系统**:Eureka(服务注册表允许短暂不一致) --- ### **三、数据库与缓存** **1. 如何优化慢SQL查询?** - **排查步骤**: 1. 使用`EXPLAIN`分析执行计划,关注`type`(扫描方式)和`Extra`字段 2. 添加索引(避免全表扫描),如联合索引需满足最左匹配原则 3. 优化SQL逻辑(如减少子查询、避免`SELECT *`) **2. 缓存穿透 vs 缓存击穿 vs 缓存雪崩** - **穿透**:查询不存在的数据(解决方案:布隆过滤器拦截非法Key) - **击穿**:热点Key过期后高并发查询压垮DB(解决方案:互斥锁重建缓存) - **雪崩**:大量Key同时过期(解决方案:随机过期时间+二级缓存) --- ### **四、系统设计** **1. 设计一个秒杀系统** - **核心难点**:高并发下的库存超卖与性能瓶颈 - **关键方案**: - **流量削峰**:MQ异步处理请求,客户端轮询结果 - **库存扣减**:Redis预扣库存(Lua脚本保证原子性)+ 数据库最终一致性 - **限流熔断**:Sentinel对突发流量熔断降级 **2. 如何设计API网关的限流?** - **算法选择**: - **令牌桶**:允许突发流量(如Guava的`RateLimiter`) - **漏桶**:恒定速率处理请求 - **实现层级**: - **网关层**:Nginx限流模块或Spring Cloud Gateway的`RequestRateLimiter`过滤器 - **服务层**:AOP切面+Redis计数器(如`INCR`命令) --- ### **五、开放性问题** **1. 如何降低系统耦合度?** - **策略**: 1. 模块化拆分(DDD领域划分) 2. 事件驱动架构(通过MQ解耦服务) 3. 依赖倒置(面向接口编程) **2. 如何管理技术债务?** - **步骤**: 1. 代码扫描工具(如SonarQube)识别高风险代码 2. 制定重构计划(每次迭代预留20%时间处理债务) 3. 建立技术评审机制,防止新增债务 --- ### **六、实战代码题示例** **题目:线程安全的单例模式** ```java public class Singleton { // 双重校验锁+volatile防止指令重排序 private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } ``` --- ### **总结建议** 1. **原理优先**:面试官常追问底层机制(如“ConcurrentHashMap如何保证线程安全?”需答分段锁/CAS) 2. **场景化回答**:结合项目说明技术选型原因(如“为什么选择Kafka而非RabbitMQ?”) 3. **横向对比**:同类技术的优缺点(如Redis Cluster vs Codis) 附:**分布式ID生成公式(Snowflake算法)** $$ \text{ID} = \text{41位时间戳} \ |\ \text{10位机器ID} \ |\ \text{12位序列号} $$ 通过以上问题及答案的梳理,可系统化提升技术深度与表达逻辑。建议结合自身项目经验,针对性准备案例分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值