当前位置: 首页 > news >正文

VSOMEIP主要流程的时序

请求服务:

client应用:

​ application_impl::request_service

​ routing_manager_client::request_service (老版本是routing_manager_proxy)

​ routing_manager_client::send_request_services

​ protocol::request_service_command its_command; // 创建订阅cmd

​ local_uds_client_endpoint_impl::send // 将订阅cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request service命令

​ routing_manager_stub::on_message

​ routing_manager_impl::request_service

​ endpoint_manager_impl::find_or_create_remote_client // 从remote_service_info_中查找远端服务的配置,创建client_endpoint

​ tcp_client_endpoint_impl::start // 启动线程进行connect操作 (创建并且打开asio socket,设置socket属性,最后async_connect)

​ udp_client_endpoint_impl::start // 同上

在vsomeip中,每一个服务只占用一个端口(TCP/UDP/BOTH),无论method还是event都在这个端口上通信。

client发给routingmanagerd的cmd中,包含了client的端的clientid

请求事件:

client应用:

​ application_impl::request_event (service, instance, event, eventgroup事件组集合, 事件类型, reliable) //事件类型event/field/select_event

​ routing_manager_client::register_event

​ routing_manager_client::send_register_event

​ protocol::register_events_command its_command; // 注册event的cmd

​ local_uds_client_endpoint_impl::send // 将注册event的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request event命令

​ routing_manager_stub::on_message

​ 轮询protocol::register_events_command中的每一个register event项目

​ routing_manager_impl::register_shadow_event

​ routing_manager_base::register_event //将事件和事件组注册到内部的events_ 和eventgroups_ 中

// routing_manager_base内部events_ 和eventgroups_ 的作用

primitive_types.hpp

...
typedef uint32_t message_t;
typedef uint16_t service_t;
typedef uint16_t method_t;
typedef uint16_t event_t;typedef uint16_t instance_t;
typedef uint16_t eventgroup_t;
...

event.hpp

...
class event {...
private:...// 记录了每个eventgroup有哪些本地client订阅了// 每个event可以属于一个或者多个eventgroupstd::map<eventgroup_t, std::set<client_t> > eventgroups_;...
};
...

eventgroupinfo.hpp

class eventgroupinfo {
...
private:...std::set<std::shared_ptr<event> > events_;    // 记录了该eventgroup中的所有event(event中可以找到订阅该eventgroup的client)...std::map<remote_subscription_id_t,std::shared_ptr<remote_subscription>> subscriptions_;    // 保存对其他域的服务的订阅者的信息remote_subscription_id_t id_;  // 每增加一个对其他域的服务的订阅者(非域内), id_ 加一...
};

routing_manager_base.hpp

std::map<service_t,    			// 服务IDstd::map<instance_t,    // 实例IDstd::map<event_t,   // 事件IDstd::shared_ptr<event> > > > events_;    // 事件所属的组和每个组的订阅客户端std::map<service_t,				// 服务IDstd::map<instance_t,// 实例IDstd::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_;  // 事件组中的事件和每个事件的订阅者信息

订阅:

client应用:

​ application_impl::subscribe

​ routing_manager_client::subscribe

​ routing_manager_client::send_subscribe

​ protocol::subscribe_command its_command; // 订阅cmd

​ local_uds_client_endpoint_impl::send // 将订阅的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的subscribe命令

​ routing_manager_stub::on_message

​ routing_manager_impl::subscribe

​ const client_t its_local_client = find_local_client(_service, _instance); // 获取是哪个client发布了要订阅的服务

​ // 1. 订阅的服务是当前routingmanagerd应用发布的

​ if (get_client() == its_local_client) {

​ endpoint_manager_base::find_or_create_local // 根据订阅者的clientid创建用于通信的local

​ application_impl::on_subscription // 通知application有订阅到达,是否accept (accept_cbk是传入的匿名函数)

​ routing_manager_stub::send_subscribe_ack // 接收订阅,则回复ACK

​ routing_manager_stub::send_subscribe_nack // 否则回复NACK

​ }

​ // 2. 订阅的服务不是当前routingmanagerd应用发布的

​ routing_manager_base::insert_subscription

​ if (_event != ANY_EVENT) { // subscribe to specific event

​ // 在event_中插入订阅client的订阅记录

​ } else {

​ // 在eventgroups_的每个event中插入订阅client的订阅记录

​ }

​ // 2.1 订阅的服务是域外的someip应用发布的

​ if (0 == its_local_client) { // 说明域内找不到提供该服务的ciient

​ routing_manager_impl::find_event // 查看是否有client对该event进行过register(调用request_event)

​ routing_manager_impl::handle_subscription_state //主要是看对该event的订阅是否已经有收到过ACK了

​ if (its_state->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {

​ // Subscription already acknowledged!

​ if (_client == get_client()) {

​ // 如果订阅该服务的是routingmanagerd应用自己,则直接回调

​ application_impl::on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /OK/);

​ } else if (stub_) {

​ // 如果订阅该服务的是域内的其他应用,则通过uds将ACK消息发送过去

​ routing_manager_stub::send_subscribe_ack(_client, _service, _instance, _eventgroup, _event);

​ }

​ }

​ service_discovery_impl::subscribe // 通过SD模块订阅其他域发布的待订阅service/event/eventgroup

​ subscribed_.find //查找之前是否订阅过该eventgroup

​ std::shared_ptr<subscription> its_subscription = create_subscription() // 创建新的订阅

​ subscribed_[service] [inst] [eventgroup] = its_subscription;

​ service_discovery_impl::send_subscription

​ entry_data_t its_data; //创建要订阅的eventgroup的entry (create_eventgroup_entry)

​ auto its_current_message = std::make_shared<message_impl>(); // 创建要发送的OFFER报文

​ add_entry_data(its_messages, its_data); // 将订阅的eventgroup entry添加到OFFER报文中 service_discovery_impl::serialize_and_send // 发送

​ }

​ // 2.2 订阅的服务是域内其他someip应用发布的

​ else {

​ routing_manager_stub::send_subscribe //通过UDS 发送订阅请求给发布该service/Instance的client

​ }

发布服务:

client应用:

​ application_impl::offer_service

​ routing_manager_client::offer_service // 参数中带着clientid以及service的信息

​ routing_manager_base::offer_service // 判断一下是否可以发布service (例如局域网中已经有别的client发布了相同的service/instance)

​ routing_manager_client::send_offer_service

​ protocol::offer_service_command its_offer; // 创建发布服务的cmd

​ local_uds_client_endpoint_impl::send // 将offer service的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的offer service命令

​ routing_manager_impl::offer_service

​ routing_manager_impl::insert_offer_command // 插入OFFER队列 (个人理解用于后期定周期发送)

​ routing_manager_impl::handle_local_offer_service // 判断是否可以Offer Service (是否存在冲突),可以offer的情况下插入local_services_中

​ service_discovery_impl::offer_service // 如果collected_offers_中不存在要发布的service,则添加进去

​ service_discovery_impl::on_offer_debounce_timer_expired // debounce定时器触发,将collected_offers_的offerentry倒出来后清空

​ std::shared_ptr<message_impl> its_message(std::make_shared<message_impl>()); // 创建要发送出去的Offer报文

​ service_discovery_impl::insert_offer_entries //将要offer的所有service entry加入Offer报文

​ service_discovery_impl::insert_offer_service // 添加单个service entry (service的entry以及option,option中包含了用于通信的endpoint信息)

​ service_discovery_impl::add_entry_data

​ service_discovery_impl::send // 发送Offer报文

​ offerservice有三种冲突的情况下,会offer失败:1. local存在相同服务 2. remote发布过相同服务 3. 当前应用本次offer的服务和之前offer的服务存在冲突

处理收到的Offer报文:

routingmanagerd:

​ routing_manager_impl::on_message

​ service_discovery_impl::on_message // 需要是SD报文才会给SD模块处理

​ service_discovery_impl::process_serviceentry // 判断entry’类型是service还是eventgroup的条件是type <= 2

​ service_discovery_impl::process_offerservice_serviceentry // service entry条目中type=1 (offer Service)

​ service_discovery_impl::update_request // 如果目前处于repetition阶段,则停止对该service发送FIND报文(因为已经收到了offer了)

​ if (_received_via_mcast) { // 如果是从组播地址收到的OFFER报文

​ auto found_service = subscribed_ .find(_service); // 从 subscribed_ 成员中查找本域中是否有client对该服务中事件组的订阅

​ 更新每一条订阅记录的状态

​ ST_ACKNOWLEDGED -> ST_RESUBSCRIBING

​ 非ST_ACKNOWLEDGED -> ST_RESUBSCRIBING_NOT_ACKNOWLEDGED

​ }

​ routing_manager_impl::add_routing_info // 新增/更新serviceinfo信息到services_remote_和services_两个内部容器

​ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); // 判断是否收到过该service的offer

​ if (!its_info) { // 没有是收到过该service的offer

​ routing_manager_base::create_service_info // 创建新的serviceinfo信息,添加到services_以及services_remote_中

​ }

​ endpoint_manager_impl::is_remote_service_known // 判断是否在该service上创建endpoint(reliable/unreliable)

​ if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) { // service提供了tcp端口,对应的endpoint没有创建

​ for (const client_t its_client : get_requesters_unlocked(

​ endpoint_manager_impl::find_or_create_remote_client // 创建和service的tcp连接

​ its_info->add_client(its_client); // 将请求该service的client添加到上面create_service_info创建的serviceinfo中

​ }

​ }

​ if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) { // service提供了udp端口,对应的endpoint没有创建

​ // 逻辑同TCP

​ }

​ if (!_reliable_address.is_unspecified() || !_unreliable_address.is_unspecified()) {

​ // 记录每个远端地址上发布的服务信息和收到的Offer报文数量并且打印

​ }

client应用:

​ 无:

entry条目类型的枚举值: (enumeration_types.hpp)

enum class entry_type_e: uint8_t {FIND_SERVICE = 0x00,OFFER_SERVICE = 0x01,STOP_OFFER_SERVICE = 0x01,REQUEST_SERVICE = 0x2,FIND_EVENT_GROUP = 0x4,PUBLISH_EVENTGROUP = 0x5,STOP_PUBLISH_EVENTGROUP = 0x5,SUBSCRIBE_EVENTGROUP = 0x06,STOP_SUBSCRIBE_EVENTGROUP = 0x06,SUBSCRIBE_EVENTGROUP_ACK = 0x07,STOP_SUBSCRIBE_EVENTGROUP_ACK = 0x07,UNKNOWN = 0xFF
};

service_discovery_impl中保存的事件组订阅情况的类Subscription主要结构如下:

class subscription {
...
private:std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;bool tcp_connection_established_;bool udp_connection_established_;std::map<client_t, subscription_state_e> clients_; // client-> is acknowledged?  // 每个client的订阅状态std::weak_ptr<eventgroupinfo> eg_info_;    // 订阅的事件组信息
};

routing_manager_impl中保存的收到的service信息的类serviceinfo主要结构如下:

class serviceinfo {
...
private:service_t service_;instance_t instance_;major_version_t major_;minor_version_t minor_;std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;std::set<client_t> requesters_;   // 请求过该服务的本地client
};

服务可用通知(Service Aailable)

routingmanagerd:

​ client_endpoint_impl::cancel_and_connect_cbk // 作为async_connect的回调函数被调用

​ client_endpoint_impl::connect_cbk

​ endpoint_manager_impl::on_connect

​ routing_manager_impl::service_endpoint_connected

​ routing_manager_impl::on_availability

​ routing_manager_stub::on_offer_service // 通知客户端sevice avaliable

​ routing_manager_stub::inform_requesters // routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE

​ for (auto its_client : service_requests_) { // 该连接是用于和远端service通信的,找到请求了对应service的本地client

​ routing_manager_stub::send_client_routing_info

​ protocol::routing_info_command its_command; // 发送给client的routing_info信息(包含了service信息)

​ }

client应用:

​ routing_manager_client::on_message

​ routing_manager_client::on_routing_info

​ for (const auto &e : its_command.get_entries()) { // 轮询每一个entry (号到type为RIE_ADD_SERVICE_INSTANCE的条目)

​ application_impl::on_availability // 通知application服务可用

​ }

处理订阅:

routingmanagerd:

​ service_discovery_impl::on_message

​ auto its_acknowledgement = std::make_shared<remote_subscription_ack>(_sender); //提前准备好给客户端回复的订阅ACK/NACK报文

​ service_discovery_impl::process_eventgroupentry

​ service_discovery_impl::insert_subscription_ack

​ service_discovery_impl::add_entry_data_to_remote_subscription_ack_msg

​ service_discovery_impl::send_subscription_ack

client应用:

​ 无

处理订阅ACK/NACK

routingmanagerd:

​ service_discovery_impl::on_message

​ service_discovery_impl::process_eventgroupentry(

​ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { // 对于eventgroupentry类型为subscribe_ack/nack

​ service_discovery_impl::handle_eventgroup_subscription_ack/_nack (根据Entry中的TTL判断是ACK还是NACK)

​ auto found_service = subscribed_.find(_service);

​ for (…) { // 找到每一个订阅该eventgroup的client

​ found_eventgroup->second->set_state(its_client, subscription_state_e::ST_ACKNOWLEDGED); // 修改订阅状态 (ACKED)

​ routing_manager_impl::on_subscribe_ack(_client)

​ }

​ }

client应用:

发布事件:

client应用:

routingmanagerd:

发送REQUEST:

client应用:

routingmanagerd:

发送RESPONSE:

client应用:

routingmanagerd:

相关文章:

VSOMEIP主要流程的时序

请求服务: client应用&#xff1a; ​ application_impl::request_service ​ routing_manager_client::request_service (老版本是routing_manager_proxy) ​ routing_manager_client::send_request_services ​ protocol::request_service_command its_command; // 创建…...

右值引用和移动语义:

C 右值引用和移动语义详解 在 C 的发展历程中&#xff0c;右值引用和移动语义的引入带来了显著的性能提升和编程灵活性。本文将深入探讨右值引用和移动语义的概念、用法以及重要性。 一、引言 C 作为一门高效的编程语言&#xff0c;一直在不断演进以满足现代软件编程的需求。…...

经纬高LLA转地心地固ECEF坐标,公式,代码

经纬高转地心地固的目的 坐标系转换是gis或者slam系统常见操作。GNSS获取的一般是经纬高&#xff0c;经纬高在slam系统里无法应用&#xff0c;slam系统一般是xyz互相垂直的笛卡尔坐标系&#xff0c;所以需要把GNSS的经纬高转到直角坐标系地心地固ECEF或者高斯投影GKP。 划重点…...

VUE前端实现天爱滑块验证码--详细教程

第一步&#xff1a; Git地址&#xff1a;tianai-captcha-demo: 滑块验证码demo 找到目录 src/main/resources/static,拷贝 static 并改名为 tac 即可。 第二步&#xff1a; 将改为 tac 的文件&#xff0c;放进项目根目录中&#xff0c;如下图&#xff1a; 第三步&#xff1…...

【链表】【删除节点】【刷题笔记】【灵神题单】

237.删除链表的节点 链表删除节点的本质是不用删除&#xff0c;只需要操作指针&#xff0c;跳过需要删除的节点&#xff0c;指向下下一个节点即可&#xff01; 删除某个节点&#xff0c;但是不知道这个节点的前一个节点&#xff0c;也不知道头节点&#xff01;摘自力扣评论区…...

springboot339javaweb的新能源充电系统pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;新能源充电系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解…...

【嵌入式——QT】QT制作安装包

第一步 QT程序写好之后&#xff0c;编译release版本 第二步 拿到release生成的.exe文件 第三步 新建文件夹deploy 第四步 将.exe文件复制到deploy目录下 第五步 在该目录下输入cmd指令&#xff0c;回车 第六步 在打开的命令窗口下输入 windeployqt TegNetCom_1.0.…...

python的文件操作练习

文件操作&#xff1a;成绩统计 有一个文件grades.txt&#xff0c;文件内容是每行一个学生的成绩&#xff08;格式&#xff1a;姓名,成绩&#xff09;。要求&#xff1a; 读取文件内容&#xff0c;统计所有学生的平均成绩&#xff1b; 将不及格&#xff08;<60分&#xff09…...

jQuery九宫格抽奖,php处理抽奖信息

功能介绍 jQuery九宫格抽奖是一种基于jQuery库的前端抽奖效果。通过九宫格的形式展示抽奖项&#xff0c;用户点击抽奖按钮后&#xff0c;九宫格开始旋转&#xff0c;最终停在一个随机位置上&#xff0c;此位置对应的抽奖项为用户的中奖结果。 本文实现九宫格的步骤为&#xf…...

2024年一级建造师考试成绩,即将公布!

一级建造师考试成绩一般在考试结束后3个月左右的时间公布&#xff01; 根据官方通知&#xff0c;重庆、江苏、青海、江西、云南、湖南、福建、北京、山西、黑龙江等地在今年一建报名通知里提到&#xff1a;2024年一级建造师考试成绩预计于2024年12月上旬公布。考生可在这个时间…...

M4V 视频是一种什么格式?如何把 M4V 转为 MP4 格式?

M4V 是一种视频文件格式&#xff0c;主要由苹果公司用于其产品和服务中&#xff0c;如 iTunes Store 上的电影和电视节目。这种格式可以包含受版权保护的内容&#xff0c;并且通常与苹果的 DRM&#xff08;数字版权管理&#xff09;技术结合使用&#xff0c;以限制内容的复制和…...

Leetcode 每日一题 104.二叉树的最大深度

目录 问题描述 示例 示例 1&#xff1a; 示例 2&#xff1a; 约束条件 题解 方法一&#xff1a;广度优先搜索&#xff08;BFS&#xff09; 步骤 代码实现 方法二&#xff1a;递归 步骤 代码实现 结论 问题描述 给定一个二叉树 root&#xff0c;我们需要返回其最大…...

文件上传漏洞:你的网站安全吗?

文章目录 文件上传漏洞攻击方式&#xff1a;0x01绕过前端限制0x02黑名单绕过1.特殊解析后缀绕过2..htaccess解析绕过3.大小写绕过4.点绕过5.空格绕过6.::$DATA绕过7.配合中间件解析漏洞8.双后缀名绕过9.短标签绕过 0x03白名单绕过1.MIME绕过(Content-Type绕过)2.%00截断3.0x00截…...

AWS账号提额

Lightsail提额 控制台右上角&#xff0c;用户名点开&#xff0c;选择Service Quotas 在导航栏中AWS服务中找到lightsail点进去 在搜索框搜索instance找到相应的实例类型申请配额 4.根据自己的需求选择要提额的地区 5.根据需求来提升配额数量,提升小额配额等大约1小时生效 Ligh…...

电子应用设计方案-29:智能云炒菜系统方案设计

智能云炒菜系统方案设计 一、系统概述 本智能云炒菜系统旨在为用户提供便捷、高效、个性化的烹饪体验&#xff0c;结合云技术实现远程控制、食谱分享、智能烹饪流程优化等功能。 二、系统组成 1. 炒菜锅主体 - 高品质不粘锅内胆&#xff0c;易于清洁和维护。 - 加热装置&#x…...

腾讯rapidJson使用例子

只需要把库的头文件拿下来加入项目中使用就行&#xff0c;我是以二进制文件存储内容并解析&#xff1a; #include <iostream> #include <fstream> #include <string> #include "rapidjson/document.h" #include "rapidjson/error/en.h"…...

UE5_CommonUI简单使用(2)

上篇我是简单写了一下CommonUI使用的初始设置以及Common Activatable Widget和Common Activatable Widget Stack以及Common 控件Style以及鼠标控制的一些内容,这些对于了解UMG的朋友来说没什么难度,唯一需要注意的就是Common Activatable Widget Stack堆栈管理只能是用来管理…...

探讨播客的生态系统

最近对播客发生了兴趣&#xff0c;从而引起了对播客背后的技术&#xff0c;生态的关注。本文谈谈播客背后的技术生态系统。 播客很简单 播客&#xff08;podcast&#xff09;本质上就是以语音的方式发布信息。它和博客非常类似。如果将CSDN 网站上的文字加一个语音播报。CSDN …...

淘宝架构演化

基本功能 LAMP&#xff08;LinuxApacheMySQLPHP&#xff09;标准架构&#xff0c;初期采用拿来主义&#xff0c;只具备基本功能。 数据库&#xff1a;读写分离&#xff0c;MyISAM存储引擎 2003年5月—2004年1月 存储瓶颈 mysql达到访问瓶颈&#xff0c;升级成oracle&#x…...

软通动力携子公司鸿湖万联、软通教育助阵首届鸿蒙生态大会成功举办

11月23日中国深圳&#xff0c;首届鸿蒙生态大会上&#xff0c;软通动力及软通动力子公司鸿湖万联作为全球智慧物联网联盟&#xff08;GIIC&#xff09;理事单位、鸿蒙生态服务&#xff08;深圳&#xff09;有限公司战略合作伙伴&#xff0c;联合软通教育深度参与了大会多项重磅…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...