news 2026/10/28 18:51:33

DeepSeek API调用入门:从API Key到流式输出与多轮对话

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek API调用入门:从API Key到流式输出与多轮对话

简介:面向有Python基础的开发者与研究人员,这份DeepSeek API调用指南围绕从注册到流式输出的完整链路展开,帮助读者快速把DeepSeek的语言理解与生成能力集成到聊天机器人、客服系统、智能助理等文本交互项目中。资源包共1个docx文档,压缩包约13KB,内容以文字讲解配合可复用代码片段为主,体量轻便,便于随查随用。已有3165人学习,说明其在API入门与集成场景中具有一定参考价值。文档依次覆盖账号注册与API Key获取、Python 3.8及以上环境准备与OpenAI SDK安装、基于OpenAI SDK和直接HTTP请求的两套调用示例,并进一步说明请求与响应JSON的解析、429或503等错误处理、temperature与max_tokens等生成参数调整,以及stream=True流式输出和多轮对话上下文维护的实现方式。文末还提示密钥保护、速率限制与使用条款等注意事项,示例代码可作为基础片段按业务需求修改,适合需要快速熟悉DeepSeek API功能特性并推进后续项目建设的读者。

1. 先搞清楚一件事:DeepSeek API 到底是个什么东西

第一次听到 DeepSeek API 调用,很多人的第一反应是:是不是得先买张显卡、把模型下载到本地跑起来?其实完全不用。你可以把 API 想成一个二十四小时营业的窗口:模型在对方的服务器上跑着,你只要把想说的话,按一份固定格式打包好递进去,窗口就会把回答递回来。落到你电脑上的活儿,其实只有三件:把文字按格式装好、发出去、把回来的内容拆开。这份指南要带你走完的路,就是从注册账号拿到那把“钥匙”开始,写出第一段能跑通的 Python 代码,再让回复像打字机一样一个字一个字往外蹦。它适合会一点点 Python、想做聊天机器人或者智能助理,但从来没接过 AI 接口的人。

2. 动手前的两件准备:拿到 API Key 和装好 Python 环境

在写第一行代码之前,你必须先解决两个前置条件。一个是身份问题,也就是那把 API Key;一个是工具问题,也就是你电脑上的 Python 环境和需要装的包。这两件事看起来是杂活,实际上是新手翻车最集中的地方。我见过太多人代码抄得一字不差,结果卡在“Key 填错了”或者“pip 装到了另一个 Python 里”这种问题上耗掉一整个下午,最后怀疑是不是接口有问题。先把这两件准备做扎实,后面会顺很多。

2.1 注册账号与拿到钥匙:API Key 怎么创建、怎么保存

注册这件事本身没什么技术含量:打开官网,找到「API 开放平台」入口,用邮箱或手机号创建账号,登录进去。真正的关键是登录之后那一步——在「API Keys」页面里创建一个新的 Key。创建成功的瞬间,页面上会显示一串很长的字符,这串字符就是你的钥匙,也是后面代码里唯一能让服务器认出“这是你”的东西。

这里有个血泪经验必须提前说:这串 Key 通常只在创建的那一刻完整显示一次,关掉页面之后你就再也看不到全貌了。所以创建完,第一件事是复制、粘贴、存好。存到哪里?千万别存到聊天记录或者随手一个记事本里,更别直接写进代码文件然后提交到代码仓库。合理的位置是你自己的密码管理工具,或者一个只在你本机存在的配置文件里。我建议新手一开始就用环境变量,下一小节会演示怎么用。

还有一个容易犯的错:反复点“创建”。有些人第一次创建完没存好,回头找不到,就再建一个,建完又忘了存,来回几次,账号里躺着一堆不知道对应哪个项目。入门阶段你只需要一个 Key 就够用了。等以后真的有好几个项目,再按项目拆分,那属于后面的事。现在,一个 Key、存好、别丢。

注意:Key 泄露的后果是别人可以拿你的额度去用。如果不小心把它贴进了公开的地方,最稳妥的处理是去后台把这个 Key 删掉,重新创建一个,而不是抱着侥幸心理继续用。

2.2 环境准备:Python 3.8 以上和 openai 这个包

Python 这块,你要确认两件事:版本够不够,以及装包的时候装没装对地方。先打开终端,敲下第一条命令:

python --version # 确认版本号,需要 3.8 或更高

如果显示的是 3.10、3.11、3.12 这类数字,就没问题。如果显示 3.7 或者干脆提示找不到命令,那就先去装一个新的 Python。版本这件事不要凑合,太老的版本在语法和依赖上会给你制造一些莫名其妙的报错,而这些报错搜出来往往牛头不对马嘴,非常打击新手信心。

版本确认完之后,装包。DeepSeek 的接口和 OpenAI 的接口格式是兼容的,所以社区里最省事的做法是直接用 OpenAI 的官方 SDK 来调用,一行命令:

pip install openai # 安装 OpenAI 官方 SDK,用来调用兼容接口

为什么推荐用 SDK 而不是一上来就手写 HTTP 请求?因为 SDK 把拼请求、解响应这些琐事包好了,你只需要关心“我要问什么”。社区里大量的示例代码、教程、现成项目也都是基于这套写法,你抄过来改两行就能跑,这对新手极其友好。等你把整套流程跑顺了,再去看底层发的是什么,会轻松很多。

装完之后建议顺手验证一下,避免出现“装了但没装上”的玄学情况:

pip show openai # 能看到版本信息,说明装成功了

如果这条命令没有任何输出,说明包没装进当前这个 Python 环境里。这是新手最常见的一个隐形坑:电脑上装了多个 Python,pip装到了 A,代码却用 B 在跑。解决办法是养成习惯,用python -m pip install openai这种方式装,让“装”和“跑”用同一个解释器。

再补一句关于虚拟环境的建议。入门阶段不是必须,但如果你打算长期折腾,强烈建议每个项目建一个独立环境:

python -m venv venv # 在当前目录创建一个独立的虚拟环境 source venv/bin/activate # macOS / Linux 激活,Windows 用 venv\Scripts\activate

激活之后,终端提示符前面通常会多出一个(venv)。这时候再执行pip install,包装的就是这个环境里的,不会和系统里其他项目打架。这个习惯养成之后,你会省掉大量“为什么昨天还能跑今天就不行了”的困惑。

最后一件事,把 Key 放进环境变量,给后面的代码用:

export DEEPSEEK_API_KEY="你刚才存下来的那串字符" # macOS / Linux

Windows 的命令行里换成set DEEPSEEK_API_KEY=你刚才存下来的那串字符。设置完之后,在同一个终端窗口里启动 Python,代码就能读到它。注意环境变量是跟着终端窗口走的,关掉窗口重开就没了,所以本地开发时通常会把这一行写进一个启动脚本里,而不是每次手敲。

3. 跑通第一个例子:用 OpenAI SDK 发出第一条消息

准备工作做完,现在进入正题。这一章的目标非常明确:让你的程序成功问出一句话,并且把回答打印在屏幕上。只要这一步通了,后面所有的功能都是在同一个骨架上加东西。所以第一个例子要尽量小、尽量简单,先追求“跑通”,不要一上来就追求“写得漂亮”。

3.1 最小可运行版本:几行代码发出第一句话

新建一个文件,比如叫first_call.py,把下面这段抄进去,把 Key 那行换成你自己的,然后运行:

import openai # 设置 API 密钥,实际使用时建议从环境变量读取,不要硬编码 openai.api_key = "your_api_key_here" # 发起一次对话请求 response = openai.ChatCompletion.create( model="deepseek-chat", # 指定使用哪个模型 messages=[ {"role": "user", "content": "你好,请介绍 DeepSeek 的功能。"} # 你要问的话 ], ) # 从返回结果里取出回答文本 print(response.choices[0].message.content)

运行方式就是在终端里python first_call.py。如果一切正常,屏幕上会打印出一段关于功能的介绍。看到这段文字的那一刻,你就已经完成了从“完全没接过接口”到“能调通”的跨越,剩下的都是在这个基础上做变化。

逐行拆一下这段代码在干什么。第一行把openai这个包引进来,它是我们和服务器之间的快递员。第二行是给快递员看通行证,也就是你的 Key。第三行开始是真正的请求:model告诉服务器你想用哪个模型,messages是一个列表,里面装的是对话内容,每一条都有role(谁说的)和content(说了什么)。最后一行是拆包裹,response.choices[0].message.content这一串看起来很长,但每一层都有含义,下一小节细讲。

如果你的 Key 是通过环境变量设置的,代码可以改成这样,避免把密钥写死在文件里:

import os import openai # 从环境变量读取密钥,代码里不出现明文 openai.api_key = os.environ.get("DEEPSEEK_API_KEY") response = openai.ChatCompletion.create( model="deepseek-chat", messages=[{"role": "user", "content": "你好,请介绍 DeepSeek 的功能。"}], ) print(response.choices[0].message.content)

这个写法看着只多了一行import os,但它意味着你把代码发给别人、或者上传到任何地方时,都不用担心把密钥一起带出去。这个习惯从第一个文件就开始养成,比事后补救轻松得多。

3.2 把黑匣子拆开:model、messages、response 三个东西

第一个例子跑通之后,很多人会处在一种“能跑但不知道为什么能跑”的状态。这不算错,但会让你在改动的时候心里没底。所以这一节把三个最核心的东西说清楚,你以后调任何参数,都知道自己动的是哪一块。

先说model。这个名字决定了服务器用哪个模型来回答你。示例里用的是deepseek-chat,你可以把它理解成“默认档”。入门阶段不要纠结模型选择,先固定用这一个,把流程跑顺。等你有具体场景了再去比较不同模型在速度、风格、成本上的差别,那属于后面的事。

再说messages,这是整个请求里最有表达力的部分。它是个列表,列表里的每一条是一个字典,字典里两个字段:role和content。role有三个常见取值,含义差别很大:

role相当于谁在说话什么时候用
system给模型立的规矩开头写一次,比如“你是一个耐心的入门助教”
user你输入的内容每一次提问都有一条
assistant模型上一轮的回答多轮对话时把历史回答塞回去

很多人第一次看到system会忽略它,其实这是控制回答风格最省力的手段。比如你希望回答简短、不要客套,就把这条规矩写进system,后面每次提问都不用重复交代。这比在每次问题里加一句“请简短回答”要干净得多。

最后说response。服务器返回的不是一段纯文本,而是一个带结构的对象。response.choices是一个列表,默认情况下里面只有一个元素,所以取[0]。再往下是.message,再往下是.content,才是真正那段文字。中间这两层为什么存在?因为一个请求理论上可以要多个候选回答,choices就是装这些候选的容器。入门阶段你只需要记住这条取值路径,但知道它不是凭空多出来的两层,以后看到别人写choices[0]就不会发懵。

除了正文,返回里还会带一些有用的信息,比如这次请求消耗了多少 token。养成打印出来看一眼的习惯:

print(response.choices[0].message.content) # 回答正文 print(response["usage"]) # 本次消耗的 token 统计

这个数字在入门阶段不重要,但它是你以后估算成本、判断上下文有没有超长的唯一依据。早点认识它没坏处。

3.3 换个姿势:不用 SDK,直接发一个 HTTP 请求

SDK 用起来省事,但它把过程包住了,你其实不太清楚网络上到底发了什么。所以我建议你在跑通 SDK 版本之后,一定再手动发一次 HTTP 请求。这一次你会看到请求的真面目,以后再出问题,你就知道该看哪里了。

需要先装一个发请求的库:

pip install requests # 一个专门用来发 HTTP 请求的库

然后写这样一段:

import os import requests api_key = os.environ.get("DEEPSEEK_API_KEY") url = "https://api.deepseek.com/v1/chat/completions" # 请求地址,和 SDK 内部用的是同一个 headers = { "Authorization": f"Bearer {api_key}", # 通行证放在请求头里,格式是 Bearer 加空格加 Key "Content-Type": "application/json", # 告诉服务器我发的是 JSON } data = { "model": "deepseek-chat", "messages": [ {"role": "user", "content": "你好,请介绍 DeepSeek 的功能。"} ], } response = requests.post(url, headers=headers, json=data) # 用 POST 把数据发出去 print(response.json()["choices"][0]["message"]["content"]) # 解析返回的 JSON

这段代码和前面 SDK 版本做的是同一件事,区别在于每一块都摊开在你面前了。url是你要敲的门,headers是你的身份证明,data是你要说的话,requests.post是把这三样一起递过去。返回的response.json()就是那个结构化对象,只是这次它变成了普通的字典,所以取值用的是方括号而不是点号。

对比一下两种写法,你会发现它们的差别主要在“谁帮你拼请求”。SDK 适合快速开发和日常使用,代码短、出错信息也友好;HTTP 请求适合排查问题和跨语言移植,因为不管你用 Python、Java 还是别的语言,发出去的东西是一模一样的。入门阶段两个都跑一遍,你对这套接口的理解会比只跑 SDK 深一层。

提示:如果你运行 3.1 的代码时报AttributeError: module 'openai' has no attribute 'ChatCompletion',不是你的 Key 有问题,而是你装到的 SDK 版本比示例代码新。这一条在第 5 章有完整说明,先别慌。

4. 让程序「边想边说」:流式输出和多轮对话怎么加

前面跑通的例子有个体验问题:程序发完请求之后,屏幕会空白好几秒,然后“啪”地一下蹦出一整段文字。字数少的时候还好,一旦回答长一点,这个等待会让人怀疑是不是卡死了。这一章解决两个实际体验问题:怎么让文字一个字一个字往外冒,以及怎么让模型记住你们刚才聊过什么。

4.1 流式输出:把一个大包裹拆成一串小包裹

流式的原理不复杂。默认情况下,服务器把整段回答生成完,打包成一个完整结果发给你;打开流式之后,服务器每生成一小段就往外发一点,你的程序收到一点就打印一点。总耗时其实差不多,但第一个字出现的时间从“好几秒”变成了“几乎立刻”,体感差别非常大。

改动只有一个参数:

import os import openai openai.api_key = os.environ.get("DEEPSEEK_API_KEY") response = openai.ChatCompletion.create( model="deepseek-chat", messages=[{"role": "user", "content": "用三句话介绍你自己"}], stream=True, # 关键开关,打开后返回的不再是一个完整结果 ) for chunk in response: # 逐个接收小包裹 if "choices" in chunk: # 有的包裹不含正文,先判断 delta = chunk["choices"][0]["delta"] # delta 是"增量",只装这一小段 if "content" in delta: # 确保这一小段里有文字 print(delta["content"], end="", flush=True) # 不换行、立刻输出 print() # 全部结束后补一个换行,让终端提示符回到新行

这段代码里有三个细节值得说。for chunk in response说明response不再是一个可以直接取值的对象,而变成了一个可以不断吐出小包裹的迭代器。delta这个词的意思是“增量”,它里面只有这一次新增的那几个字,不是完整回答,所以你必须自己把它们一段段拼起来,拼的方式就是print不换行地连续输出。

end=""和flush=True是让效果正常的关键。默认的print每输出一次就换一行,去掉换行才能连成一句话;flush=True是强制立刻把内容推到屏幕上,否则 Python 可能会攒一批再一起打印,那你看到的就不是“一个字一个字冒”,而是“一顿一顿地冒”。这两个参数不加,效果会差很多,很多新手以为流式没生效,其实是这两个地方没写对。

注意:流式模式下,返回的每个小包裹结构不完全一样,有的只带角色信息、不带正文。所以代码里那两层if判断不是多余的保险,是必须写的,否则很容易在某一次循环里报键不存在的错。

4.2 多轮对话:上下文得你自己攒

这是新手最容易误解的一点:模型本身不记得你上一句说了什么。每一次请求都是独立的,它能“记得”,完全是因为你把前面的对话一起发过去了。所谓多轮对话,本质上就是你维护一个越来越长的messages列表。

看这段代码:

import os import openai openai.api_key = os.environ.get("DEEPSEEK_API_KEY") # 一开始就把规矩立好,后面每一轮都会带上它 messages = [{"role": "system", "content": "你是一个耐心的入门助教,回答尽量简短"}] while True: question = input("你:") if question == "退出": break messages.append({"role": "user", "content": question}) # 先把你的问题加进历史 response = openai.ChatCompletion.create( model="deepseek-chat", messages=messages, # 整个历史一起发过去 ) answer = response.choices[0].message.content messages.append({"role": "assistant", "content": answer}) # 把回答也加进历史 print("AI:", answer)

关键在那两次append。第一次把你说的话加进去,第二次把模型的回答加进去。第二次特别容易被漏掉——很多人只加了user,结果模型下一轮完全不知道自己刚才说了什么,表现得很健忘。原因很简单:你不把它自己说过的话放回列表,它看到的历史里就只有一连串提问,没有回答,自然接不上。

跑起来之后你可以试着问“我刚才问了你什么”,它会答得出来。这个体验很直观,也是理解上下文机制最快的方式。

但要注意,这个列表会越来越长。每多一轮,请求里带的文字就多一份,消耗的 token 也随之增长,而且总长度是有上限的,超过之后要么被截断要么直接报错。入门阶段你可以先用“聊到一定轮数就清空历史”这种土办法,等真的做产品了再去研究更精细的上下文管理策略。

4.3 什么时候该用流式,什么时候不必

不是所有场景都适合流式。如果你的程序是在后台跑批处理、结果最后统一写进文件,那流式反而增加了解析复杂度,老老实实用普通模式更省心。但如果你的输出是直接给人看的——比如命令行小助手、网页上的对话框、客服机器人——那就该开流式,因为等待感是体验里最伤人的部分。

还有一个折中做法:流式接收,但同时在本地把每个delta拼成一个完整字符串,收完之后再统一做后续处理。这样既有即时显示的效果,又拿到了完整文本可以存库或做分析。这个模式在实际项目里用得很多,值得你早点熟悉。

5. 新手最容易翻车的四个地方:常见问题排查

前面几章的代码,只要环境干净,基本都能跑通。但真实情况是,新手卡住的地方往往不在逻辑,而在一些看起来毫不相干的小事上。这一章列四个最高频的翻车现场,每条都按“你会看到什么、为什么会这样、怎么解决”来说,遇到问题时可以直接对号入座。

5.1 现象是 401:Key 的三种死法

现象:代码一跑就报错,错误信息里带着 401 或者“未授权”“认证失败”这类字眼。

原因:服务器没认出你是谁。常见的有三种:Key 复制的时候少了几位或者前面多了空格;代码里读的环境变量名和设置时写的不一致;Key 在后台被删掉了但本地还在用旧的。

解决:先做最简单的验证——把 Key 直接硬编码进代码跑一次(只在本地临时测试,跑完就删掉)。如果这样能通,说明 Key 本身没问题,问题出在读取环节,去检查环境变量名有没有拼错、是不是在另一个终端窗口里设置的。如果硬编码也不通,那就回后台重新创建一个 Key,别再纠结旧的。

5.2 现象是 AttributeError:你抄的代码和装的包不是一代

现象:AttributeError: module 'openai' has no attribute 'ChatCompletion',代码明明一字不差抄的,就是跑不起来。

原因:SDK 更新过大版本,新旧写法不一样。你抄的示例是旧写法,pip装到的却是新版本的包,里面的入口名字已经换了。

解决:两条路选一条。一是把包降到和示例匹配的旧版本,命令是pip install openai==0.28这类形式,好处是网上大量老教程都能直接用。二是改用新写法,核心变化是把调用包在一个客户端对象里,并且要显式告诉它请求发往哪里——把第 3 章那个请求地址里的/v1/chat/completions去掉,作为客户端的 base_url 传进去,后面的调用改成client.chat.completions.create(...),返回值的取值路径也从方括号变成点号。

新手我建议走第二条,虽然要改几行,但不用和版本号较劲。改的时候对照着报错一行行试,比一次性大改容易定位问题。

5.3 现象是 429 或 503:这不是你的代码写错了

现象:跑着跑着突然报错,状态码是 429 或者 503,但同样的代码刚才还好好的。

原因:429 通常是请求太频繁,短时间内发得太多,触发了速率限制;503 一般是服务端临时不可用。这两个都不是你代码逻辑的问题,是外部状态。

解决:429 的处理方式是等一等再重试,而不是立刻重发。写个简单的等待逻辑就够用:

import time import requests for attempt in range(3): # 最多重试三次 response = requests.post(url, headers=headers, json=data) if response.status_code == 429: time.sleep(2 ** attempt) # 等待时间逐次加长:1 秒、2 秒、4 秒 continue break

503 的处理类似,等一会儿重试即可。需要提醒的是,不要写成死循环无脑重试,那样只会在服务恢复的瞬间再被打回来一次。重试次数设个上限,超过就把错误信息打出来看看。

5.4 现象是输出越来越飘:参数不是越高越好

现象:把temperature调高之后,回答变得前言不搭后语,或者同一句话问三遍得到三个完全不同的答案。

原因:temperature控制的是输出的随机性,值越高越发散。很多人以为“高一点更有创意”,结果调到一个很夸张的值,模型就开始胡说。这个参数属于典型的玄学参数,调之前先搞清楚它管什么。

参数作用新手建议值
temperature随机性,越高越发散0.7 起步,要稳定就调到 0.2
max_tokens限制回答的最大长度不确定就先不设
top_p另一种控制随机性的方式先别动,和 temperature 二选一调
stop遇到指定字符串就停止生成需要固定格式输出时再用

解决:先固定temperature在 0.7 左右,把功能跑通;需要稳定可复现的结果时调到 0.2 附近;确实要做创意类任务再往上试,但每次只动一个参数,动完对比效果。最忌讳的是同时调三四个参数,最后根本不知道是哪个起了作用。

6. 学到这里之后:往下走的三个方向和一套自己的收尾动作

走到这一步,你已经能注册、能装环境、能发请求、能处理流式、能维护多轮对话,也知道报错了该往哪看。按理说入门的目标已经达成了。接下来往哪走,我给三个方向,按投入从轻到重排。

第一个方向是换模型、换参数、换提示词。这一步不需要写新代码,就是在你已经跑通的脚本上改字符串。把同一个问题分别用不同的system提示词跑一遍,看看回答风格差别有多大;把temperature从 0.2 调到 1.0,感受一下发散程度的变化。这个练习看起来很简单,但它能让你建立对模型“能被控制到什么程度”的直觉,而这个直觉比记住十个参数名有用得多。

第二个方向是把脚本封装成能反复用的东西。现在你的代码是散落在文件里的,每次用都要改字符串。试着写一个函数,输入是问题、输出是回答,把 Key 读取、请求、错误重试都藏在函数里。再进一步,做成命令行工具,能python ask.py "你的问题"直接问。做完这一步,你就有了一个真正能日常用的小工具,而不是一个跑完就扔的示例。

第三个方向是接到一个真实的界面上。命令行用久了会觉得不方便,那就试试把你封装好的函数接到一个简单的网页或者聊天窗口里,配上流式输出,做成一个能打字的东西。这一步会逼你处理跨语言、跨进程的问题,难度上一个台阶,但做完之后你手上就有一个完整的、能给别人看的东西了。

最后一个技巧,是关于收尾动作的。我踩过最蠢的一个坑,是某次调试时图省事把 Key 直接写进了代码,跑完忘了删,过了几天把整个文件夹打包发给了别人。虽然发现得早没出事,但那一刻的冷汗我到现在还记得。从那以后我每次写完一段能跑通的代码,都强制走一遍同样的动作:先搜一遍文件里有没有那串 Key,再把 Key 相关的行改成从环境变量读,最后确认代码里没有任何明文密钥,才允许自己继续往下写。这三十秒的动作,比任何事后补救都值。

如果你现在还没动手,那就从第 2 章的第一条命令开始,别急着一次看懂所有代码,先让它跑起来,跑通了再回头读解释,会顺很多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 18:48:50

Emoji如何干扰AI语义理解及消除实操指南

Emoji作为自然语言处理中的非标准符号,其多义性与高语境依赖特征会显著增加AI语义理解的噪声,导致模型在情感极性判断、意图识别及实体抽取环节出现偏差,必须通过符号学拆解与结构化清洗机制进行干预。Emoji语义干扰的底层逻辑Emoji并非简单的…

作者头像 李华
网站建设 2026/10/28 18:42:23

AI未来会毁灭人类吗?不,人类正在用AI毁灭自己!

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/28 18:40:34

倾转旋翼机悬停仿真代码拆解:MATLAB/Simulink配平、线性化与避坑指南

简介:这份资源面向倾转旋翼机飞行动力学与控制方向的初学者及研究人员,聚焦悬停状态下的仿真建模与代码实现,帮助读者理解旋翼气动、动力系统与飞行控制之间的耦合关系。压缩包共7个文件,约59KB,以MATLAB脚本&#xff…

作者头像 李华
网站建设 2026/10/28 18:39:34

DNS over HTTPS 与 DNS over TLS 有什么区别?

DNS over HTTPS 与 DNS over TLS 有什么区别? 访问网站时,设备通常需要先通过 DNS 查询域名对应的 IP 地址。传统 DNS 查询在许多环境中没有加密,网络路径上的观察者可能看到查询内容,某些网络设备也可能对查询进行干预。 DNS ove…

作者头像 李华
网站建设 2026/10/28 18:30:38

SCAN欠定盲源分离实战:从混叠矩阵估计到源恢复的调参避坑指南

简介:这份资源聚焦欠定盲源分离(UBSS)这一信号处理方向,面向音频处理、医学成像、通信解码及金融数据分析等领域的学习者与研究人员,帮助理解观测通道少于源信号数量时的分离思路。压缩包共5个文件,以4个m脚…

作者头像 李华
网站建设 2026/10/28 18:28:07

STM32F1入门实战:DHT11驱动与底层逻辑详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华