Ascend的aclgraph(七)AclConcreteGraph:capture_begin
1 回顾
在上一章Ascend的aclgraph(六)AclConcreteGraph中提到了capture_begin
和capture_end
两个函数,这2个函数是pybind形式,调用到torch_npu中去执行。
大概流程图如下:
def __enter__(self):# Free as much memory as we can for the graphtorch.npu.synchronize()gc.collect()torch.npu.empty_cache()# Stackoverflow seems comfortable with this patternself.stream_ctx.__enter__()self.npu_graph.capture_begin(*self.pool, capture_error_mode=self.capture_error_mode)def __exit__(self, exc_type, exc_value, traceback):self.npu_graph.capture_end()self.stream_ctx.__exit__(exc_type, exc_value, traceback)
2 capture_begin
在torchair
进入torch_npu
之前,首先进行了算子同步、python的垃圾回收、缓存清理等操作,
然后调用进入到torch_npu
的c++侧,
def("capture_begin",[](c10_npu::NPUGraph& self,std::optional<c10_npu::MempoolId_t> pool_opt,std::string capture_error_mode) {aclmdlRICaptureMode capture_mode;c10_npu::MempoolId_t pool = pool_opt.has_value()? pool_opt.value() : c10_npu::MempoolId_t{0, 0};if (capture_error_mode == "global") {capture_mode = aclmdlRICaptureMode::ACL_MODEL_RI_CAPTURE_MODE_GLOBAL;} else if (capture_error_mode == "thread_local") {capture_mode = aclmdlRICaptureMode::ACL_MODEL_RI_CAPTURE_MODE_THREAD_LOCAL;} else if (capture_error_mode == "relaxed") {capture_mode = aclmdlRICaptureMode::ACL_MODEL_RI_CAPTURE_MODE_RELAXED;} else {TORCH_CHECK(false,"Unknown capture error mode. Expected `global`, `thread_local`, or `relaxed`, got ",capture_error_mode);}return self.capture_begin(pool, capture_mode);},py::arg("pool"),py::arg("capture_error_mode"),py::call_guard<py::gil_scoped_release>())
capture_begin
首先执行的是上述的lamda表达式中的内容,主要是对capture_mode进行了判断,还记得这几个mode模式之间的区别不?
该参数用于指定图形捕获流中的aclmdlRICaptureMode。可以是“全局”、“线程本地”或“宽松”。在NPU图形捕获期间,某些操作(如npuMalloc)可能会不安全。
- “全局”将在其他线程中执行的操作上引发错误,
- “线程本地”仅会在当前线程中执行的操作上引发错误,
- “宽松”不会在操作上引发错误。
除非您熟悉aclmdlRICaptureMode_,否则请勿更改此设置。
然后就正式进入到c++侧capture_begin
函数,首先结合代码
void NPUGraph::capture_begin(MempoolId_t pool, aclmdlRICaptureMode capture_mode)
{static const auto _task_queue_enable = c10_npu::option::OptionsManager::GetTaskQueueEnable();TORCH_CHECK(_task_queue_enable != 2,"Do not support TASK_QUEUE_ENABLE = 2 during NPU graph capture, please ""export TASK_QUEUE_ENABLE=1/0.",PTA_ERROR(ErrCode::NOT_SUPPORT));TORCH_CHECK(!has_graph_exec_,"This NPUGraph instance already owns a captured graph. ""To capture a new graph, create a new instance.");auto stream = c10_npu::getCurrentNPUStream();TORCH_CHECK(stream != c10_npu::getDefaultNPUStream(),"NPU graphs must be captured on a non-default stream. ""(However, after capture, it's ok to replay them on the ""default stream.)");capture_stream_ = stream;capture_dev_ = c10_npu::current_device();if (pool.first != 0 || pool.second != 0) {// Either value being nonzero means the user supplied a pool to share.// But only one should be nonzero.// If pool was created by another graph's capture_begin, first should be nonzero.// If pool was created by graph_pool_handle, second should be nonzero.TORCH_INTERNAL_ASSERT(!(pool.first && pool.second));mempool_id_ = pool;} else {// User did not ask us to share a mempool. Create graph pool handle using is_user_created=false.// Sets just the first value, to distinguish it from MempoolId_ts created by graph_pool_handle().auto mempool = c10_npu::MemPool({}, false);mempool_id_ = mempool.id();TORCH_INTERNAL_ASSERT(mempool_id_.first > 0);}// Addendum: beginAllocateStreamToPool is now called before cudaStreamBeginCapture to prevent an// autograd thread's free() call triggering an invalid cudaEventRecord in the caching allocator// due to the capture status being updated _after_ a capture had already started.c10_npu::NPUCachingAllocator::beginAllocateToPool(capture_dev_, mempool_id_, [this](aclrtStream stream) {aclmdlRICaptureStatus status;aclmdlRI model_ri;NPU_CHECK_ERROR(c10_npu::acl::AclmdlRICaptureGetInfo(stream, &status, &model_ri));return status == aclmdlRICaptureStatus::ACL_MODEL_RI_CAPTURE_STATUS_ACTIVE && model_ri == model_ri_;});// At this point, any NCCL watchdogs should be aware that we are in capture mode// and therefore should not enqueue any additional work that could be event-queried.// We still must wait on any existing work that has not been cleaned up.while (num_pending_event_queries()) {TORCH_WARN_ONCE("Waiting for pending NCCL work to finish before starting graph capture.");std::this_thread::sleep_for(std::chrono::milliseconds(kSynchronizeBusyWaitMillis));}// cudaStreamCaptureModeGlobal is the most conservative option to// prevent potentially unsafe CUDA API calls during capture.NPU_CHECK_ERROR(c10_npu::acl::AclmdlRICaptureBegin(capture_stream_, capture_mode));aclmdlRICaptureStatus status;NPU_CHECK_ERROR(c10_npu::acl::AclmdlRICaptureGetInfo(stream, &status, &model_ri_));TORCH_INTERNAL_ASSERT(status == aclmdlRICaptureStatus::ACL_MODEL_RI_CAPTURE_STATUS_ACTIVE);
}
给出流程图
mempool是图capture用来做显存复用的,每次cupture都有一个PrivatePool
对象。PrivatePool
对象可以被多个capture graph共用,使用mempool_id来管理。
// Called by NPUGraph::capture_begin
void beginAllocateToPool(MempoolId_t mempool_id, std::function<bool(aclrtStream)> filter)
{std::lock_guard<std::recursive_mutex> lock(mutex);auto it = graph_pools.find(mempool_id);if (it == graph_pools.end()) {// mempool_id does not reference an existing pool. Make a new pool for// this capture.graph_pools.emplace(mempool_id, std::make_unique<PrivatePool>());} else {// mempool_id references an existing pool, which the current capture will// share. Check this pool is live (at least one other capture already// references it).TORCH_INTERNAL_ASSERT(it->second->use_count > 0);it->second->use_count++;}for (auto it2 = captures_underway.begin(); it2 != captures_underway.end(); ++it2) {TORCH_CHECK(it2->first != mempool_id, "beginAllocateToPool: already recording to mempool_id");}captures_underway.emplace_back(mempool_id, std::move(filter));
}
captures_underway
用来继续当前正在图capture中使用到的mempool_id
。
captures_underway 用于跟踪我们是否将某些分配重定向到特定池。
// 大多数情况下它是空的,在这种情况下,malloc 可以避免在热路径上调用 aclrtStreamGetCaptureInfo。
num_pending_event_queries
是在图开始capture之前,等待所有nccl的任务完成。
AclmdlRICaptureBegin函数核心的cupture函数
aclError AclmdlRICaptureBegin(aclrtStream stream, aclmdlRICaptureMode mode)
{typedef aclError (*AclmdlRICaptureBegin)(aclrtStream, aclmdlRICaptureMode);static AclmdlRICaptureBegin func = nullptr;if (func == nullptr) {func = (AclmdlRICaptureBegin) GET_FUNC(aclmdlRICaptureBegin);}TORCH_CHECK(func, "Failed to find function aclmdlRICaptureBegin", PTA_ERROR(ErrCode::NOT_FOUND));return func(stream, mode);
}
GET_FUNC
的宏定义如下:
#define GET_FUNC(funcName) \GET_FUNCTION(libascendcl, funcName)
整个代码的逻辑就是:
- 先定义了一个函数指针类型 AclmdlRICaptureBegin,它指向一个接受两个参数(一个 aclrtStream 和一个 aclmdlRICaptureMode)并返回一个 aclError 值的函数。
- 然后定义了一个函数级的静态成员变量AclmdlRICaptureBegin
- 尝试通过
GET_FUNC
(aclmdlRICaptureBegin) 动态加载 aclmdlRICaptureBegin 函数,并将其地址赋值给 func。也就是从libascendcl.so
中查找aclmdlRICaptureBegin的函数 - 然后调用func执行具体的函数。
说白了,关键函数还是藏在libascendcl.so
里面。
先弄明白aclmdlRICaptureBegin
是什么时候注册进去的?
#define REGISTER_LIBRARY(soName) \auto library_##soName = \::std::unique_ptr<c10_npu::option::FunctionLoader>(new c10_npu::option::FunctionLoader(#soName)); \static c10_npu::option::register_function::FunctionRegisterBuilder \register_library_##soName(#soName, library_##soName);#define REGISTER_FUNCTION(soName, funcName) \static c10_npu::option::register_function::FunctionRegisterBuilder \register_function_##funcName(#soName, #funcName);#define GET_FUNCTION(soName, funcName) \c10_npu::option::register_function::FunctionRegister::GetInstance()->Get(#soName, #funcName);
这里看到了REGISTER_FUNCTION
宏定义。根据小编的理解,先给出流程图:
这里关注FunctionLoader
这个对象,弄明白为什么registry
这个map里面存储的不是函数对象,而是需要一个类对象(智能指针形式)。
先给出FunctionLoader
的定义:
class FunctionLoader {
public:/**ctr*/explicit FunctionLoader(const std::string& filename);/**dectr*/~FunctionLoader();/**set function name*/void Set(const std::string& name);/**get function address by function name.*/void* Get(const std::string& name);
private:mutable std::mutex mu_;std::string fileName;void* handle = nullptr;mutable std::unordered_map<std::string, void*> registry;
}; // class FunctionLoader
发现,真正存储函数指针的地方,应该是FunctionLoader
中的registry
。Set
函数
void FunctionLoader::Set(const std::string &name)
{this->registry[name] = nullptr;
}
Set
函数执行的时候,在registry
中存储了对应的key值,value设置为nullptr。
Get
函数
void *FunctionLoader::Get(const std::string &name)
{// 缓存if (this->handle == nullptr) {auto handle = dlopen(this->fileName.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (handle == nullptr) {AT_ERROR(dlerror());return nullptr;}this->handle = handle;}auto itr = registry.find(name);if (itr == registry.end()) {AT_ERROR("function(", name, ") is not registered.");return nullptr;}if (itr->second != nullptr) {return itr->second;}auto func = dlsym(this->handle, name.c_str());if (func == nullptr) {return nullptr;}this->registry[name] = func;return func;
}
先通过dlopen
打开了对应的so,如上就是libascendcl.so
,并缓存了对应的handle(在FunctionLoader
析构的时候调用dlclose)
然后通过dlsym
在so中去查找对应的函数名称。
读到这里,还没弄明白aclmdlRICaptureBegin到底做的是什么事情?
在昇腾官网上搜索到如下信息:
https://www.hiascend.com/document/detail/zh/canncommercial/81RC1/apiref/appdevgapi/aclcppdevg_03_1782.html
函数原型
aclError aclmdlRICaptureBegin
(aclrtStream stream, aclmdlRICaptureMode mode)
接口解释
开始捕获Stream上下发的任务。
在aclmdlRICaptureBegin
和aclmdlRICaptureEnd
接口之间,所有在指定Stream上下发的任务不会立即执行,而是被暂存在系统内部模型运行实例中,只有在调用aclmdlRIExecuteAsync
接口执行模型推理时,这些任务才会被真正执行,以此减少Host侧的任务下发开销。任务执行完毕后,若无需再使用内部模型,可调用aclmdlRIDestroy接口及时销毁该资源。
aclmdlRICaptureBegin
和aclmdlRICaptureEnd
接口要成对使用,且两个接口中的Stream应相同。在这两个接口之间,可以调用aclmdlRICaptureGetInfo
接口获取捕获信息,调用aclmdlRICaptureThreadExchangeMode
接口切换当前线程的捕获模式。此外,在调用aclmdlRICaptureEnd
接口之后,还可以调用aclmdlRIDebugPrint
接口打印模型信息,这在维护和测试场景下有助于问题定位。
在aclmdlRICaptureBegin
和aclmdlRICaptureEnd
接口之间捕获的任务,若要更新任务(包含任务本身以及任务的参数信息),则需在aclmdlRICaptureTaskGrpBegin
、aclmdlRICaptureTaskGrpEnd
接口之间下发后续可能更新的任务,给任务打上任务组的标记,然后在aclmdlRICaptureTaskUpdateBegin
、aclmdlRICaptureTaskUpdateEnd
接口之间更新任务的输入、输出信息。
说明
在aclmdlRICaptureBegin和aclmdlRICaptureEnd接口之间捕获到的任务会暂存在系统内部模型运行实例中,随着任务数量的增加,以及通过Event推导、内部任务的操作,导致更多的Stream进入捕获状态,Stream资源被不断消耗,最终可能会导致Stream资源不足(Stream数量限制请参见aclrtCreateStream),因此需提前规划好Stream的使用、关注捕获的任务数量。
这里也说明了stream管理,在mempool使用的重要性。
3 小结
最终device侧如何根据aclmdlRICaptureBegin和aclmdlRICaptureEnd捕捉,存储相关的节点,当前是没有对外代码说明的,无从看起。但是能知道,算子的执行信息都是在device侧的,并没有在host上留下信息,那么跟以前的FX graph又是什么关系呢?先记住这些疑问,后续继续探讨。下一篇章,看下capture_end又做了些什么事情。
相关文章:
Ascend的aclgraph(七)AclConcreteGraph:capture_begin
1 回顾 在上一章Ascend的aclgraph(六)AclConcreteGraph中提到了capture_begin和capture_end两个函数,这2个函数是pybind形式,调用到torch_npu中去执行。 大概流程图如下: def __enter__(self):# Free as much memory as we can…...
JT/T 808 各版本协议字段级别对比与解析适配建议
文章目录 一、概述二、字段级对比表(以核心消息为例)三、版本文档结构差异分析四、Java 协议解析适配建议4.1、协议版本识别策略:4.2、可扩展消息体结构设计:4.3、字段兼容处理建议:4.4、推荐使用解析库或框架…...
Kafka 消费者组进度监控方法解析
#作者:张桐瑞 文章目录 前言一、使用 Kafka 自带命令行工具 kafka-consumer-groups 脚本二、使用 Kafka Java Consumer API 编程三、使用 Kafka 自带的 JMX 监控指标 前言 在 Kafka 消息队列系统中,对于 Kafka 消费者而言,监控其消费进度&a…...
国产大模型 “五强争霸”,决战 AGI
中国 AI 大模型市场正经历一场史无前例的洗牌!曾经 “百模混战” 的局面已落幕,字节、阿里、阶跃星辰、智谱和 DeepSeek 五大巨头强势崛起,形成 “基模五强” 新格局。这场竞争不仅是技术实力的较量,更是资源、人才与生态的全面博…...
lesson01-PyTorch初见(理论+代码实战)
一、初识PyTorch 二、同类框架 PyTorchVSTensorFlow 三、参数 对比 四、PyTorch生态 四、常用的网络层 五、代码分析 import torch from torch import autogradx torch.tensor(1.) a torch.tensor(1., requires_gradTrue) b torch.tensor(2., requires_gradTrue) c tor…...
几种运放典型应用电路
运算放大器简称:OP、OPA、OPAMP、运放。 一、电压跟随器 电压跟随器顾名思义运放的输入端电压与运放的输出电压相等 这个电路一般应用目的是增加电压驱动能力: 比如说有个3V电源,借一个负载,随着负载电流变大,3V就会变小说明3V电源带负载能力小,驱动能力弱,这个时候…...
Mybatis——动态sql
<if> 实现方式 动态标签 <if> 条件判断,进行sql语句拼接 成立则拼接 <where> 进行条件子句拼接,防止and重复 if案例 crtl alt L 格式化 <foreach>——用于批量操作(删除) <include>...
技术社区集锦
推荐地址 社区汇总地址 https://juejin.cn/post/7468935497799286834 社区 项目ValueValueGitHubgithub.com-----Giteegitee.com-----StackOverflowstackoverflow.com全球知名的技术问答网站博客园www.cnblogs.com开发者的知识分享社区稀土掘金juejin.cn技术内容分享与交流平…...
【Elasticsearch】DSL 篇
Elasticsearch 之 DSL 篇 介绍 Elasticsearch 提供了基于 JSON 的 DSL 语句来定义查询条件,其 JavaAPI 就是在组织 DSL 条件。 先学习 DSL 的查询语法,然后再基于 DSL 来对照学习 JavaAPI,就会事半功倍 json 格式,好理解&#…...
常见 RPC 协议类别对比
RPC(Remote Procedure Call,远程过程调用)协议是分布式系统中实现跨进程通信的核心机制之一。它允许客户端像调用本地函数一样调用远端服务器上的函数。 根据通信方式、数据编码方式和平台兼容性不同,常见的 RPC 协议分为以下几类…...
React系列——nvm、node、npm、yarn(MAC)
nvm,node,npm之间的区别 1、nvm:nodejs版本管理工具。nvm 可以管理很多 node 版本和 npm 版本。 2、nodejs:在项目开发时的所需要的代码库 3、npm:nodejs包管理工具。nvm、nodejs、npm的关系 nvm 管理 nodejs 和 npm…...
LeetCode 热题 100 230. 二叉搜索树中第 K 小的元素
LeetCode 热题 100 | 230. 二叉搜索树中第 K 小的元素 大家好,今天我们来解决一道经典的二叉搜索树问题——二叉搜索树中第 K 小的元素。这道题在 LeetCode 上被标记为中等难度,要求查找二叉搜索树中的第 K 小的元素。 问题描述 给定一个二叉搜索树的根…...
vscode - 笔记
1 IDE就用vscode,安装Remote-SSH插件通过SSH访问树莓派里的文件夹 写在开始:阿尔法Linux开发板学习开始 - 银色的音色 - 博客园 2 VSCode之Linux C/C开发和调试 VSCode之Linux C/C开发和调试 CMake代码编译 json配置_哔哩哔哩_bilibili 3 VS Code 凭…...
使用VSCode编辑Markdown+PlantUml
vscode :https://code.visualstudio.com/ 什么是markdown: Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。 Markdown 编写的文档可以导出 HTML 、Word、图像、PDF、Epub 等多种格式的文档。 在vscode上安装MarkDown相关…...
关于 Golang GC 机制的一些细节:什么是根对象?GC 机制的触发时机?
文章目录 关于 Golang GC 机制的一些细节:什么是根对象?GC 机制的触发时机?简要回顾 Golang GC 三色标记法的工作流程什么是根对象?GC 的触发时机? 关于 Golang GC 机制的一些细节:什么是根对象?…...
内存虚拟盘(RAMDisk)是什么?
内存虚拟盘(RAMDisk)是一种通过软件将计算机的部分物理内存(RAM)模拟为硬盘驱动器的技术,利用内存的高速读写特性显著提升数据访问效率。以下从原理、优势、实现方式及应用场景等方面详细解析: 1. 技术原…...
深入浅出入侵检测系统(IDS)的工作原理与应用场景
网络安全界的“火眼金睛”:入侵检测系统IDS 一、IDS简介:网络安全界的“火眼金睛” 在计算机安全领域,有一个“火眼金睛”的角色,它能在网络世界中识破各种“妖魔鬼怪”的伪装,及时发出警报,保护我们的数…...
AISBench benchmark评测工具实操-精度评测场景-采用命令行指定模型和数据集的方式
一、环境信息 1.1.硬件设备 昇腾Atlas800 I A2:910A 01:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d801 (rev 20) 1.2.软件信息 1.2.1模型: DeepSeek-R1-Distill-Qwen-1.5B 1.2.2.物理机系统: NAME="EulerOS" VERSION="2.0 …...
HTTP GET报文解读
考虑当浏览器发送一个HTTP GET报文时,通过Wireshark 俘获到下列ASCII字符串: GET /cs453/index.html HTTP/1.1 Host: gaia.cs.umass.edu User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) Acc…...
南审计院考研分享会 经验总结
汪学长 – 中科大 计科专硕 初试准备 数学先做真题,模拟题刷的越多分越高;408真题最重要,模拟题辅助;英语只做真题;政治9月份开始背 代码能力在低年级培养的重要性和路径 考研不选择机构原因 因为机构里面学习的框…...
Android多媒体——媒体解码流程分析(十四)
NuPlayer 的解码模块相对比较简单,统一使用了一个基类 NuPlayerDecoderBase 管理,该类中包含了一个 MediaCodec 的对象,实际解码工作全靠 MediaCodec。 一、解码器创建 解码器创建的入口在 NuPlayer 的 NuPlayer::instantiateDecoder() 函数调用时。NuPlayer 在执行 start(…...
学习threejs,使用Physijs物理引擎,通过控制重力,实现多米诺骨牌效果
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…...
自由学习记录(60)
Lecture 16 Ray Tracing 4_哔哩哔哩_bilibili 老师说的“高频采样”问题是什么? 现在考虑一个特殊情况: ❗ 一个像素内,图像信号变化很剧烈(高频): 比如: 细网格纹理 马赛克背景 很高频的…...
Gartner《分布式和微服务架构中数据架构》学习心得
一、简介 随着信息技术的不断发展,软件架构也在持续演变以适应不断变化的业务需求。从传统的单体架构向分布式和微服务架构转变,给数据的管理带来了新的挑战和机遇。《Working With Data in Distributed and Microservices Architectures》研究针对在分布式和微服务架构中处…...
谷歌web第三方登录
1.在谷歌控制台创建客户端信息 https://console.cloud.google.com/auth/clients 注:在重定向的url中一定要是https开头的。 创建完成之后主要获取三个信息 clientID、secret、redirctUrl 2.配置pom <dependency><groupId>com.google.auth</group…...
ConfigMap 和 Secret 是否支持热更新
在 Kubernetes 中,ConfigMap 和 Secret 是否支持热更新取决于它们的使用方式和应用程序的行为。以下是详细分析: 1. ConfigMap 的热更新 场景 1:通过 Volume 挂载到 Pod 支持热更新: 如果 Pod 通过 volume 挂载 ConfigMap&#…...
时序数据库IoTDB分布式系统监控基础概述
在分布式系统环境中,系统性能调优与瓶颈定位一直是工程实践与架构设计中的关键挑战。面对诸如系统性能无法提升、查询延迟增加等问题,需要一套有效的监控体系来洞察系统的内部状态与运行情况。 可观测性概念 随着分布式架构的普及,可观测性…...
【乱码】前端js流式输出因为Uint8Array字节不完整导致乱码问题
【乱码】流式输出因为Uint8Array字节不完整导致乱码问题 function push() {reader.read().then(({ done, value }) > {if (done) { 问题代码 var a new Uint8Array([115,44,32,115,101,114,105,102,34,62,230]) var b new Uint8Array([156,136,60,47,115,112,97,110,62…...
PDF Base64格式字符串转换为PDF文件临时文件
需求描述: 在对接电子病历系统与河北CA,进行免密文件签章的时候,两者系统入参不同,前者是pdf文件,base64格式;后者要求File类型的PDF文件。 在业务中间层开发时,则需要接收EMR侧提供的base64格式…...
ClickHouse详解
ClickHouse 是一款开源的列式数据库管理系统(DBMS),由 Yandex 开发,专为联机分析处理(OLAP)设计,具备高性能、低延迟、海量数据处理能力,广泛应用于日志分析、用户行为分析、指标监控…...
Go语言中的函数类型参数:深入理解`func()`
在Go语言中,函数是一等公民,可以作为参数传递、作为返回值,甚至赋值给变量。其中,func()作为一种特殊的函数类型,在Go的并发编程、回调机制和接口设计中扮演着重要角色。本文将全面解析func()的用法、原理和最佳实践。…...
deepseek梳理java高级开发工程师微服务面试题-进阶版
高级Java微服务面试题与深度解析 一、Spring Cloud核心组件深度剖析 1. Eureka服务注册发现机制 题目:详细分析Eureka的AP特性实现原理,包括服务注册、续约、剔除和自我保护机制,并说明与Nacos的CP模式区别。 答案: Eureka A…...
Math工具类全面指南
Math工具类全面指南 前言一、Math 类的基础特性1.1 类的声明与常量1.2 数据类型支持 二、基础算术运算2.1 绝对值运算2.2 取整运算2.2.1 floor():向下取整2.2.2 ceil():向上取整2.2.3 round():四舍五入取整 2.3 最大值与最小值 三、三角函数与…...
为什么 Linux 上默认没有 host.docker.internal
在 Linux 环境中,host.docker.internal 是 Docker 为容器提供的一个特殊 DNS 名称,用于指向宿主机的 IP 地址(类似 macOS/Windows 中的行为)。但这个功能在 Linux 上默认不启用,需要手动配置才能使用。以下是详细解释和…...
HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南
一、HTML 颜色系统详解 HTML 中的颜色可以通过多种方式定义,包括颜色名称、RGB 值、十六进制值、HSL 值等,同时支持透明度调整。以下是详细分类及应用场景: 1. 颜色名称(预定义关键字) HTML 预定义了 140 个标准颜色名…...
HTTP / HTTPS 协议
目录 一、前言: 二、Fiddler 抓包工具: 三、http 协议: 1、http 请求: 1.(1)请求行: 1、(2) 请求头: 1、(3) 请求正文: 2、http 响应: 2、(1) 状态码&#x…...
使用GRPO训练调度事件的语言模型!
参考:https://huggingface.co/blog/anakin87/qwen-scheduler-grpo 现在是2025年,在DeepSeek热潮之后,每个人都想使用GRPO训练自己的推理模型。 作为一名实践者,我也想这样做:仅使用提示和奖励来训练语言模型是一件非常…...
关于 js:9. Node.js 后端相关
一、Node 环境搭建与执行流程 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让 JS 不再局限于浏览器内,而是可以在服务器、终端、本地脚本中运行。 核心定位:让我们可以用 JS 写本地程序、脚本、爬虫、加密逻辑、hook 工具、…...
More Effective C++:改善编程与设计(上)
More Effective C: 目录 More Effective C: 条款1:仔细区别pointers和 references 条款2:最好使用C转型操作符 条款3:绝对不要以多态方式处理数组 条款4:非必要不要提供default constructor 条款5:对定制的“类型转换函数”保持警觉 …...
SCDN如何有效防护网站免受CC攻击?——安全加速网络的实战解析
在互联网安全威胁日益复杂化的今天,CC(Challenge Collapsar)攻击已成为网站运营者面临的主要挑战之一。这种攻击通过模拟大量合法用户请求,消耗服务器资源,导致正常用户无法访问。而**安全内容分发网络(SCD…...
关于并发编程AQS的学习
目录 1. AQS的核心作用 2. AQS的核心结构 3. 关键方法 4. AQS的应用示例 4.1、ReentrantLock的实现 4.2、CountDownLatch的实现 5. AQS的优势 6. 对比其他同步机制 前言 AQS(AbstractQueuedSynchronizer) 是Java并发编程中一个核心的同步器框架…...
16S18S基础知识(1)
相关内容: https://blog.csdn.net/weixin_34315189/article/details/86397125?fromshareblogdetail&sharetypeblogdetail&sharerId86397125&sharereferPC&sharesource2302_80012625&sharefromfrom_link https://metagenome.blog.csdn.net/art…...
Java Spring Boot 控制器中处理用户数据详解
目录 一、获取请求参数1.1 获取查询参数1.2 获取路径参数 二、处理表单提交2.1 处理表单数据 三、处理 JSON 数据3.1 接收 JSON 数据 四、返回 JSON 数据五、处理文件上传5.1 单文件上传5.2 多文件上传 六、总结 在 Spring Boot 应用开发中,控制器(Contr…...
AI产品上市前的“安全通行证“
首席数据官高鹏律师团队 如今AI 产品如雨后春笋般涌现,从智能音箱到自动驾驶汽车,从语音助手到医疗诊断软件,它们正全方位渗透进我们的生活。然而,在 AI 产品迈向市场、走进千家万户之前,有一系列强制性安全认证如同坚…...
sql server 2019 将单用户状态修改为多用户状态
记录两种将单用户状态修改为多用户状态,我曾经成功过的方法,供参考 第一种方法 USE master; GO -- 终止所有活动连接 DECLARE kill_connections NVARCHAR(MAX) ; SELECT kill_connections KILL CAST(session_id AS NVARCHAR(10)) ; FROM sys.dm_ex…...
[滑动窗口]越短越合法(可转化成越长越合法)
题目链接 题意 给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于k 的连续子数组的数目。 首先当ans增加时 我们认为r固定 方法一、转化成越长越合法 思路 算出乘积 ≥ k \ge k ≥k的子数组数量 再用所有子数组数量减去上面算出来…...
idea中编写spark程序
### 在 IntelliJ IDEA 中配置和编写 Spark 程序 要在 IntelliJ IDEA 中高效地开发 Spark 程序,需要完成一系列必要的环境配置以及项目搭建工作。以下是详细的说明。 --- #### 1. 安装与配置 IntelliJ IDEA 为了确保 IDE 可以支持 Scala 开发,首先需要…...
机器学习入门(一)
机器学习入门(一) 文章目录 机器学习入门(一)一、机器学习分类1.1 监督学习1.2 半监督学习1.3 无监督学习1.4 强化学习 二、scikit-learn工具介绍scikit-learn安装 三、数据集3.1 sklearn玩具数据集介绍3.2 sklearn现实世界数据集…...
力扣每日一题之移动零
题目说明: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 思路分析:我们可以考虑使用双指针来解答该题。双指针分…...
GaiaEx 盖亚:从合规出发,一家新兴交易平台的全球化路径探索
在加密货币交易平台日益激烈的竞争中,监管趋严、安全要求提升、用户体验优化已成为行业发展的三大核心议题。2025年初正式上线的GaiaEx 盖亚交易所,正是在这一市场背景下,以“合规 产品 生态”的多维路径,逐步建立起自身的发展方…...