1、Unix/Linux操作系统介绍 1.1、操作系统的作用 1)操作系统的目标
方便:使计算机系统易于使用有效:以更有效的方式使用计算机系统资源扩展:方便用户有效开发、测试、引进新功能 2)操作系统的地位
操作系统在计算机系统中有承上启下的地位,向下封装硬件,向上提供操作接口 1.2、Unix/Linux操作系统介绍 1)Unix 家族
1965年,贝尔实验室,MULTICS 操作系统,失败1969年,Unix 之父,Unics -> Unix,B语言和汇编语言1971年,Unix 之父,C语言,C语言重写 Unix1974年,Unix 流行开来1980年,BSD Unix 和 AT&T 的 Unix1982年,Unix System III,不再开原1992-2001年,版权问题,两个 Unix 分枝逐渐衰败 2)Linux 家族
Minix(mini-Unix),教学使用1990年,Linus,1991年,Linux 内核正式发布Linux 系统的发展五个支柱:Unix 操作系统、minix 操作系统、GNU 计划、PUSIX 标准和互联网GNU 计划:GNU is Not Unix,包括:EMACS编辑系统、Bash shell程序、GCC、GDB等开发工具1992年,Linux 和 GNU 软件结合 -> GNU/Linux(简称 Linux)POSIX 标准:操作系统应该为应用程序提供的接口标准,提高通用性和可移植性 3)Linux 的两类用户
知道自己在用 Linux:Linux 电脑系统不知道自己在用 Linux:处理器、安卓内核等 4)Linux 的远亲
macOS -> Darwin -> BSD -> unix 5)Linux 和 Unix 的联系
Unix 是工作站上最常用的操作系统,多用户、多任务、实时,但是昂贵Linux,类 Unix,免费,Unix兼容的 6)Linux 内核及发行版本介绍
🌈个人主页:聆风吟
🔥系列专栏:算法模板、数据结构
🔖少年有梦不应止于心动,更要付诸行动。
文章目录 📋前言一. ⛳️单调栈讲解1.1 🔔单调栈的定义1.2 🔔如何维护一个单调栈1.3 🔔单调栈的用途1.4 🌟模板总结(重点)🌟1.5 🔔单调栈的实例练习 二. ⛳️单调队列讲解2.1 🔔单调队列的定义2.2 🔔单调队列的用途2.3 🌟模板总结(重点)🌟2.4 🔔单调栈的实例练习 📝结语 📋前言 💬 hello! 各位铁子们大家好哇,今天作者给大家带来了单调栈和单调队列的算法模板讲解,让我们一起加油进步。
📚 系列专栏:本期文章收录在《算法模板》,大家有兴趣可以浏览和关注,后面将会有更多精彩内容!
🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝
一. ⛳️单调栈讲解 1.1 🔔单调栈的定义 定义:栈内的元素是单调递增或单调递减的栈。
1.2 🔔如何维护一个单调栈 单调递增栈:在保持栈内元素单调递增的前提下,如果栈顶元素大于要入栈的元素,将栈顶元素弹出,将新元素入栈。单调递减栈:在保持栈内元素单调递减的前提下,如果栈顶元素小于要入栈的元素,则将栈顶元素弹出,将新元素入栈。
1.3 🔔单调栈的用途 由上图可以看出,对于栈内元素来说:
在栈内左边的数就是数组中左边第一个比自己小的元素;但元素被弹出时,遇到的就是数组中右边第一个比自己小的元素。 对于将要入栈的元素来说:在对栈进行更新后(即弹出了所有比自己大的元素),此时栈顶元素就是数组中左侧第一个比自己小的元素;
由上图可以看出,对于栈内元素来说:
在栈内左边的数就是数组中左边第一个比自己大的元素;但元素被弹出时,遇到的就是数组中右边第一个比自己大的元素。 对于将要入栈的元素来说:在对栈进行更新后(即弹出了所有比自己小的元素),此时栈顶元素就是数组中左侧第一个比自己大的元素;
由此,我们可以看出单调栈的用途是:给定一个序列,指定一个序列中的元素,求解该元素左侧或右侧第一个比自己小或大的元素。
1.4 🌟模板总结(重点)🌟 本文总结的模板是找出每个数左边离它最近的比它大或小的数,右边的可以自行推导(单看模板比较抽象,建议看完下面的题目,在返回来看)
//常见模型:找出每个数左边离它最近的比它大/小的数 int tt = 0;//栈顶指针 for (int i = 1; i <= n; i ++ ) { //check函数是判断查找: //1. 每个数左边第一个比它小的数 //2. 还是每个数左边第一个比它大的数 while (tt && check(stk[tt], i)) tt -- ; stk[ ++ tt] = i; } 1.
在最后有总结,中间对CSMA/CD和CSMA/CA的描述也很详尽
目录
一.CSMA/CD(载波监听多点接入/碰撞检测)
1.截断二进制指数退避算法
2.CSMA/CD协议定义的监听算法有以下三种:
二.CSMA/CA
三.两者异同
一.CSMA/CD(载波监听多点接入/碰撞检测) 为什么要使用CSMA/CD:
因为总线上只要有数据,传输资源时就会被占用,又因为传统总线型以太网采用半双工的通讯方式和最简单的随机接入,所以当计算机以多点接入的方式连接到一根总线上时,会发生冲突碰撞。
在CSMA中,由于信道传播时延的存在,即使总线上两个站点没有监听到载波信号而发送帧时,仍可能会发生冲突。由于CSMA算法没有冲突检测功能,即使冲突已发生,仍然将已破坏的帧发送完,使数据的有效传输率降低。
一种CSMA的改进方案是使发送站点传输过程中仍继续监听媒体,以检测是否存在冲突。如果发生冲突,信道上可以检测到超过发送站点本身发送的载波信号的幅度,由此判断出冲突的存在。一旦检测到冲突,就立即停止发送,并向总线上发一串阻塞信号,用以通知总线上其他各有关站点。这样,通道容量就不致因白白传送已受损的帧而浪费,可以提高总线的利用率。这种方案称为“载波监听多路访问/冲突检测协议”(CarrierSenseMultipleAccess with Collision Detection,CSMA/CD),这种协议已广泛应用于局域网中。
适用场景:
CSMA/CD有线连接的局域网,CSMA/CD 是一种分解访问冲突的协议,应用在竞争发送的网络环境中,适合于传送非实时数据。在网络负载较小时,发送的速度很快,通信效率很高。在网络负载很大时,由于经常出现访问冲突,通信的效率很快就下降了。 注:所以CSMA/CD不适合突发性业务,但帧中继适合突发性业务
不适用于:
在千兆以太网中,当采用半双工传输方式时。要使用 CSMA/CD 协议来解决信道的争用问题。千兆以太网的全双工方式适用于交换机到交换机,或者交换机到工作站之间的点对点连接,两点间可同时进行发送与接收,不存在共享信道的争用问题,所以不需要采用 CSMA/CD 协议。2002 年 6 月发布的万兆以太网 802.3ae 10GE 标准只支持全双工方式,不支持单工和半双工,也不采用 CSMA/CD 协议。
1.多点接入:作用在总线型网络,许多计算机以多点接入的方式连接在一根总线上
2.载波监听:检测总线上有没有其他计算机在传输数据,发送前后每个主机都必须不停地检测信道
3.碰撞检测:边发送边监听,适配器边发送数据边检测信道上的信号电压变化情况,以此判断是否有别人在发送数据。若没有检测到电压,即信道为“空闲”状态,可以发送数据。若检测到极大或极小的电压,就说明有两个及以上主机的信号发生了碰撞(电磁波相遇),此时适配器就会立即停止发送。
如图所示的例子可以说明这种情况。设图中的局域网两端的站A和B相距1km用同轴电缆相连。电磁波在1km 电缆的传播时延约为5s。因此A向B发出的数据,在约5 s 后才能传送到B。换言之,B若在A发送的数据到达B之前发送自己的帧(因为这时 B的载波监听检测不到A所发送的信息),则必然要在某个时间和A发送的帧发生碰撞。碰撞的结果是两个帧都变得无用。在局域网的分析中,常把总线上的单程端到端传播时延记为t。发送数据的站希望尽早知道是否发生了碰撞。那么,A 发送数据后,最迟要经过多长时间才能知道自己发送的数据和其他站发送的数据有没有发生碰撞?从图中不难看出,这个时间最多是两倍的总线端到端的传播时延(2t),或总线的端到端往返传播时延。由于局域网上任意两个站之间的传播时延有长有短,因此局域网必须按最坏情况设计,即取总线两端的两个站之间的传播时延(这两个站之间的距离最大)为端到端传播时延。
注:在使用 CSMA/CD 协议时,一个站不可能同时进行发送和接收(但必须边发送边监听信道)。因此使用 CSMA/CD 协议的以太网不可能进行全双工通信而只能进行双向交替通信(半双工通信)。
对应上图的特殊时刻:
这里的2t称为争用期(contention period),它是一个很重要的参数。争用期又称为碰撞窗口(collision window)。这是因为一个站在发送完数据后,只有通过争用期的“考验”,即经过争用期这段时间还没有检测到碰撞,才能肯定这次发送不会发生碰撞。这时,就可以放心把这一顿数据顺利发送完毕。
4.传播时延是指数据包从发送方到接收方所需的时间,而传输时延是指数据包在发送过程中所花费的时间。为了避免碰撞,我们需要确保在传输时延内能够及时检测到可能的冲突。如果传输时延太短,就可能无法及时检测到碰撞,导致数据丢失。为了确保在传输时延内能够及时检测到潜在的冲突,我们需要设置足够的传输时延,通常是传播时延的两倍。
由此引出了CSMA/CD总线网络中最短帧长的计算关系式:
不知道传输时延和传播时延的区别可以看:
计算机网络中的传输延时与传播延时的区别? - 知乎 (zhihu.com)
例题:
在以太网中出于对(64)的考虑,需设置数据帧的最小帧。
(64)A.重传策略 B.故障检测 C.冲突检测 D.提高速率
【答案】C
【解析】
为了确保发送数据站点在传输时能检测到可能存在的冲突,数据帧的传输时延要不小于两倍的传播时延。
CSMA/CD中避免冲突碰撞的两种方式:1.截断二进制指数退避算法 2.监听算法
目录
1 常用状态码
2 近义辨析
3 所有状态码
1 常用状态码 200:请求成功。
204:无内容,没有返回内容。
301:永久重定向。
302:临时重定向。
400:参数错误,服务器不识别该请求。
401:未授权,非本系统的用户。
403:禁止访问,是本系统的用户,但是没有当前请求的权限。
404:请求的网页不存在。
429:太多请求。(网关限流,你发的请求太多了)
499:客户端主动断开了连接。
500:服务器遇到错误,无法完成请求。
502:网关或代理服务器从上游服务器收到无效响应,很有可能是服务挂了。
503:服务暂时不可用,可以稍候重试。(网关总流量到达上限)
504:网关超时,网关或代理服务器没有及时从上游服务器收到请求。
2 近义辨析 301和302
301:永久重定向。浏览器和搜索引擎会缓存301重定向后的结果,下次访问时直接访问重定向后的网址。302:临时重定向。浏览器和搜索引擎不会缓存302重定向后的结果,下次访问时还是访问原网址。因为302转向可能会有URL规范化及网址劫持的问题,可能被搜索引擎判为可疑转向,甚至认为是作弊,所以被认为是对搜索引擎不友好的。 401和403
401:未授权,非本系统的用户。403:禁止访问,是本系统的用户,但是没有当前请求的权限。 502、503和504
502:服务器作为网关或代理,从上游服务器收到无效响应。 常见的几种502对应的 error_log:
recv() failed (104: Connection reset by peer) while reading response header from upstream
upstream prematurely closed connection while reading response header from upstream
connect() failed (111: Connection refused) while connecting to upstream
503:服务暂时不可用(通常由于超载或停机维护),服务器限流。比如可以在Nginx中配置参数,来限制ip的访问频率 #limit per ip per second access times 10 limit_req_zone $binary_remote_addr zone=allips:20m rate=20r/s; 504:网关或代理服务器没有及时从上游服务器收到请求。网关设置了超时时间,上游服务器没有在规定时间内返回数据,就会返回504。可能确实是服务响应时间太长,也可能是网关配置超时时间太短……(一般,可以把网关的超时时间设置长一点,由具体的客户端应用来决定每个接口可以接收的超时时间。) 所以,这三个状态码的严重程度从高到低依次是:
TinyMCE 编辑器支持粘贴图片,但是自动会将图片转换成 base64 编码,这样将内容提交到后台,数据会很大。
图 | TinyMCE
本文内容配置TinyMCE(版本:5.10.0)向编辑器中粘贴图片自动上传到后台,以下为配置代码:
tinymce.init({ selector: '#textarea', plugins: 'preview autolink directionality visualchars fullscreen image link template code table pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autoresize imagetools paste', paste_data_images: true, //粘贴图片后,自动上传 urlconverter_callback: function(url, node, on_save, name) { console.log('图片链接', url ); return url; }, images_upload_handler: function (blobInfo, succFun, failFun) { var xhr, formData; var file = blobInfo.blob();//转化为易于理解的file对象 xhr = new XMLHttpRequest(); xhr.withCredentials = false; xhr.open('POST', 'upload.php'); xhr.
目录
1、编辑用户
1.1 编辑用户后端接口实现
1.2 编辑用户前端实现
1.2.1 效果图
1.2.2 前端api脚本代码
1.2.3 修改用户脚本代码 2、删除用户
2.1 删除用户后端接口实现
2.2 删除用户前端代码实现 1、编辑用户 1.1 编辑用户后端接口实现 /** * 修改用户 * * @param user * @return */ @PutMapping("/update") @PreAuthorize("hasAuthority('sys:user:edit')") public Result update(@RequestBody User user) { //查询用户 User item = userService.findUserByUserName(user.getUsername()); //判断对象是否为空,且查询到的用户ID不等于当前编辑的用户ID,表示该名称被占用 if (item != null && item.getId() != user.getId()) { return Result.error().message("登录名称已被占用!"); } //调用修改用户信息的方法 if(userService.updateById(user)){ return Result.ok().message("用户修改成功"); } return Result.error().message("用户修改失败"); } 1.2 编辑用户前端实现 1.2.1 效果图 1.2.2 前端api脚本代码 1.
大家好,我是 「负雪明烛」,一位用 7 年写了 1000 篇 LeetCode 算法题题解的程序员。欢迎关注。
粉丝常说:LeetCode 算法题太多了,准备面试该刷哪些题目?
我之前根据 LeetCode 上面的点赞量分享过: LeetCode 上最经典的 100 道题。
这 100 道题目都属于经典题目了,面试也常考,不过我还是不放心呢,毕竟经典题 ≠ 面试题呀!
但如果想知道面试常考的 100 道算法题的话,需要至少整理 1000 篇面经吧?这个工作量可不小啊!
还好,网上有个开源项目,帮我们做了这件事情,这个项目就是 CodeTop!
这是网站的界面(地址:https://codetop.cc/home),展示的就是每个面试题目出现的频度情况,甚至区分了公司和岗位:
这是开源项目的 GitHub 主页,已经 11.5k star ⭐️ 了:
这个项目中的题目来源是牛客网的面经、网友投票等,而且持续更新中,所以还是比较可靠的。
我对这个项目做了整理,分类整理出来面试常考的 100 道算法题。
在整理之后,我对结果还是有点惊讶的!因为一些常见的数据结构与算法,竟然没有在常考面试中出现过!
比如前缀和、前缀树、并查集、图,这些都没有出现……
最常考面试题还是很基本的链表、二叉树、动态规划等等,是不是符合你的认知呢?
强烈建议大家在面试前把这 100 道题目搞懂!
作为宠粉达人,我提供了 3 种方式查看这 100 道题目:
思维导图力扣(LeetCode)题单所有的题目链接 没有任何套路,直接分享给大家!
题目汇总链接 负雪明烛粉丝充值力扣会员福利
现在力扣中国官方和我合作,给我(负雪明烛)的读者一项专属福利:充值季卡会员,多送 2 周;充值年卡会员,多送 2 月!
1945 年时,刚开始有计算机,那时候使用二进制数编程到了40年代末期,出现了汇编器,可以自动将汇编程序转换为二进制数序列1951 年 Grace Hopper 发明了编译器1957 年,Fortran,第一个高级语言,首次亮相接下来就是层出不穷的新编程语言 - COBOL 、 C 、 Pascal 、 C++ 、Java 等等1 经过了几十年的发展,今天的软件与过去的软件本质上仍然是一样的,程序都是由 顺序结构 、分支结构 和 循环结构 组成,再没有出现新的结构。
1958 年 John Mccarthy 发明了 LISP 语言,函数式编程 范式诞生1966 年 Ole Johan Dahl 和 Kriste Nygaard 的论文开创了 面向对象编程 范式1968 年 Edsger Wybe Dijkstra 论证了 goto 语句的危害,结构化编程 范式诞生 经过了几十年的发展,今天的编程范式与过去完全一样,也是结构化编程 范式、 面向对象编程 范式和 函数式编程 范式,再没有出现新的编程范式。
到 1968 年,今天所有的程序结构和编程范式就已经全部出现,从那之后的半个多世纪以来,软件工程领域只是更新了更好的工具以及沉淀了一些构建程序的关键经验。
软件工程的最基本经验是:保持简洁。2
软件设计有两种方式:一种是设计得极为简洁,明显没有缺陷;另一种是设计得极为复杂,没有明显的缺陷。第一种方式要难得多。3
大多数软件禁不起磕碰,毛病很多,就是因为过于复杂,很难通盘考虑。如果不能够理解一个程序的逻辑,就不能确信其是否正确,在出错时,你将更加没有头绪:可能性太多。
Brian Kernighan 认为 “计算机编程的本质就是控制复杂度”。要编写复杂软件而又不至于一败涂地的唯一方法就是降低其整体复杂度——用清晰的接口把若干简单的模块组合成一个复杂软件。如此一来,多数问题只会局限于某个局部,那么就还有希望对局部进行改进而不至牵动全身。
要保持代码简洁,需要艰辛的劳动和严格的职业操守,遵循的原则是“童子军规范”:每次迁入都要比迁出好一些。
要保持架构简洁,需要理解“单一职责原则”、“开闭原则”、“接口隔离原则” 、和“依赖反转原则”。
要保持设计简洁,需要思维上的转变。能删除什么?能简化什么?能重新定义什么?
Postman除了前面介绍的一些功能,还有其他一些小功能在日常接口测试或许用得上。今天,我们就来盘点一下,如下所示:
1.数据驱动
想要批量执行接口用例,我们一般会将对应的接口用例放在同一个Collection中,然后再通过Runner批量执行。这种方式适用于接口用例参数固定的情况下,但也存在另一个问题,如果每次运行时,接口参数都在变化,该如何操作了?
认真看过前面文章的童鞋可能已经猜到,将变量参数化就可以了。但这种方式,存在也存在另外一个问题,就是需要每次将参数提前设置好,比如在Pre-request Script中设置如下:
pm.environment.set("username","Surpass") pm.environment.set("password","Surpass") 使用Pre-request Script设置环境变量并进行赋值不论运行多少次,其实还是用固定的的数据进行测试。
既然以上两种方式都不能解决我们的问题,那将数据写到文件中,然后从文件中读取是不是可以?在Postman中其实也提供了这种方式。
这种用于存放测试数据的文件,一般称之为测试数据集
在Postman中测试数据集支持两种格式csv和json
csv格式
username,password Surpass,Surpass Kevin,Kevin Diana,Diana ... json格式 [ { "username": "Surpass", "password": "Surpass" }, { "username": "Kevin", "password": "Kevin" }, { "username": "Diana", "password": "Diana" } ] 数据格式类似于表格,第一行对应变量名,后面数据对应相应的测试数据
下面来看看操作步骤:
1、打开Run Collection界面,填写运行次数、导入测试数据集,最后点击Run Collection 2、运行结果如下所示: 2.定期任务 Postman提供了一个Monitor功能,支持提交具有定时功能的测试任务,可以按设置的定时器执行接口用例,操作如下所示:
3.接口依赖
接口依赖就是在执行一个接口时,其数据会依赖于其他接口,其本质上是一个接口数据传递的问题。例如:比如在删除用户时,必须要求携带相应的token,而token则是在用户登录后才会产生。
3.1 接口执行顺序
1.默认执行顺序
在Postman中默认的执行顺序,是按照在Collection中的目录顺序执行,即从上到下依次执行。
2.自定义执行顺序
如果按默认的目录顺序执行,通常无法其业务需求,好在Postman提供了一个函数 postman.setNextRequest("你要跳转的接口名"),支持跳转到指定接口执行。例如:在执行完接口用户查询后,跳过接口用户新增,直接跳转执行修改密码,示例如下所示:
1、在用户查询接口Tests中添加如下代码:
if(pm.response.code == 200 && pm.response.text().toString().indexOf("username")!=-1 ){ // 如果 响应码为 200 且 返回body中包含username,则代表查询成功 pm.
目录 一、前言
二 、完成效果
三、 项目包
四、运行项目 (教程)
12月更新: 因为有兄弟想要流畅调用摄像头,我就用MTSP的项目改了一下。
更新项目:Python——yolov8识别车牌2.0-CSDN博客
时间:2023年12月26日12:57:52
一、前言 YOLOv8+LPRNet车牌定位与识别https://www.bilibili.com/video/BV1vk4y1E7MZ/ 最近做了有一个车牌识别的小需求,今天完成了,在此记录和分享 首先,我去了GitHub上面找开源项目,就找到了3个大佬的项目,于是融合一下就完成了 基于YOLOV8的车牌识别的项目参考项目: GitHub - mmastererliu/master_liuContribute to mmastererliu/master_liu development by creating an account on GitHub.https://github.com/mmastererliu/master_liuhttps://github.com/Jai-wei/YOLOv8-PySide6-GUIhttps://github.com/Jai-wei/YOLOv8-PySide6-GUIGitHub - MuhammadMoinFaisal/Automatic_Number_Plate_Detection_Recognition_YOLOv8: Automatic Number Plate Detection YOLOv8Automatic Number Plate Detection YOLOv8. Contribute to MuhammadMoinFaisal/Automatic_Number_Plate_Detection_Recognition_YOLOv8 development by creating an account on GitHub.https://github.com/MuhammadMoinFaisal/Automatic_Number_Plate_Detection_Recognition_YOLOv8 二 、完成效果 三、 项目包 YOLOv8-license-plate-recognize.zip - 蓝奏云文件大小:24.4 M|https://wwwf.lanzout.com/iCY5N0uhltdg下载解压后,可根据下面的提示,运行代码
注意Python版本!要3.8及以上!!!
注意Python版本!要3.8及以上!!!
注意Python版本!要3.8及以上!!!
python>=3.8 四、运行项目 4.1、下载库——ultralytics (记得换源) 记录pip问题(解决下载慢的问题、升级失败问题)_pip升级太慢_Pan_peter的博客-CSDN博客https://blog.csdn.net/Pan_peter/article/details/129553679
# 安装对应版本的库 pip install ultralytics==8.
目录
一、前言
二、关于项目UI
2.1、修改界面内容的文本
2.2、修改界面的图标和图片
三、项目修改地方
四、其他配置问题
一、前言 因为后续有许多兄弟说摄像头卡顿,我在之前那个MATS上面改一下就可以了,MAST项目:基于YOLOv8的多端车流检测系统(用于毕设+开源)-CSDN博客其实这个直接用yolov8的官方api就可以了,然后在画标签那里修改一下代码,就可以了卡顿的原版项目:(这里有配置方法)Python——基于YOLOV8的车牌识别(源码+教程)_车牌识别python代码-CSDN博客 代码包:
YOLOv8-license-plate-recognize-2.zip - 蓝奏云文件大小:42.0 M|https://wwwf.lanzout.com/inCTH1izjrqh配置方法和原项目差不多~如果有配置问题,可以看看下面的内容
二、关于项目UI 因为MATS那个基础项目,就没有用ui文件,所以这个也没有UI文件了
在修改pyside6时,最好有一些这方面的基础
2.1、修改界面内容的文本 可以自行修改ui文件夹里面的main_window.py
2.2、修改界面的图标和图片 1、替换或修改YOLOv8-license-plate-recognize-2\ui\img中的图片(img那个文件夹里面)
2、把resources.qrc中的对应映射进行修改,如果你是添加了文件,就按照那个格式新增就好了
3、使用命令——重新编译为资源文件:pyside6-rcc resources.qrc -o resources_rc.py
重新启动程序,查看是否更新成功
三、项目修改地方 其实,很多东西,原项目都写好了,只需要在画标签那里,自定义一下就好了,把对应的坐标和图片丢给lprr就行了
关于lprr本人一窍不通,只是调用了他的api,然后他可以返回一个车牌的结果
画标签的代码:(写得丑陋,请大佬们指正,Python没有常用,常写)
在yolo.py的333行
# 画标签到图像上 def creat_labels(self, detections, img_box, model): # 画车牌 draw a license plate label_plate = [] xy_xy_list = detections.xyxy.squeeze() class_id_list = detections.class_id.squeeze().tolist() xyxy = [] # 车牌获取 for i in range(len(xy_xy_list)): if isinstance(class_id_list, int) and class_id_list != 0: continue # 如果长度为1,则是int if isinstance(class_id_list, int) and class_id_list == 0: xy_xy_filter = xy_xy_list xyxy.
配置详情 节点k8sdockercontainerdmasterv1.26.024.0.61.6.22node1v1.26.024.0.61.6.22node2v1.26.024.0.61.6.22node3v1.26.024.0.61.6.22 所有节点操作 替换系统源 cat <<'EOF' > /etc/apt/sources.list # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors.cloud.tencent.com/ubuntu/ jammy main restricted universe multiverse # deb-src https://mirrors.cloud.tencent.com/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.cloud.tencent.com/ubuntu/ jammy-updates main restricted universe multiverse # deb-src https://mirrors.cloud.tencent.com/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.cloud.tencent.com/ubuntu/ jammy-backports main restricted universe multiverse # deb-src https://mirrors.cloud.tencent.com/ubuntu/ jammy-backports main restricted universe multiverse # deb https://mirrors.cloud.tencent.com/ubuntu/ jammy-security main restricted universe multiverse # deb-src https://mirrors.cloud.tencent.com/ubuntu/ jammy-security main restricted universe multiverse deb https://mirrors.
1 kafka消息压缩 kafka关于消息压缩的定义(来源于官网):
此为 Kafka 中端到端的块压缩功能。如果启用,数据将由 producer 压缩,以压缩格式写入服务器,并由 consumer 解压缩。压缩将提高 consumer 的吞吐量,但需付出一定的解压成本。
压缩就是用时间换空间,其基本理念是基于重复,将重复的片段编码为字典,字典的 key 为重复片段,value 为更短的代码,比如序列号,然后将原始内容中的片段用代码表示,达到缩短内容的效果,压缩后的内容则由字典和代码序列两部分组成。解压时根据字典和代码序列可无损地还原为原始内容。通常来讲,重复越多,压缩效果越好。比如 JSON 是 Kafka 消息中常用的序列化格式,单条消息内可能并没有多少重复片段,但如果是批量消息,则会有大量重复的字段名,批量中消息越多,则重复越多,这也是为什么 Kafka 更偏向块压缩,而不是单条消息压缩。
2 kafka的消息压缩类型对比 目前 Kafka 共支持四种主要的压缩类型:Gzip、Snappy、Lz4 和 Zstd。关于这几种压缩的特性。
压缩类型压缩率CPU 使用率压缩速度带宽使用率GzipHighestHighestSlowestLowestSnappyMediumModerateModerateMediumLz4LowLowestFastestHighestZstdMediumModerateModerateMedium 从上表可知,Snappy 在 CPU 使用率、压缩比、压缩速度和网络带宽使用率之间实现良好的平衡,我们最终也是采用的该类型进行压缩试点。这里值得一提的是,Zstd 是 Facebook 于 2016 年开源的新压缩算法,压缩率和压缩性能都不错,具有与 Snappy(Google 杰作)相似的特性,直到 Kafka 的 2.1.0 版本才引入支持。
3 何时需要压缩 压缩是需要额外的 CPU 代价的,并且会带来一定的消息分发延迟,因而在压缩前要慎重考虑是否有必要。
压缩带来的磁盘空间和带宽节省远大于额外的 CPU 代价,这样的压缩是值得的。数据量足够大且具重复性。消息压缩是批量的,低频的数据流可能都无法填满一个批量,会影响压缩比。数据重复性越高,往往压缩效果越好,例如 JSON、XML 等结构化数据;但若数据不具重复性,例如文本都是唯一的 md5 或 UUID 之类,违背了压缩的重复性前提,压缩效果可能不会理想。系统对消息分发的延迟没有严苛要求,可容忍轻微的延迟增长。 4 如何开启压缩 Kafka 通过配置属性 compression.type 控制是否压缩。该属性在 producer 端和 broker 端各自都有一份,也就是说,我们可以选择在 producer 或 broker 端开启压缩,对应的应用场景各有不同。目前没有尝试在broker段开启压缩。
背景:在某些使用情况下,单个选择器可能最终加载数万行数据。 将这么多的数据渲染至 DOM 中可能会给浏览器带来负担,从而造成性能问题。 ——vue3+element-plus有现成的轮子。而vue2+element-ui没有。
以下 文章大部分 摘自 源组件中的README.md
Select V2 虚拟列表选择器 基于 Element UI适用于 Vue 2 版本的虚拟列表选择器组件。
在线演示 在线演示
使用说明 安装
npm i el-select-v2 -S 全局引入
//全局引入 import ElSelectV2 from 'el-select-v2'; Vue.use(ElSelectV2); 局部引入
<template> <el-select-v2 v-model="value" :options="options" /> </template> <script> //局部引入 import ElSelectV2 from 'el-select-v2' export default { components: { ElSelectV2 }, data() { return { options: [], value: '', }; }, created() { for (let i = 0; i < 10000; i++) { this.
pycharm安装 安装版本选择链接
激活参考链接
python安装 Windows下载指定python链接
选择相应版本的64位即可。
安装可以自己选择安装位置,记得勾选,add path即可。其余下一步默认即可。
windows临时换源
pip install 模块包名字 -i https://pypi.tuna.tsinghua.edu.cn/simple windows 永久换源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pycharm新建项目 选择项目地址 看个人情况选择
选择环境 pycharm为什么需要创建不同的虚拟环境,因为每个项目,可能涉及的python包的版本不一致,比如pytorch和tensorflow它们的环境需要的依赖不同,且要保证每个项目都能够正常运行。
Previously configured interpreter是使用一个现有的虚拟环境
其他参数说明 Inherit global site-packages选项的作用是,如果勾选它,系统环境中已经安装过的包,你在新建项目时就不用再次安装到你的项目里了。如果不勾选它,则新建的项目还要重新安装所需的包。
Make available to all projects选项的作用是,你在虚拟环境中安装包的同时,也安装到系统环境中。如果你一直遵守系统环境与虚拟环境隔离的原则,这一项也就没必须勾选了。
Create a main.py welcome script选项作用是新建一个main.py文件,它给你创建了一个主程序入口文件。第一次写程序,勾上就行。
错误记录 python 3.12
module 'pkgutil' has no attribute 'ImpImporter'. Did you mean: 'zipimporter'? 错误参考链接
新建的环境需要切换到虚拟环境目录
python -m enseurepip --upgrade
python.exe -m pip install --upgrade pip
pip install setuptools–更新版本
1.问题描述 1.近些年PLC设备及通讯方式的升级,PLC从FetchWrite通讯协议升级Snap7通讯协议
2.服务器升级的主板都是架构在最新的操作系统(2012Server及之后)
3.将原本的程式放置2012Server的OS上,发现在IP网路PING得通的情况下,原通讯程式无法通讯。
2.改善办法 2.1 2012 Server及之后版本,OS的 ECS实例上开启了ECN功能导致该问题,但在传输过程中,如果中间链路的某个设备不支持ECN功能会直接丢弃带有ECN位的数据包,从而导致该问题发生,故需要关闭ENC。
netsh interface tcp set global ecncapability=disabled 2.2 关闭后可以再查询
netsh interface tcp show global
本文主要是介绍了如何利用 POE 提供的 API 服务来驱动原来依赖 OpenAI 的 API 服务
AIGC 的大模型已经火了很久,但是众所周知的原因 OpenAI 的服务订阅对于大陆用户很不友好。而另一个 AIGC 聚合平台 POE 则对大陆用户比较友好,招行的 VISA 和 Master 卡都可以用来订阅付费服务,且目前 POE 提供的 AIGC 模型十分丰富,无论是 GPT-4 还是 Google 家的,甚至还有开源的大模型提供
且最近 POE 也提供了自己的 API 服务,GPT-3.5 Turbo 等模型都是无限量使用,而且链接很稳定且速度很快
https://developer.poe.com
最近实现了一个小功能,就是可以把 POE 的 API 服务进行转换为 OpenAI 的 API 格式,使得原来依赖 OpenAI API 的应用可以用 POE 的 API 进行驱动
https://github.com/ZERO-A-ONE/poe-gpt-api
用起来也很简单,只需要把自己 POE API 的 Token 替换掉,然后在安装必须的依赖后使用如下的指令进行运行
python external/api.py ./poe-openai-proxy 目前写得还比较初级,但是已经可以在 Bob 翻译服务中正常驱动
总之这样我们可以用 POE 提供的 API 来驱动 OpenAI 的 API 应用,只用花一份订阅的钱把所有的服务都享受了
一.题目 二.分析与思路 根据题目按部就班即可,不难发现西电的题目大多都是以一个简单的背景稍作嵌套命题的,主要考察基础知识点的嵌套,本题先计算平均值,再根据给出的公式计算方差,最后遍历所有数据进行判断。主要考察的点在于数据类型的选择和处理,由于开方和除法的操作,很多变量比如总数,均值,方差都使用了类型,此外,由于样本个数为整形,还涉及类型转换。
三.代码实现 #include<bits/stdc++.h>//万能头文件 int main() { int n;//个数为整形 scanf("%d",&n); double num[n];//数据为双精度浮点型 double E_x=0;//期望 for(int i=0;i<n;i++){ scanf("%lf",&num[i]); E_x+=num[i]; }//读入数据并累加到期望中 double n0=n*1.0;//隐式类型转换 E_x/=n0;//求期望 double D_x=0;//方差 for(int i=0;i<n;i++){ D_x+=(num[i]-E_x)*(num[i]-E_x); }//累加到方差中 D_x/=(n0-1);//按照公式求出方差 double SD_x=sqrt(D_x);//按照公式的标准差 int ans=0;//用来储存答案 for(int i=0;i<n;i++){ if(num[i]<E_x-3*SD_x||num[i]>E_x+3*SD_x)ans++; }//判断是否符合条件 printf("%.4lf %d",SD_x,ans);//打印答案,注意中间空格隔开,标准差保留4位小数 return 0; } 四.评价 其实我一开始用的不是这种方法,在概率论中方差和均值有关系的(高中数学也应该见到过):
推导如下:
所以代码就是:
#include<bits/stdc++.h> int main() { int n; scanf("%d",&n); double num[n]; double E_x=0; double E_x_square=0; for(int i=0;i<n;i++){ scanf("%lf",&num[i]); E_x+=num[i];//和 E_x_square+=num[i]*num[i];//平方和 } double n0=n*1.0; E_x/=n0;//E[X] E_x_square/=n0;//E[X^2] double SD_x=sqrt(E_x_square-E_x*E_x);//公式 int ans=0; for(int i=0;i<n;i++){ if(num[i]<E_x-3*SD_x||num[i]>E_x+3*SD_x)ans++; } printf("
🌈个人主页:聆风吟
🔥系列专栏:算法模板、数据结构
🔖少年有梦不应止于心动,更要付诸行动。
文章目录 📋前言一. ⛳️模拟队列1.1 🔔用数组模拟实现队列1.1.1 👻队列的定义1.1.2 👻初始化队列1.1.3 👻向队尾插入一个数 x(入队列)1.1.4 👻从队头弹出一个数(出队列)1.1.5 👻判断队列是否为空1.1.6 👻查询队头元素 1.2 🌟模板提取(重点)🌟1.2.1 👻无详细注释版1.2.2 👻有详细注释版 二. ⛳️题目练习2.1 题目2.2 输入样例2.3 输出样例2.4 c++代码 📝结语 📋前言 💬 hello! 各位铁子们大家好哇,我们上期已经带大家学习了栈的模板,相信爱学习的你都熟练掌握了,如果你还需要查漏不缺可以通过下面专栏自行跳转学习,今天作者给大家带来了队列的算法模板讲解,让我们一起加油进步。
📚 系列专栏:本期文章收录在《算法模板》,大家有兴趣可以浏览和关注,后面将会有更多精彩内容!
🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝
一. ⛳️模拟队列 1.1 🔔用数组模拟实现队列 1.1.1 👻队列的定义 队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。如下图所示:
由于我们使用数组去模拟队列,因此可以将队列看成是一个特殊的数组:这个数组,最前面叫队头,最后面叫队尾。只允许在最后面添加元素,并并且只允许在最前面删除元素。如下图所示:
1.1.2 👻初始化队列 初始状态:我们可以将数组的队头指针指向数组下表为0的位置,队尾指向-1位置,因为满足 tt < hh,所以初始状态队列为空。
代码展示(建议结合图示看注释):
//初始化 //定义一个数组q用于存储队列中的元素 int q[N]; int hh = 0;//hh表示队头 int tt = -1;//tt表示队尾 1.1.3 👻向队尾插入一个数 x(入队列) 根据以上可知:如果我们想向队尾插入一个元素x(即进行入队列操作),我们只需要将队尾指针tt向后移动一位,并将待插入元素 x 存入队尾指针tt指向的位置。
前言 高耦合,低内聚,降低复杂度:在软件迭代中,不关注软件系统结构,导致软件复杂度累加,软件缺乏系统设计,模块混乱,一旦需求增加、修改或者优化,改变的代价无法评估,甚至为了解决一个 bug,引入一个新的 bug。软件设计的核心在于降低复杂性。
一、介绍(关于复杂性) 所有编程都需要具有创造力的头脑和组织思想的能力。
编写软件的最大限制是我们了解所创建系统的能力。随着程序的发展和获得更多功能,它变得复杂,其组件之间具有微妙的依赖性。随着时间的流逝,复杂性不断累积,程序员在修改系统时将所有相关因素牢记在心中变得越来越难。这会减慢开发速度并导致错误,从而进一步延缓开发速度并增加成本。在任何程序的生命周期中,复杂性都会不可避免地增加。程序越大,工作的人越多,管理复杂性就越困难。
仅凭出色的工具,我们只能做些事情。如果我们想简化编写软件的过程,从而可以更便宜地构建功能更强大的系统,则必须找到简化软件的方法。尽管我们尽了最大努力,但复杂度仍会随着时间的推移而增加,但是更简单的设计使我们能够在复杂性压倒性优势之前构建更大,功能更强大的系统。
有两种解决复杂性的通用方法:1)通过使代码更简单、更明显来消除复杂性。例如,可以通过消除特殊情况或以一致的方式使用标识符来降低复杂性。;2)封装,以便程序员在系统上工作而不会立即暴露所有复杂性 ——模块化设计。
由于软件具有很好的延展性,因此软件设计是一个贯穿软件系统整个生命周期的连续过程。开发人员尝试在不改变整体设计的情况下解决问题,将导致复杂性爆炸式增长。因此增量方法适用于软件,可以在实施过程中进行重大的设计更改,但这也意味着永远不会完成软件设计。作为开发人员,应该始终在寻找机会来改进正在开发的系统的设计,并且应该计划将部分时间花费在设计改进上,软件开发人员应始终考虑复杂性。
阅读其他人的代码时,请考虑它是否符合此处讨论的概念,以及它与代码的复杂性之间的关系。在别人的代码中比在您的代码中更容易看到设计问题。阅读代码还将使您接触到新的设计方法和编程技术。
改善设计技能的最好方法之一就是学会识别危险信号:危险信号表明一段代码可能比需要的更加复杂。
二、复杂性的本质 如果设计看起来很复杂,请尝试其他方法,看看是否更简单。某些技术往往会导致设计更简单。
1、复杂性的定义 复杂性与软件系统的结构有关,这使它很难理解和修改系统。在复杂的系统中,要实施甚至很小的改进都需要大量的工作。在一个简单的系统中,可以用更少的精力实现更大的改进。
复杂性是开发人员在尝试实现特定目标时在特定时间点所经历的。它不一定与系统的整体大小或功能有关。具有复杂功能的大型系统若易于使用,那就不复杂。小型而不复杂的系统也可能非常复杂。
复杂性取决于最常见的活动。如果系统中有一些非常复杂的部分,但是几乎不需要触摸这些部分,那么他们对于系统的整体复杂性不会有太大的影响。
C = ∑ p c p t p C=\sum_p c_p t_p C=p∑cptp
系统的总体复杂度(C)由每个部分的复杂度( c p c_p cp)乘以开发人员在该部分上花费的时间( t p t_p tp)加权。在一个永远不会被看到的地方隔离复杂性几乎和完全消除复杂性一样好。
读者比作家更容易理解复杂性。如果编写了一段代码,对自己来说似乎很简单,但是其他人则认为它很复杂,那么它就是复杂的。
2、复杂性的表现 变更放大:复杂性的第一个表现是,看似简单的变更需要在许多不同地方进行代码修改认知负荷:复杂性的第二个标表现,指开发人员需要多少知识才能完成一项任务。较高的认知负担意味着开发人员必须花更多的时间来学习所需的信息,并且由于错过了重要的东西而导致错误的风险也更大。例如一个功能分配了内存,需要开发者自己释放内存,这边增加了开发人员的认知负担。因为如果开发人员忘记释放内存,会造成内存泄漏或者其他不可预见的问题。而在同一个功能模块中增加内存释放,这将减少认知负荷。在考虑认知负荷的条件下,就不再是代码越短就与简单,在能够减少认知负荷的时候,使用更多的代码的实现会更加简单。未知的未知:复杂性的第三个症状是,必须修改哪些代码才能完成任务,或者开发人员必须获得哪些信息才能成功地执行任务,这些都是不明显的。 在复杂性的三种表现中,未知的未知是最糟糕的。对于未知的未知,不清楚该做什么,或者提出的解决方案是否有效。唯一确定的方法是读取系统中的每一行代码,这对于任何大小的系统都是不可能的。甚至这可能还不够,因为更改可能依赖于一个从未记录的细微设计决策。
3、复杂性的原因 依赖性和模糊性
依赖性:当无法孤立地理解或者修改一段给定的代码的时候,便存在依赖关系。该代码以某种方式与其他代码相关,如果更改了给定代码,则必须考虑和/或修改其他代码。依赖关系是软件的基本组成部分,不能完全消除。
模糊性:复杂性的第二个原因是晦涩。当重要的信息不明显时,就会发生模糊。模糊性通常与依赖性相关联。不一致性也会是造成模糊性的一个主要原因:如果同一个变量名用于两个不同的目的,那么开发人员就无法清楚地知道某个特定变量的目的是什么。在许多情况下,由于文档不足而导致模糊不清。对大量文档的需求通常是一个警告,即设计不正确。减少模糊性的最佳方法是简化系统设计。
依赖性导致变更放大和高的认知负荷。模糊性会产生未知的未知,还会增加认知负荷。
4、复杂性是递增的 复杂性不是由单个灾难性错误造成的,而是许多小的复杂性堆积而成。
复杂性的增量性质使其难以控制。
复杂性来自于依赖性和模糊性的积累。随着复杂性的增加,它会导致变化放大,高认知负荷和未知的未知。从而导致每个新的修改,都需要更多的代码才能够实现。
复杂性使得修改现有代码库变得困难且冒险。
三、能跑的代码是不够的 战术思维:能跑就行,尽快跑起来
战略思维:花费时间来设计干净的设计并解决问题。
1、战术编程 战术编程的主要重点是使某些功能正常工作,例如新功能或者 bug 修复。战术编程几乎不可能产生良好的系统设计。
战术编程为了使当前任务尽快完成,会引入一些复杂性或者引入一两个小错误。这就是使系统变得复杂的原因,每个编程任务都会带来一些此类的复杂性。复杂性的累积是迅速的。
2、战略规划 仅仅是 working code 是不够的,为了更快地完成当前任务而引入不必要的复杂性是不被接受的。任何系统中的大部分代码都是通过扩展现有代码库编写来的,因此,最重要的是促进这些将来的扩展。因此,working code 是前提,但是 working code 不是主要目标,主要目标是制作出出色的设计,并且这种出色的设计也是能够解决当前问题的。战略规划在短期内让您放慢脚步,但从长远来看会加快您的速度。