ubuntu装完gnome后如何moba登录使用

在Ubuntu中安装了GNOME桌面环境后,你可以通过以下步骤设置MobaXterm远程桌面访问: 确保你的Ubuntu系统已经安装了xrdp服务,如果没有安装,可以使用以下命令安装: sudo apt update sudo apt install xrdp 安装GNOME桌面环境(如果尚未安装): sudo apt install gnome-shell 重启xrdp服务以使用新的配置: sudo systemctl restart xrdp 在MobaXterm的远程桌面功能中输入你的Ubuntu机器的IP地址,并且选择X11协议。 点击“OK”按钮,输入你的Ubuntu机器的用户名和密码进行连接。 连接成功后,你将看到GNOME桌面环境出现在MobaXterm的远程桌面会话中。 确保你的Ubuntu防火墙允许通过3389端口(xrdp默认使用的端口)的流量,如果有必要,可以使用以下命令更新防火墙规则 sudo ufw allow 3389 完成以上步骤后,你应该能够通过MobaXterm使用远程桌面功能登录到Ubuntu系统,并使用GNOME桌面环境。

android studio2024最新详解(完全小白)安装-运行第一个程序

前面我用2023最新版本的,死活就卡在引入依赖那里卡了两天,俺的崩溃谁知啊!! 后面我就换了个思维,看着网上大多的教程都是基于2022或者2020的,我就找了个看起来非常详细的视频,里面的是2020的,所以我就下载了2020 。 有点小伙伴可能会找不到android studio的过往版本,这里我就直接复制链接在下面了,根据你自己想要的版本即可下载,但为了该文章每个细节都不会出错,所以建议跟我一样安装,2020的 Android Studio download archives | Android Developers (google.cn) 进去后,滑到网页底部,点击I agree to the terms,然后就有历代版本了。找到2020的,下载即可。另外:当你找到你需要的版本之后,点击它,会展开,里面会有各种对应不同电脑的不同安装包。 下载后,双击运行(我下载的是.exe的程序),双击后弹出的页面(除了你想要该安装目录外)其他什么都不要管,一点到底直至完成安装后,finish即可(最后的那个勾不要取消哦,意思为安装完毕后运行)。 运行后就会出现该页面,就按照它给我们的默认选项点击ok即可(也即是do not那个) 然后又会弹出一个选项,由于我点得太快,没截图,反正不是主程序,这个选项直接退出即可,不过按照我之前安装经验,似乎都没什么问题,不过还是推荐点退出,这个选项的意思是发送什么消息给谷歌,所以无所谓。但,还是推荐退出,不要妥协!!然后呢,又会出现这个 这个是因为我们的电脑没有安装过该类软件,这个时候点cancel即可。 然后就到主页面了 如果你这里出现了什么提示信息,不用管,关掉即可 然后就点击下一步(next) 就选择standard(标准)点击下一步,然后后面的就是一个选择风格的界面了,白色和黑色,随便啦!选好了点击下一步, 点击finish即可,然后就默默的等它吧。全部下载后,点击finish即可,然后就是这样的页面了 接着就是振奋人心万分激动的代码时刻即将来临!!!创建第一个安卓应用(俗称敲代码) 新建项目 选择这个然后点击下一步 然后我把比较重要的两个选择拎出来说 一般没什么问题了,就点击finish了。然后就等它下面的所有加载项完毕即可 第一次的创建项目非常非常慢,所以我呢,希望大家都能坚持自己的热爱,我去找了两种方法,改变这样的情况。我的步骤都是一步接着一步来的哦 现在,进去之后,你会发现下载gradle巨特么慢,所以这里我采用了网上找到的第一个方法,自己下载gradle后,在Android Studio进行配置,如下,就像上面的那样,可以看到Android Studio自己下载的gradle版本号,然后自己去镜像下载,我有这个镜像 Index of /gradle/ (tencent.com) 虽然速度有点慢,但是比Android Studio自己下载得快太多了,下载完毕后,由于前面我用过最新版的2023,即便gradle下载成功后,然后也有一堆gradle配置,也巨特么慢,所以这里就要用到我在网上找到的第二个方法,用以解决后面的gradle下载慢的问题,欸,可能有人问我,那这第二个方法就行了啊,都是gradle,不行哦,我自己试过了,反正我下载到gradle安装包时,巨特么慢。 那么重新说: 在上面的镜像网站下载好Android Studio对应版本的gradle后,先把它解压到.gradle目录下中的dists,然后此时用第二种方法用以加快其他gradle配置速度,进入到.gradle文件目录中,该文件夹一般都在c盘用户文件夹中,找到后,进入,就在.gradle文件夹中创建一个文本文件 init.gradle 添加下列代码 allprojects{ repositories { def ALIYUN_REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public' def ALIYUN_JCENTER_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter' all { ArtifactRepository repo -> if(repo instanceof MavenArtifactRepository){ def url = repo.

【Web】2024 京麒CTF ezjvav题解

目录 step 0 step 1 step 2 EXP1 EXP2 step 0 进来是一个登录框 admin/admin成功登录 访问./source jwt伪造 带着伪造的jwt访问./source,拿到题目源码jar包 step 1 pom依赖有spring、fj、rome 反序列化入口在./Jsrc路由 有两层waf,一个是明文流量层面的检测,一个是反序列化过程的检测,前者可以自定义输出流改写序列化数据绕过 流量层面关于序列化数据明文绕过 waf部分,只看前者的话,就是ban掉了Rome的一些打法 可以打jackson原生反序列化 EventListenerList.readObject -> POJONode.toString -> TemplatesImpl.getOutputProperties Jackson原生反序列化 处理Jackson链子不稳定性 也可以打fastjson原生反序列化 HashMap.readObject->HashMap.putVal->HotSwappableTargetSource.equals->XString.equals->JSONArray.toString-> JSONArray#toJSONString -> TemplatesImpl.getOutputProperties FastJson原生反序列化 step 2 EXP1 自定义输出流 package com.example.jsrc.exp; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; public class CustomObjectOutputStream extends ObjectOutputStream { private static HashMap<Character, int[]> map; static { map = new HashMap<>(); map.

Python 文件操作指南:使用 open 和 with open 实现高效读写

🍀 前言 博客地址: CSDN:https://blog.csdn.net/powerbiubiu 👋 简介 本系列文章主要分享文件操作,了解如何使用 Python 进行文件的读写操作,介绍常见文件格式的读取和写入方法,包括TXT、 CSV、JSON、XML 等,以及如何使用相应的 Python 库来处理这些文件格式,同时对数据进行持久化操作。本章节就从最常见的TXT文件开始。 📖 正文 1 open 文件准备 春眠不觉晓 处处闻啼鸟 迎来风雨声 花落知多少 1.1 读取文件内容 f = open('test.txt', 'r', encoding='utf-8') res = f.read() print(res) f.close() #春眠不觉晓 #处处闻啼鸟 #迎来风雨声 #花落知多少 Tips: 读取文件的时候,这个文件必须存在,否则会抛异常 1.1 内容写入文件 在对文件写入内容的时候,若指定的文件不存在,则会自动创建 f = open('test1.txt', 'w', encoding='utf-8') s = '春眠不觉晓\n处处闻啼鸟\n迎来风雨声\n花落知多少\n' f.write(s) f.close() 但是存在一个问题,如果在执行一次以上代码,文件中的内容被覆盖了,没有实现追加,如果需要实现对文件内容的追加,需要指定参数mode的值为a才能实现追加功能 f = open('test1.txt', mode='a', encoding='utf-8') s = '春眠不觉晓\n处处闻啼鸟\n迎来风雨声\n花落知多少\n' f.write(s) f.close() 1.3 模式详解 mode含义r只读的方式打开文件,文件指针在文件的开头r+读写的方式打开文件,文件指针在文件的开头w打开一个文件只用于写入,并从头开始编辑,原有内容会被删除w+打开一个文件用于读写,并从头开始编辑,原有内容会被删除a打开一个文件用于追加,文件指针在文件结尾a+打开一个文件用于读写,文件指针在文件结尾 这里不涉及对二进制的操作,所以只列举文本操作使用的mode参数。 1.4 文件读写方法 f.

【Qt Creator】跨平台的C++图形用户界面应用程序开发框架---QT

🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1.互联网的核心岗位以及职责2. QT3.QT背景介绍3.1 什么是 Qt3.2 Qt的发展史3.3 Qt支持的平台 4.Qt 版本5.Qt的优点6 Qt的应用场景7.QT的成功案例Linux 桌面环境 KDEWPS Office 办公软件Google Earth 谷歌地图 8.Qt的发展前景及就业分析行业发展方向就业方面的发展前景: 1.互联网的核心岗位以及职责 互联网的核心岗位主要分为 开发岗 互联网开发岗是指负责开发互联网产品的工程师。他们需要掌握多种技能,包括前端、后端、数据库等。 主要分为 后端开发前端开发算法工程师游戏开发等等… 这里面,前端开发又分为 网页前端开发(做网页的)桌面应用开发(做电脑上的应用程序)移动应用开发 测试岗 互联网测试岗是互联网公司中非常重要的一个岗位,主要职责是负责软件测试、功能测试、性能测试、安全测试、自动化测试等相关工作。主要工作内容包括: 编写测试计划和测试用例,根据需求和设计文档编写测试用例。 执行测试,按照测试用例进行测试,并记录测试结果和问题,报告缺陷。 编写测试报告,对测试结果进行分析和总结,并提交给项目负责人和相关开发人员。 参与产品的需求评审、设计评审等工作,为产品的质量提供保障。 熟悉自动化测试工具,能够开发自动化测试脚本,提高测试效率。 运维岗(管理机器) 互联网运维岗位是指负责维护和管理互联网系统、网络和应用程序的技术人员。他们的主要职责包括确保系统和网络的高可用性、安全性和性能,并及时解决出现的故障和问题。常见的互联网运维工作包括服务器管理、网络管理、数据库管理、应用程序部署和监控、性能调优、安全管理等。互联网运维工程师需要熟练掌握多种技术,如Linux操作系统、网络协议、数据库管理、自动化运维工具、云计算等,并且需要具备快速响应、高效沟通和团队协作的能力。 产业经理(非技术岗,目的是提出需求) 互联网产品经理是负责互联网产品的规划、设计、推广、运营等工作的专业人员。他们需要通过市场调研、用户需求分析、竞品分析等方式,制定产品策略、产品规划和设计方案,协调各个部门的工作,确保产品按时上线,并通过数据分析、用户反馈等方式持续优化产品。同时,互联网产品经理还需要有敏锐的市场洞察力、较高的沟通协调能力和团队协作能力。 2. QT QT这个技术主要用于客户端开发,为前端开发的一种,准确的来说QT特指用来进行桌面应用开发(电脑上写的程序)所涉及到的一套技术。 客户端:直接和用户打交道的这一端程序 比如:chrome、QQ音乐、steam… 客户端是指在客户端-服务器模型中,运行在用户计算机上的软件程序,用于向服务器请求服务并接收响应。通俗地说,客户端就是一个用户使用的软件界面,可以通过它来与服务器进行交互。客户端可以是各种各样的应用程序,比如网页浏览器、即时通讯软件、FTP客户端、邮件客户端等等。 需要注意的是,客户端通常需要遵守一定的协议和规范,以便与服务器进行通信和数据交换。常见的客户端协议包括HTTP、FTP、SMTP、POP3等。 服务器:站在客户端背后的男人 服务器是一种计算机硬件设备,可以提供各种服务,如存储数据、运行应用程序、管理网络等。它通常被用作为网络上的中心化存储设备,以提供可靠和高效的数据存储和处理。服务器通常安装了各种不同的软件和应用程序,以满足特定的需求。例如,Web服务器可以用于托管网站和应用程序,邮件服务器可以用于管理电子邮件等。 另外,服务器也可以分为物理服务器和虚拟服务器。物理服务器是指实际的硬件设备,而虚拟服务器是指在同一台物理服务器上运行的多个虚拟服务器实例。虚拟服务器通常使用虚拟化技术来实现,这种技术可以将一台物理服务器划分为多个虚拟机,每个虚拟机都可以独立运行操作系统和应用程序。 虽然大部分的客户端程序,是需要有背后的服务器做支撑的。 但是确实也有些程序,是不需要服务器的.这样的程序(比如画图板,计算器…)同样也是直接和客户打交道,也可以称为“客户端程序" QT无法开发网页前端,也无法开发移动应用 目前QT官方也支持移动应用的开发了,但是目前还没有听说有啥知名的商用移动应用程序是QT开发的 3.QT背景介绍 3.1 什么是 Qt Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展。Qt为开发者提供了一种基于组件的开发模式,开发者可以通过简单的拖拽和组合来实现复杂的应用程序,同时也可以使用C++语言进行高级开发。 图形用户界面:指采用图形方式显示的计算机操作用户界面,是计算机与其使用者之间的对话接口,是计算机系统的重要组成部分。 3.2 Qt的发展史 1991年Qt最早由奇趣科技开发; 1996年进入商业领域,它也是目前流行的Linux桌面环境KDE的基础; 2008年奇趣科技被诺基亚公司收购,Qt成为诺基亚旗下的编程工具; 2012年Qt又被 Digia公司收购;

检测 CSS 中的 JavaScript 支持

最近,我惊喜地发现了一个CSS媒体特性——scripting,它能够在所有现代浏览器中使用。这意味着,我们可以根据用户浏览器是否支持JavaScript来提供不同的CSS规则,从而减少未样式化内容的闪烁或不受欢迎的布局偏移。 使用方法 使用这个特性,我们可以按以下方式渐进式增强样式: @media (scripting: enabled) { .my-element { /* 如果JS可用,增强样式 */ } } 或者,我们可以优雅地回退到一些备选样式: @media (scripting: none) { .my-element { /* 如果JS不支持,使用备选样式 */ } } 还有一个initial-only值,适用于在页面加载期间启用脚本但在之后不启用的情况。CSS媒体查询第5级W3C工作草案中提到了一些它可能有用的场景。 例如,打印页面,或者在服务器上渲染页面并发送给用户的预渲染网络代理。 我个人不太能想象自己会经常使用initial-only,尽管我很想找到更多实际应用中的具体例子。 特性出现之前 在这项特性出现之前,检测JavaScript支持的一种方法是通过在html标签上设置一个自定义选择器——常见的做法是添加一个no-js类名。如果JavaScript得到支持并启用,它会在渲染页面内容之前移除该选择器。当JavaScript被禁用时,我们可以提供适应体验的备选样式。 <html class="no-js"> <!-- 页面内容 --> </html> .no-js .my-element { /* 当JS被禁用时的样式 */ } 组合查询 下面是一个示例,注意到媒体查询被结合起来检查脚本和减少运动的条件。 @media (scripting: enabled) and (prefers-reduced-motion: no-preference) { /* JS可用且运动OK */ } @media (scripting: none), (prefers-reduced-motion) { /* JS已禁用或减少运动已启用 */ } 每个条件当然可以有独家样式,如果预期的结果需要的话,但在规则集有重叠的地方,将它们结合起来也很好。 问题 更新于2024年4月21日 - 在发布这篇文章后,一些反馈浮现出来,解释了这个媒体特性在哪些方面意外地失败了。

贪心算法--区间调度问题

贪心算法 引言 贪心算法是一种简单而有效的算法设计技巧,广泛应用于解决各种优化问题。其基本思想是通过每一步的局部最优选择,最终达到全局最优解。贪心算法通常不会回溯之前的决策,而是基于当前状态作出最优决策,因此其执行效率较高。 原理 贪心算法(Greedy Algorithm)是一种通过每一步的局部最优选择,最终达到全局最优解的算法范式。其核心思想可以概括为以下两点: 贪心选择性质:每一步都选择当前情况下看起来最好的选择,即局部最优解。最优子结构性质:当一个问题的最优解包含其子问题的最优解时,称该问题具有最优子结构性质。贪心算法通过递归地求解子问题,并利用最优子结构性质,保证每一步的选择都是最优的。 由于贪心算法不回溯之前的决策,仅根据当前状态作出最优决策,这使得其执行效率较高,但也限制了其适用范围。贪心算法通常适用于满足贪心选择性质和最优子结构性质的问题,例如最小生成树、最短路径和任务调度等。 应用场景 贪心算法在许多领域都有广泛的应用,特别是在以下几个方面: 最小生成树: 在图论中,贪心算法经常用于构建最小生成树,例如 Prim 算法和 Kruskal 算法。这些算法通过每次选择权值最小的边来构建最小生成树,从而实现图的最优连通。最短路径问题: 在图论中,Dijkstra 算法和 A* 算法等都是基于贪心策略的最短路径算法。它们通过每次选择当前距离最短的顶点来逐步确定起点到其他顶点的最短路径。任务调度问题: 在任务调度问题中,贪心算法可以用于优化任务的执行顺序,以使得总执行时间最小化。例如,按照任务的截止时间或处理时间进行排序,然后依次执行。背包问题: 在背包问题中,贪心算法可以用于近似求解,例如分数背包问题中的分数贪心算法。这种算法每次选择单位价值最高的物品放入背包中,以尽可能达到背包的容量限制并使总价值最大化。区间调度问题: 在区间调度问题中,贪心算法可以用于确定最大数量的互不重叠的区间。例如,会议安排问题中,每次选择结束时间最早的会议安排,以尽可能安排更多的会议。Huffman 编码: Huffman 编码是一种用于数据压缩的贪心算法。它通过构建一棵最优前缀树来实现对字符的编码,使得出现频率较高的字符拥有较短的编码,从而实现数据的高效压缩。 实现贪心算法 本篇我们主要分享的是区间调度问题相关例题。 452. 用最少数量的箭引爆气球 我们以 [[10,16],[2,8],[1,6],[7,12]] 为例: 原气球的排列为: 题目要求求出引爆所有气球所必须射出的 最小 弓箭数 如果按照原来顺序去判断的话,很难找出有重复的气球,所以我们可以对气球先进行排序(按照左边界或者右边界排序都可以,本题我按照左边界排序来进行讲解) 排序后为: 排序了之后我们就可以从上往下遍历去判断是否重合了。 当下面的气球的左边界小于等于上面气球的右边界时,证明两个气球重合,可以用一支箭引爆。 当然下面一个气球有可能和上面两个气球都重合,如果只和上面一个气球重合而不和上上面气球重合的话,那么还需要额外的一支箭去引爆。为了实现判断,当两支气球重合时,我们可以把右边界缩小为两个气球右边界较小的一个值(因为此时新气球的左边界一定大于等于上面两个气球的左边界,所以不用判断),如果新气球左边界小于上面气球的右边界,那么就不需要额外的箭就能引爆。 遍历完所有的气球,我们便可以统计出需要的箭的数量。 下面为代码实现: class Solution { public int findMinArrowShots(int[][] points) { if (points.length == 0) return 0; Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));//不使用a[0] - b[0]而使用Integer.compare(a, b)是为了防止整数溢出 int ans = 1; for (int i = 1; i < points.

HTTPS 的加密流程

HTTPS 本质上就是 HTTP 的基础上增加了一个加密层,抛开加密之后,剩下的部分就和 HTTP 是一样的,在HTTPS中,比HTTP多了一个"S",这里的S是SSL。HTTPS=HTTP+SSL。 HTTPS引入的背景是臭名昭著的运营商劫持 在当年,法律在互联网相关的东西上面还不是很完善 在使用https,加密的过程中,涉及到了密码学中的几个核心的概念 (1)明文:要传输的真正的意识是啥 (2)密文:加密之后得到的数据 (3)密钥:用来加密和解密的重要道具 这个过程简单来说就是,把明文通过密钥变成密文 ,把密文通过密钥变成明文 对称加密和非对称加密 对称加密:加密和解密,使用同一个密钥就行了,加密解密速度比较快。 非对称加密:密钥是一对(分别称为公钥和私钥)加密解密速度比较慢,安全性更高。可以使用公钥加密,此时就是私钥解密。或者可以使用私钥加密,公钥解密. HTTP本身是不安全的,为了能够安全,最简单的做法就是使用对称加密来进行操作 这里有一个问题 对称密钥,当有多个客户端的时候,是要有一个密钥还是多个密钥??所有客户端使用同一个对称密钥,还是每个客户端有一个自己的呢? (1)对称密钥 如果只有一个密钥,黑客使用自己的客户端,不就知道密钥是啥了嘛~~黑客就可以把密文进行解密了呀~~ 所以让每个客户端生成一个自己的密钥,让后告诉服务器就可以了 在这里就又有一个新的问题了,如图所示 在上述过程中,密钥在第一次传输的时候,也可能被黑客获取到,那之后的的加密也就是形同虚设了。 (2)非对称密钥 在这里我们引入非对称密钥,通过非对称密钥,对对称密钥进行加密 引入非对称加密,不是针对后续传输的数据内容展开的,而是只针对对称密钥来进行!! 在上述过程中,客户端持有公钥,服务器持有私钥,通过公钥对对称密钥进行加密,服务器用私钥解密,得到对称密钥。 黑客拿到加密后的对称密钥之后,是无法解密的,使用公钥加密,得拿着对应的私钥来解密,黑客能轻松拿到公钥,但是拿不到私钥 上述过程中看起来很美好,实际上黑客还是有办法获取到原始数据的 (3)中间人攻击 黑客可以自己冒充自己是服务器 在上述过程中,服务器生成一对公钥和私钥(假设是pub和pri),再把公钥发给客户端的途中,黑客获取到,黑客可以自己生成一对公钥和私钥(pub2和pri2),让后把自己生成的公钥发给客户端,让后客户端基于黑客给的公钥来加密密钥,黑客就可以根据自己的密钥来进行解密,得到其中的密钥,让后用服务器给的公钥来加密,再返还给服务器。 此时黑客面对客户端的时候,扮演服务器的角色,面对服务器的时候,扮演客户端的角色,客户端和服务器, 都不知道 黑客的存在~~ (4)解决中间人攻击 最关键的切入点,就是让客户端能够区分出当前的公钥是不是服务器自己的公钥,是不是被伪造出来的公钥~~ 在这里引入第三方公证机构。 公证机构对公钥进行公证,此时客户端看到这个公钥被公证了,就可以认为是合法的了 在上述过程中,服务器上线就会向第三方公正机构申请一个证书,此时服务器就会保存好自己申请道德证书(不是字纸的,而是数字的字符串)。之后返回给客户端 (1)客户端收到证书后,会对证书的合法性进行校验,针对证书中的内容1.发证机构2.证书的有效期3.服务器的公钥4.证书的所有者5.持有者网站的主域名6.数字签名。在上述的6个内容中,只有数字签名是加密的,其他的属性都是明文的。数字签名是前5个内容进行加密得到的,前5个内容计算的校验和为校验和1 (2)针对数字签名进行解密 数字签名是基于公正机构的私钥来加密的,就需要拿着公正机构的公钥来解密,获取公正机构的公钥,不是通过"网络"的方式获取到的!!!通过网络的方式,就可能会得到黑客伪造的公钥,而是操作系统会内置公正机构的公钥!! 公正机构,一共没有多少,你一个操作系统, 就可以在发布的时候,把市面上的公正机构的公钥都打包放到一起。随着安装操作系统,公钥就有了!(系统内置的公钥,一定是正经公钥,不是伪造的!! (3)客户端对比校验和1和校验和2是否相等 接下来,就可以使用公正机构的公钥 (系统内置)来对数字签名进行解密了,解密之后得到校验和 2,客户端会对比校验和1和校验和2是否相等,相等就说明整个证书,都是没有被篡改过的,此时,证书既然都是有效的,证书中包含的公钥自然就是可信的服务器公钥了。 针对公正机构加密的数字签名,进行解密是很容易的,公正机构的公钥是内置到系统中的,用户可以解密,黑客当然也能解密了 黑客很容易能拿到校验和,虽然能拿到,但是无法篡改,也无法伪造!!! 1)如果黑客修改了证书中的公钥,但是不修改数字签名,客户端校验的时候就会发现,自己算出来的校验和和从数字签名中解密出来的校验和,不一致了!!!客户端就可以判定,证书非法! 2)如果黑客修改了公钥, 并且自己重新计算校验和,重新加密得到数字签名?? 黑客不知道公正机构的私钥是啥。黑客只能拿着自己生成的私钥来加密,客户端收到数据之后,肯定是拿着公正机构的公钥来解密,此时就会出现解密失败!!客户端也可以判定,证书非法~~ 大家还记得在安装fidder,开启https的时候,会有一个”安装证书“过程,必须要选同意!! 这个过程就是给你的系统里增加一个公证机构,fiddler的公证机构

5 个不错的开源 AI 网络爬虫工具

你好,我是坚持分享干货的 EarlGrey,翻译出版过《Python编程无师自通》、《Python并行计算手册》等技术书籍。 如果我的分享对你有帮助,请关注我,一起向上进击。 简单地说,网络爬虫就是从网站上抓取数据和内容,然后以 XML、Excel 或 SQL 的形式保存数据。除了潜在客户挖掘、竞争对手监控和市场调研之外,网络爬虫工具还可用于实现数据收集过程的自动化。 在人工智能网络爬虫工具的帮助下,可以解决手动或纯粹基于代码的爬虫工具的局限性:动态或非结构化网站现在也可以轻松处理,都无需人工干预。 在此,我们将介绍几款开源 AI 网络爬虫工具供您选择。 Reader LLM Scraper Firecrawl ScrapeGraphAI LangChain Reader reader-star-history Reader是 Jina AI 推出的一款产品。当你将任意网址附加到https://r.jina.ai/之后,它可以将任何 URL 转换为 LLM 友好的输入,并免费获得可用于 RAG 系统的结构化输出。 自上个月(确切地说是 4 月 15 日)首次发布以来,全球累计请求量已超过 1800 万个请求,而项目本身也已经获得了 4.5K 个星标。 reader 除了爬取任意 URL 之外,Jina 还发布了另一项功能,即可以使用 https://s.jina.ai/YOUR_SEARCH_QUERY 搜索互联网上的最新知识。搜索结果包括标题、LLM友好的markdown文本 和注明来源的 URL。 这样就可以为 LLM、智能体和 RAG 系统构建一个全面的解决方案。 reader-knowledge LLM Scraper llm-scraper-star-history LLM Scraper 是一个 TypeScript 库,可通过 LLM 将任何网页转换为结构化数据。本质上,它使用函数调用将网页转换为结构化数据。 与 Reader 类似,它也是上个月才开源的。它目前支持本地(GGUF)、OpenAI 和 Groq 聊天模型。显然,作者正在努力通过 llama.

【C++】从零开始map与set的封装

送给大家一句话: 今日的事情,尽心、尽意、尽力去做了,无论成绩如何,都应该高高兴兴地上床恬睡。 – 三毛 《亲爱的三毛》 🌃🌃🌃🌃🌃🌃🌃🌃🌃 🌏🌏🌏🌏🌏🌏🌏🌏🌏 从零开始map与set的封装 1 前言2 红黑树的迭代器3 map与set的封装3.1 红黑树的改进3.2 map的封装3.3 set 的封装 4 总结Thanks♪(・ω・)ノ谢谢阅读!!!下一篇文章见!!! 1 前言 为了map与set 的封装,我们进行了非常充足的知识储备!!! 首先,为了了解map 与 set 的底层原理我们开始学习二叉搜索树,二叉搜索树在二叉树的基础上增添了: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树注意通常二叉搜索树不会有相同的键值 这样可以在一定程度上满足高效搜索的需求,但是在极端的情况(单子树情况)其效率会下降到O(n)。因此就有了改进的二叉搜索树:AVL树和红黑树。他们都增加一些特性使其最大程度上近似平衡二叉树! AVL 树 和 红黑树 都是在保持二叉搜索树基本性质的基础上,通过旋转和重新平衡等操作,确保树的高度保持在一个相对平衡的状态,从而保证了操作的时间复杂度始终为 O(logn)。它们的出现大大提高了二叉搜索树在实际应用中的性能和稳定性。 AVL树增加了以下特性: 它的左右子树都是AVL树左右子树高度之差(简称平衡因子)的绝对值不超过1(-1 / 0 / 1 ) 在平衡因子超出要求就会进行旋转,旋转分为:右单旋 ,左单旋,左右双旋,右左双旋。 红黑树加入以下特性: ⚠️每个节点要么是红色,要么是黑色。⚠️根节点必须是黑色的。⚠️如果一个节点是红色的,则它的两个子节点必须是黑色的。⚠️对于任意一个节点,从该节点到其所有后代叶子节点的简单路径上,必须包含相同数目的黑色节点。⚠️每个叶子节点都是黑色的。这里的叶子节点指的是为空的节点。 在不满足规则时也会进行旋转。但是旋转的频率比AVL树要少很多,红黑树是只是接近平衡,AVL树几乎就是平衡的! map与set大多数情况是用来检索的工具,我们底层使用红黑树来完成map与set的封装。 进行封装之前,我们先来实现一个非常重要的东西:迭代器 2 红黑树的迭代器 迭代器的好处是可以方便遍历。如果想要给红黑树增加迭代器,需要考虑以前问题: 迭代器的框架如何实现,才能满足泛型编程的需求??STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序的序列,因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,这里为了方便就给nullptr。operator++()与operator–()要如何实现?这里的++和–要满足中序遍历的顺序,就不能简单的进行指针的移动了! 接下来我们来逐个实现。 首先我们来搭建一下迭代器的框架 // 迭代器 //T 表示数据类型 Ref为引用 Ptr为指针 template<class T , class Ref , class Ptr> struct _RBTreeIterator { //为了方便调用,我们重命名一下 typedef RBTreeNode<T> Node; typedef _RBTreeIterator<T, Ref, Ptr> Self; //内部是节点指针 Node* _node; _RBTreeIterator(Node* node) :_node(node) {} //两种指向方式 Ref operator*() { return _node->_data; } Ptr operator&() { return &_node->_data; } bool operator!

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(一)音频数据编码与预处理

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的,主流落地领域主要有:视觉,听觉,AIGC这三大板块。目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相关联的,其实语音模块在近来市场上面活跃空间很大。从智能手机的语音助手到智能家居中的语音控制系统,再到银行和电信行业的语音身份验证,语音技术的应用日益广泛。那么对应现在ACG技术是可以利用原音频去进行训练学习,从而得到相对应的声音特征,从而进行模仿,甚至可以利用人工智能生成的语音可以以假乱真,给社会带来了严重的安全隐患。 当前,语音深度鉴伪识别技术已经取得了一定的进展。研究人员利用机器学习和深度学习方法,通过分析语音信号的特征,开发出了一系列鉴伪算法。然而,随着生成大模型和其他语音合成技术的不断进步,伪造语音的逼真度也在不断提高,使得语音鉴伪任务变得愈加复杂和具有挑战性。本项目系列文章将从最基础的语音数据存储和详细分析开始,由于本系列专栏是有详细解说过深度学习和机器学习内容的,音频数据处理和现主流技术语音分类模型和编码模型将会是本项目系列文章的主体内容,具体本项目系列要讲述的内容可参考下图: 语音模型的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。不过我会尽可能将知识简化,转换为我们比较熟悉的内容,我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。希望有需求的小伙伴不要错过笔者精心打造的专栏。 那么本系列文章第一节我们将解答音频常见存储载体和其特征,以及音频的数据保存形态有哪些?具体数据可视化展示为何种形式?也就是我们第一部要了解声音是如何转换为数据的,是如何编码保存的。 一、音频数据编码 音频数据的编码和解码是将声音信号转换为数字信号以及将数字信号还原为声音信号的过程。不同的音频文件格式采用不同的编码方式来保存音频数据。音频数据的编码方式主要有两类:未压缩编码和压缩编码。未压缩编码保留了原始音频数据,而压缩编码则通过各种算法减少音频数据的大小,可以是有损压缩或无损压缩。 1.1未压缩编码 未压缩编码保存音频数据的原始信息,主要采用脉冲编码调制(PCM)方式。 1.1.1 脉冲编码调制(PCM) PCM是最常见的未压缩音频编码方式。它直接对模拟信号进行采样、量化和编码,将声音波形转换为数字信号。总共有三步: 采样:以固定的时间间隔对模拟信号进行采样,得到离散的时间点。 将连续的模拟音频信号在时间上以固定的间隔进行采样,得到离散的时间点。采样频率(如44.1kHz)决定了每秒钟采样的次数。高采样率能够更准确地表示原始信号,但也会产生更多的数据。 量化:将每个采样点的幅值转换为最接近的离散值,通常使用16位或24位表示。 量化位数(如16位、24位)决定了每个采样点的精度,量化的过程会引入量化误差,位数越高,误差越小,音质越好。 编码:将量化后的值编码为二进制数,形成数字信号。 通常使用整型数表示量化后的幅值。 我们可以使用Python编码实现PCM编码: import wave import numpy as np # 生成一个1秒的1kHz正弦波 sample_rate = 44100 # 采样率:44.1kHz,CD质量 frequency = 1000 # 频率:1kHz duration = 1.0 # 持续时间:1秒 t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False) # 时间点 signal = 0.5 * np.sin(2 * np.pi * frequency * t) # 正弦波,幅值为0.5 # 量化为16位PCM signal_int16 = np.

使用Excel转JSON加载项快速将单元格转换为JSON的教程

1. 引言 在数据处理和数据交换过程中,将Excel表格中的数据转换为JSON格式是一项常见任务。使用Excel转JSON加载项,您可以轻松地将Excel单元格数据转换为JSON格式,以便更好地进行数据分析、数据交换和数据存储。 2. 安装Excel转JSON加载项 按照以下步骤安装Excel转JSON加载项: 打开Excel:打开Excel应用程序。 转到"文件"选项:在Excel界面的顶部菜单中,点击"文件"选项。 选择"选项":在"文件"选项下拉菜单中,选择"选项"。 打开"加载项":在Excel选项窗口中,选择"加载项"选项卡。 点击"Excel加载项":在"加载项"选项卡下方的列表中,点击"Excel加载项"。 点击"转到"按钮:在Excel加载项窗口中,点击"转到"按钮。 下载Excel转JSON加载项:Excel将自动打开浏览器,并跳转到Excel转JSON加载项的下载页面。按照页面上的指示下载加载项并保存在您的计算机上。 安装加载项:双击下载的加载项文件,按照安装向导的指示进行安装。 完成安装:安装完成后,重新启动Excel应用程序。您将在Excel的"加载项"选项卡中看到"Excel转JSON"工具栏出现,表示加载项已成功安装。 3. 使用Excel转JSON加载项进行转换 按照以下步骤使用Excel转JSON加载项进行转换: 打开Excel文件:打开包含您要转换为JSON的数据的Excel文件。 选择数据范围:选择您要转换为JSON的数据范围。可以是单个单元格、一行、一列或整个表格。 点击"Excel转JSON"工具栏:在Excel界面的顶部菜单中,点击"Excel转JSON"工具栏上的相应按钮。 配置转换选项:Excel转JSON加载项将弹出一个窗口,提供一些转换选项,例如设置JSON键名、选择转换方式等。根据您的需求进行配置。 点击"转换"按钮:在转换选项配置完成后,点击窗口中的"转换"按钮。 保存JSON文件:Excel转JSON加载项将根据您的配置生成JSON文件。选择保存位置和文件名,然后点击"保存"按钮。 完成转换:转换完成后,您将获得一个包含Excel中数据的JSON文件。

视频汇聚管理平台EasyCVR程序报错“create jwtSecret del server class:0xf98b6040”的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力,平台支持7*24小时实时高清视频监控,能同时播放多路监控视频流,视频画面1、4、9、16个可选,支持自定义视频轮播。 用户反馈,视频汇聚管理安防监控平台EasyCVR突然无法启动,于是联系我们进行排查。 1)技术人员使用进程启动查看到程序报错“create jwtSecret del server class:0xf98b6040”,提示是集群的错误。 2)对其集群配置进行排查发现,现场并未使用集群相关配置。 3)于是对程序文件深入排查,原来是private文件被更改导致程序无法启动。 4)替换相同的private文件后,程序启动恢复了正常。 视频汇聚综合管理平台EasyCVR视频监控系统支持多协议接入、兼容多类型设备,平台能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理。视频监控/集中存储系统EasyCVR平台可支持国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议与SDK,如:海康ehome、海康sdk、大华sdk、宇视sdk、华为sdk、萤石云sdk、乐橙sdk,兼容Windows系统、Linux系统以及国产化操作系统等。感兴趣的用户可以前往演示平台进行体验或部署测试。

【Fiddler抓包工具】第五节.安卓、IOS抓包+fildder插件

文章目录 前言一、HTTPS抓包 1.1 HTTPS与HTTP区别 1.2 HTTPS抓包设置过程 1.3 错误解决方法 1.4 验证证书是否安装成功 1.5 Firefox HTTPS请求捕获二、IOS设备APP抓包 2.1 APP抓包Fiddler设置 2.2 APP抓包IOS设备设置 2.3 Android设备设置 2.4 安装证书解密HTTPS三、Fiddler插件工具总结 前言 一、HTTPS抓包 1.1 HTTPS与HTTP区别 HTTPS 在HTTP 的基础下加入SSL/TLS,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 所以证书 里还有对称、非对称的加密 密钥 公钥。 1.2 HTTPS抓包设置过程 HTTPS抓包设置过程操作步骤: 1.点击Tools > Options >HTTPS2.勾选Decrypt HTTPS Traffic3.如果提示下载证书,就下载安装4.注意点,IE和Chrome都是读系统的证书,如果要Firefox的证书默认自己管理。修改过程在下一章。 图示说明: 1.3 错误解决方法 如果没抓到,可以尝试重装证书:Actions > Reset All Certificates > 确定 图示说明: 1.4 验证证书是否安装成功 目的:验证证书是否安装成功,如果不成功一定无法捕获https请求 验证步骤: 步骤1:进入windows证书管理界面,可以从fiddler进入,也可以直接搜索cert进入 步骤2:操作>查找证书>输入fiddler>存在证书,如果没有即安装证书失败,尝试上一步重新安装。 步骤3:打开百度之类的网站有https请求可以捕获。 1.5 Firefox HTTPS请求捕获 注意: 自己管理证书,不和上面一样,所以要更改为使用系统代理,版本不一样不一定如图片一样的位置,但过程都一样。 Firefox HTTPS请求捕获操作步骤:

AI漫画推文:Stable Diffusion 保姆级入门教程

AI技术的崛起已经改变了我们生活的方方面面,包括创作领域。 最近AI漫画推文成为了一个备受欢迎的趋势,让小说推文以一种全新的视频形式呈现在观众面前。 本文将介绍Stable Diffusion,一款强大的AI绘图工具,以及如何使用它来创建高质量的AI漫画推文。 AI漫画推文:小说推文的全新形式 AI漫画推文本质上仍然是小说推文,只是在呈现方式上有了巨大的创新。不论是游戏视频、解压视频还是美食视频,理论上都可以通过AI漫画推文的形式呈现出来。 那么,为什么我们需要学习AI漫画推文呢? 事实上,如今越来越多的人开始从事小说推文,而大部分初学者通常使用视频素材,这使得这个领域竞争非常激烈,起号也变得非常困难。而AI漫画是目前最容易入门且效果最出色的小说推文形式之一。 然而,需要牢记的是,AI漫画作图只是小说推文项目的一部分,选文和改文仍然是最重要的环节。 在这篇教程中,我们将重点介绍如何学习和使用AI绘图软件Stable Diffusion,其他小说推文环节可以参考其他资源。 Stable Diffusion教程目录 一、软件安装 软件安装可以分为本地安装、云端部署和云电脑三种方式。本文主要介绍后两种方法,它们相对更容易上手。 1. 云电脑 云电脑是一种在线租用高性能电脑的方式,其中已经预装了Stable Diffusion。虽然价格稍高(约2.5元/小时),但安装非常方便。 打开云电脑客户端,选择华南4地区并添加一个云桌面。 在定制产品中选择SD-绘唐定制。 启动云桌面,进入SD的操作界面。 2. 云端部署 云端部署需要使用云服务器,常见的云平台有谷歌云、阿里云、AutoDL等。这种方法相对复杂一些,但更经济(约1.58元/小时)。 在云平台租用服务器,选择GPU型号和数量。 选择社区镜像并输入novelAI,选择相关镜像后创建服务器。 启动服务器,进入JupyterLab,运行相应代码块。 启动SD的WebUi,等待成功运行。 二、界面及主要参数讲解 Stable Diffusion的界面和主要参数对于创作至关重要。 以下是一些主要参数的解释: 大模型:决定图片整体风格基调,如写实、古风、动漫等。 外挂VAE:有的大模型需要特定的VAE,例如animevae、840000。 正向提示词:希望画面中出现的元素。 反向提示词:不希望出现在画面中的元素。 LORA:用于微调模型,固定人物形象、动作等。 采样方式:影响噪点,可选择Euler a、DPM++ SDE Karras等。 迭代步数:决定图片质量,常用范围为20-30步。 面部修复/高清修复:可让图片更清晰,但耗时较长。 图片大小:常用大小为512x512或512x768(竖版)。 生成批次/每批次数:每次生成图片的数量。 三、大模型和Lora加载 选择合适的大模型和LORA对于图片的风格和效果至关重要。各种模型和LORA可在不同网站下载,也可以使用已准备好的模型和LORA。 四、提示词写法 提示词直接影响画面内容和质量,准确的提示词可以帮助您创建理想的图片。提示词应分为正向和负向提示词,详细分解成图像质量、主要元素和细节。 当需要强调某个提示词时,可以使用符号()或(提示词:1.2)来增加其权重。 五、高质量出图 除了模型、LORA和提示词,其他参数也会影响图片质量。初次出图时,建议将面部修复和高清修复保持未勾选,步数设置为20,图片大小可选择512x512或512x768,生成批次为4/1。 如果生成的图片效果不理想,可以多次尝试,或者尝试修改提示词。在需要时,可以使用高清修复工具对图片进行二次绘制。 总结 AI漫画推文是小说推文的一种创新形式,Stable Diffusion为您提供了强大的创作工具。 然而,不要忘记,除了AI绘图,选文和改文依然是小说推文项目中最重要的环节。 如果您能在这三个方面都达到极致,那您的创作定会脱颖而出。祝愿您在AI漫画推文的创作之路上取得巨大成功! 写在最后 感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能等前沿科技教程和软件工具,具体看这里。 AIGC技术的未来发展前景广阔,随着人工智能技术的不断发展,AIGC技术也将不断提高。未来,AIGC技术将在游戏和计算领域得到更广泛的应用,使游戏和计算系统具有更高效、更智能、更灵活的特性。同时,AIGC技术也将与人工智能技术紧密结合,在更多的领域得到广泛应用,对程序员来说影响至关重要。未来,AIGC技术将继续得到提高,同时也将与人工智能技术紧密结合,在更多的领域得到广泛应用。 一、AIGC所有方向的学习路线 AIGC所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。 二、AIGC必备工具 工具都帮大家整理好了,安装就可直接上手! 三、最新AIGC学习笔记 当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。 四、AIGC视频教程合集

人工智能时代的程序设计教学与课程设计

声明:本文已经投稿至“2024年中国高校计算机教育大会”,并发表于微信公众号“于仕琪”,可以转载,但不可修改。 作者:于仕琪,郑锋,廖琪梅,田蕾 单位:南方科技大学计算机科学与工程系 摘要:随着人工智能的兴起,学生对编程的热情逐渐从C/C++向Python迁移,对于计算机硬件体系结构的理解也呈现逐年下降的趋势。当前许多人工智能从业者做的是人工智能算法设计,但参与基础人工智能软件开发的相对较少。我们认为本科生教育中应该加强基础软件开发的教学,可利用学生对人工智能的热情,培养学生开发基础底层软件平台的能力。本文作者在多年教学中,面向人工智能时代的社会需求,将一门传统的程序设计课程“C/C++程序设计”,逐年优化和改进成为一门包含多项内容的“高级计算机程序设计”课程。该课程通过引入开源项目作为案例,向学生传授C和C++的独特优势,介绍多种CPU架构、GPU编程、计算瓶颈分析、各种开发工具和新型Rust语言等内容。这些内容让学生更加深入地理解程序设计,提升了教学质量,课程受到了学生的广泛欢迎。 关键词:程序设计,人工智能,C,C++,Rust 导言 目前人工智能已经成为热门的方向,大量的科研和技术人员投入其中。在科研人员中,大部分人的工作是深度学习算法设计,即利用开源的PyTorch或其他深度学习训练库,设计不同的深度网络结构,并在各种数据集上进行训练和评估。而在人工智能框架开发方面,例如优化计算效率、发挥硬件性能方面只有相对较少的人员投入。从国家需求来讲,我们需要在人工智能软硬件的基础架构有人才和技术积累。 计算机和人工智能创新想法的验证需要程序设计,其中C和C++语言是大部分基础软件的实现语言,有着重要的地位。C和C++编程语言因为语法复杂,很多学生即使进行了系统学习,仍然难以编写出稳定且少错的程序,尤其是其中的指针和内存管理机制,令无数学生困扰不已。随着人工智能的发展,Python编程语言的使用率日益提升,有的学生认为学好Python就足够了。当学生的就业方向是网络开发或者移动应用开发时,会认为熟悉Java已经足够;如果就业方向是网页前端开发,会觉得HTML/JavaScript足够。这样的现状让很多学生缺乏学习C/C++的热情,甚至质疑学习C/C++的必要性。其实不然,从学生的职业规划来讲,深厚的计算机基础可以打破“35岁退休”魔咒。如果只追技术热点而缺少深入理解,学生的职业发展难以达到较高的层次。 1. 目前面临的困难 1.1 学生需要精通多门编程语言 程序设计是计算机和人工智能等相关专业本科生的一项基本能力。随着技术发展和需求的拓宽,学生除了掌握C和C++编程语言之外,还需要掌握Java、Python甚至JavaScript等语言。此外,一些新型的编程语言如Rust也展示了潜力,需要学生有所了解甚至需要掌握。这么多编程语言,在本科生教育中为每种语言开设相应的课程不太现实,因为这会挤压其他课程的课时,无法在培养方案中实施。 当前大部分学校将C语言作为本科教育的第一门编程语言,并辅以C++或Java作为第二门编程语言课,也可能将Python作为选修课程。C和C++作为两门课,因这两门语言的基础语法有较大重合度,会面临内容重复的问题。如果在C++课程中不讲C课程中的基础语法,那么只能讲C++的高级特性,而C++最近20年的技术路线非常激进,引入了大量的新特性,但学生缺乏工程基础,即使学了许多C++新特性,也难以理解为何需要这些新特性,无法将之变成真正的知识并进行应用。 C和C++语言中的指针和内存管理是其精髓和特色,同时也是其难点,有大量的学生无法深入理解并掌握这个知识点。C和C++的语法规则因为历史原因有大量晦涩的知识点,不像Java那样直白简单。例如C和C++中基本数据类型的变量默认不进行初始化,内存管理不善容易泄露或者重复释放,进而导致程序崩溃。这让学生的程序中有大量的BUG,让学生的自信心严重受挫。要深层理解程序的运行,除了理解内存还需要理解CPU缓存和寄存器。行业的发展需要学生精通多门编程语言,但现实却并非如此,大部分学生连一门编程语言都无法精通。 1.2 人工智能时代C/C++的不可替代性 因为学习C和C++语言面临诸多困难,有些学生甚至认为现在进入人工智能时代了,会用Python就足够了,甚至不会编程也可以,因为有ChatGPT这类工具自动生成代码。深度学习的热潮带来Python语言热,Python语言因为易于实现想法,所以广泛应用于深度学习的训练和部署中。如果我们“近距离”看一下人工智能基础软件,便会发现Python主要应用在算法设计和部署中,底层软件如PyTorch和TensorFlow都是用C或C++实现,编译成高效率的Python包供调用。如果底层硬件是英伟达的GPU,那么需要调用CUDA库实现各种算法;如果底层是华为的昇腾GPU,那么需要用华为的Ascend C接口和相关编译器。 使用最广泛的操作系统Linux是使用C语言开发,编译器GCC是C语言,数据库管理系统如MySQL和PostgreSQL是C语言,开源计算机视觉库OpenCV是C++语言。也就是说,目前大部分计算机领域的基础软件是采用C或C++实现。虽然新型的编程语言Rust很有前景,但尚未成广泛生态。在未来的若干年内,C和C++语言在计算机基础软件开发中依然不可替代。我们的人才培养,不仅需要培养人工智能算法设计方面的人才,更需要培养有着深厚计算机基础的系统开发人才。我们无法建立“空中楼阁”,ChatGPT的成功也凸显芯片、通信、计算机体系结构、编译器等基础开发愈发重要。 1.3 教学中的问题 在程序设计课程教学中,课程容易沦为“语法规则课”,课程的目的容易降低为“语法规则学习”。在这种低要求下,培养出的学生只会将简单代码输入IDE(集成开发环境),然后点击“运行”按钮验证结果。学生不理解“编译”“连接”等基本编程概念,也缺乏开发大一点规模软件的经验。程序设计课程中的例子往往比较简单,可以帮助理解语法规则,但学了这些有什么用,必须使用一些真实的案例来回答。受限于高校教师一般缺乏工业界的工作经验,难以举出高质量的真实案例。 现代程序开发不仅涉及语法规则,还会涉及大量的工具软件和不同的开发平台,例如各种不同IDE、各种编译器、Makefile/cmake等代码管理工具、git版本控制和合作工具等。较大比例的同学习惯于使用Windows操作系统的图形界面和笔记本电脑,缺少DIY桌面电脑带来的CPU、内存、磁盘等硬件的直观概念,也无法理解有了易用的图形界面为什么要用命令行窗口输入命令。而计算机行业的现实是大部分开发,包括人工智能基础软件、网络服务器软件乃至手机App都是Linux或类Unix系统。 学生的学习动力也是一项挑战。学生会认为学习Java、Python和JavaScript跟就业市场更匹配,C和C++这类很难的编程语言是否有必要学习?我们在本科生教育中固然要帮助学生打好基础,深厚的基础方能让学生在职业生涯中“以不变应万变”,破解“35岁退休”问题,同时我们也必须考虑到学生的就业需求,让学生熟练使用各种开发工具,快速掌握一些“容易”的编程语言,平滑地进入职场。 2. 课程内容设计 本节介绍作者所在的南方科技大学的程序设计课程设计。南方科技大学本科生第一年不分专业,所有本科生都进行程序设计的通识教育。程序设计通识教育包括Java、C、Pythoy、Matlab多门编程语言,学生根据自己的需求自由选择。如学生有意愿选择计算机专业,则需要修读Java编程语言。计算机专业将Java而非C作为第一门编程语言的原因在于Java的语法规则简单,入门相对容易,可以避免C语言带来的挫败感,重点培养学生的编程逻辑而非对语法细节的掌握,提升学生的编程兴趣。 学生在大学一年级学习的通识课程中的Java编程语言,目的是培养学生的逻辑思维能力,以及基础的编程能力,但这些基础能力无法应对人工智能时代对专业人才的要求。为了全面培养学生的程序设计能力,南科大计算机相关专业本科生的第二门程序设计课为“高级计算机程序设计”课程,面向人工智能时代的需求,经过多年迭代和改进而成。课程的所有课件和例程已经在GitHub网站开源[1],课程视频在哔哩哔哩网站播放超过20万次[2]。课程的上课安排为每星期4课时,其中理论课2课时,实验课2课时。理论课讲授语法知识和编程中的注意事项,实验课通过练习题让学生巩固理论课的知识点。 2.1 C和C++合并教学 鉴于修读本课程的学生已经有Java语言的程序设计基础,本课程将C和C++两门编程语言合并起来一起讲授。C和C++两门语言的语法规则有一定程度的重合,但也有差异。两门语言一起讲授,既可以高效率地讲授相同的部分,避免分成两门课的衔接问题;也可以对两门语言中的差异进行对比,突出两门语言的不同,例如基础数据类型的变量的初始化,两门语言都不进行初始化;C++有函数重载,C语言无函数重载;C和C++虽然都有结构体struct,但二者的结构体是完全不同的。这样的对比学习,有助于学生对知识点掌握的更深刻。 两门语言都涉及指针和内存管理,这是课程的难点,也是重点。如果学生没有掌握指针和内存管理,那不算学过C和C++语言。我们在课程中广泛采用内存示意图和动画对指针和内存这个知识点进行讲解,并将内存管理这个知识点渗透到课程中大部分知识点中。例如C++中类的默认复制构造函数和赋值运算符的重载,都会涉及内存管理问题。课程对各种可能发生的指针和内存管理问题进行讲解和深入分析。 课程内容设计以C和C++语言编程为基本内容,辅以介绍不同的CPU架构、GPU、Rust语言以及各种开发工具,并引入开源软件作为案例,让学生在掌握基本知识点之上,尽可能地扩大知识面。课程的最终目的是加深学生对计算机的理解,提升学生动手能力,并开阔学生的眼界。 2.2 突出C/C++的独特优势 课程设计的另一个目的是让学生体会到C和C++语言的魅力,所以如何提升程序的效率是课程的重点内容之一。课程内容会涉及编译器不同编译选项(如gcc的O3)对程序速度的影响,单指令多数据(SIMD)的用法,OpenMP充分利用CPU多核心等。这些程序优化方法可以让程序有几十倍的速度提升,让学生亲身感受到C和C++语言的价值。 课程将矩阵乘法的实现作为核心例子。矩阵乘法的原理在“线性代数”课程中有讲解,是现在深度学习领域中最核心的计算,无论普通卷积还是Transformer中的Attention模块,都是矩阵乘法计算。矩阵乘法的计算量在大多数深度学习模型中占90%以上的比重。矩阵乘法的基本实现很简单,只需要不到10行代码,但将之优化以提升速度却不容易。学生除了使用编译器优化选项、SIMD和多核并行,还需要考虑充分利用CPU的缓存(Cache),提升缓存读取的命中率等一系列方法。矩阵乘法的例子可以让学生充分感受到程序效率跟计算机体系结构密切相关,再将自己的程序跟跟专业的矩阵计算库(如OpenBLAS)进行对比,学生会深刻感受到自己的程序与专业程序的差距,这有助于提升学生对计算机的理解。 2.3 介绍X86、ARM和RISC-V架构 为了让学生充分理解不同CPU架构的相同和不同之处,课程中介绍了三种最常见CPU架构X86、ARM和RISC-V的异同。课程还提供了ARM开发板和华为的ARM云服务器供学生使用,并建议学生在ARM平台上完成课程项目。通过接触ARM系统,学生可以消除对ARM的陌生感,感受到使用ARM进行开发与在其他CPU架构上开发并无明显区别,消除学生畏难情绪。随着RISC-V硬件的日渐丰富,未来课程也会为学生提供RISC-V的开发环境。 课程还介绍了不同CPU架构中的SIMD指令,并讲解SIMD指令加速程序效率的作用。并鼓励学生使用SIMD指令(X86的AVX2或者ARM的NEON)去加速矩阵乘法的计算。通过使用SIMD,学生不仅可以学会编程技巧,还可以更好的理解CPU中的寄存器和计算机制。 声明:本文原发表于微信公众号“于仕琪”,可以转载,但不可修改。 2.4 介绍CUDA/Ascend C编程 现有的各种人工智能基础软件基本上都是运行在专用的GPU上,要发挥GPU的计算能力则需要专用的第三方库,如英伟达的CUDA和华为的Ascend C。课程中增加了CUDA和Ascend C的入门知识,通过在GPU上进行简单的矩阵运算,让学生了解CUDA和Ascend C的基本用法。 考虑到不是所有的学生都有GPU服务器,学校专门为本课程配置了一台有GPU的服务器,供学生远程登录使用。这部分内容仅是入门知识,目的不是让学生精通GPU编程,而是让学生有所了解并体验硬件加速的能力,看到相关名词不会产生畏惧心理。未来有需要的时候,学生可以快速上手GPU开发,为学生未来的发展提供知识储备。 2.5 介绍Rust编程语言 Rust是一门新型的编程语言,是一门对内存安全的语言。目前Linux内核开发[3]和Windows开发[4]都支持Rust语言。Rust语言未来有替换C和C++语言的潜力,但Rust生态尚未成熟,专门开设一门课讲授Rust未必妥当。鉴于此,本课程在C和C++内容之外,增加了Rust入门知识。相信学生在精通了C和C++之后,通过课堂介绍的Rust入门知识,可以通过自学快速地掌握Rust语言。 2.6 介绍各种开发工具的用法 要形成真正的开发能力,除了掌握编程语言的相关知识,还需要熟练使用各种开发工具。鉴于理论课的内容已经很多,以下工具软件的学习放在课程的实验课中。这些软件的使用跟实验课练习一起考核,计入学生的考核成绩。 1. Linux基本用法和常用命令:建议学生使用Linux系统开发。如果学生的个人电脑是Windows,则建议安装WSL(Windows Subsystem for Linux)。这样学生可以快速了解Linux的使用,特别是常用命令的使用。 2. gcc和g++编译器的用法:主要介绍一些常用选项,如“-c”、“-o”、“-O3”。学生通过在命令行中使用编译器进行编译,强化对“编译”、“连接”和“运行”等概念的认知。 3. Makefile的用法:通过一个包含多个源文件的项目,介绍Makefile的对多文件的管理。学生也可以通过Makefile理解多个源文件之间的关系。 4. cmake的用法:针对跨平台源文件管理,介绍Makefile的不足,引出cmake的必要性。 5. VS Code IDE的用法。介绍IDE将所有开发工具集中在一起的便利性。

【SpringCloud】负载均衡

目录 负载均衡什么是负载均衡生活场景为什么需要负载均衡负载均衡手段负载均衡总的来说有两种实现手段负载均衡具体可以通过多种手段来实现 SpringCloud中的负载均衡组件Ribbon VS Nginx负载均衡区别集中式LB进程内LB RibbonRibbon的工作原理Ribbon在工作时分成两步 使用1.提供者集群2.引入依赖4.测试 Ribbon的负载均衡策略核心组件轮询随机代码案例 权重代码案例 最小连接数代码案例 重试代码案例 可用性敏感策略代码案例 区域敏感策略代码案例 总结 负载均衡 什么是负载均衡 负载均衡(Load Balancing)是指在分布式系统中,将工作负载(Workload)平均分配给多个服务器或计算机资源,以提高系统的性能、可靠性和可扩展性。 生活场景 我们在日常生活中经常免不了要去一些比较拥挤的地方,比如地铁站、火车站、电影院、银行等。无论是买票,还是排队入场,这些场所一般都会设置多个服务点或者入口的。如果没有人引导的话,大多数情况下,最近的入口会挤满人。而哪些距离较远的服务点或者入口就宽松很多。 这种情况下,就会大大浪费资源,因为如果可以把这些排队的人很好的分散到各个入口的话会大大缩短排队时间。其实,软件的建设也是一样的。为了提升系统的服务能力,很多网站采用集群部署,就像话剧院有多个入口一样。这时候,就需要一个协调者,来均衡的分配这些用户的请求,可以让用户的可以均匀的分派到不同的服务器上。 为什么需要负载均衡 负载均衡是一种分配和管理网络流量的技术,主要用于确保网络服务的高可用性、可扩展性和性能优化。以下是需要负载均衡的主要原因: 高可用性:负载均衡可以将流量分配到多个服务器上,当其中一台服务器发生故障时,流量会自动转移到其他正常工作的服务器上,从而确保服务的连续性和可用性。 扩展性:负载均衡可以将流量分布到多个服务器上,允许系统根据需要动态地添加或删除服务器。这样可以更好地应对流量的增长和业务的扩展。 性能优化:负载均衡可以根据服务器的负载情况将流量分配到最空闲或最适合处理当前请求的服务器上,从而提高系统的响应速度和吞吐量。 故障恢复:当一台服务器发生故障时,负载均衡可以自动将流量转移到其他正常工作的服务器上,从而实现快速的故障恢复,减少服务中断时间。 节约成本:通过负载均衡,可以充分利用服务器的资源,提高服务器的利用率,从而减少不必要的硬件投入和维护成本。 总的来说,负载均衡是一种提高系统性能、可用性和可扩展性的重要技术,适用于各种网络应用和服务。 负载均衡手段 负载均衡总的来说有两种实现手段 一种是服务端负载均衡器,另一种是客户端负载均衡器 服务端负载均衡器的问题是,它提供了更强的流量控制权,但无法满足不同的消费者希望使用不同负载均衡策略的需求,而使用不同负载均衡策略的场景确实是存在的,所以客户端负载均衡就提供了这种灵活性。客户端负载均衡也有其缺点,如果配置不当,可能会导致服务提供者出现热点,或者压根就拿不到任何服务的情况服务端负载均衡器和客户端负载均衡器的区别如下图所示 客户端负载均衡器的实现原理是通过注册中心,如 Nacos,将可用的服务列表拉取到本地(客户端),再通过客户端负载均衡器(设置的负载均衡策略)获取到某个服务器的具体 ip 和端口,然后再通过 Http 框架请求服务并得到结果,其执行流程如下图所示: 负载均衡具体可以通过多种手段来实现 以下是一些常见的负载均衡手段: 基于DNS的负载均衡:通过使用DNS来将流量分布到不同的服务器上。在DNS解析请求时,返回多个服务器的IP地址,客户端根据返回的IP地址选择一个服务器进行连接。 集中式负载均衡:使用专门的负载均衡设备(如负载均衡器或负载均衡服务器)来分发流量。这些设备通常位于服务器和客户端之间,根据特定的算法将流量分配到不同的服务器上。 分布式负载均衡:将负载均衡的功能分散到多个服务器上,每个服务器都负责分发一部分的流量。这种方式可以提高系统的扩展性和容错性。 会话保持(Session Affinity):某些应用需要保持与特定服务器的会话状态,这需要负载均衡器将同一用户的请求始终分发到同一台服务器上,以保证会话的连续性。 基于内容的负载均衡:根据请求的内容或URL等特征来进行负载均衡。例如,可以根据请求的路径将静态资源请求分发到专门处理静态资源的服务器。 哈希负载均衡:根据客户端请求的特征(如IP地址、用户标识等)计算哈希值,将相同哈希值的请求定向到同一台服务器上。这可以保证相同请求始终分发到同一台服务器上。 需要注意的是,不同的负载均衡手段适用于不同的场景和需求,需要根据具体的应用和系统来选择合适的负载均衡策略。 SpringCloud中的负载均衡组件 在spring cloud H版大部分使用的负载均衡组件就是Ribbon和OpenFegin而在spring cloud跟新后官方宣布在 SpringCloud 2020版本以后 SpringCloud剔除掉了 除了eureka-server与 eureka-client 除外的所有 Netflix组件,spring也给出了使用spring cloud Loadbalancer替代的方案但就在目前,Ribbon以及OpenFegin仍然是主流的负载均衡的方案 Ribbon VS Nginx负载均衡区别 Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端实现的。Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。 集中式LB 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方; 进程内LB 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。 Ribbon Ribbon 是 Spring Cloud 技术栈中非常重要的基础框架,它为 Spring Cloud 提供了负载均衡的能力比如 Fegin 和 OpenFegin 都是基于 Ribbon 实现的,就连 Nacos 中的负载均衡也使用了 Ribbon 框架。Ribbon 框架的强大之处在于,它不仅内置了 7 种负载均衡策略,同时还支持用户自定义负载均衡策略,所以其开放性和便利性也是它得以流行的主要原因。 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。

字符串函数(2)<C语言>

前言 快一周没更博客了,最近有点忙,今天闲下来了,还是不行,继续干,书接上回继续介绍字符串函数:strncpy()、strncat()、strcmp()、strtok()使用、strstr()使用以及模拟实现、strerror()使用。 strncpy()、strncat()、strncmp() 这几个函数看着很眼熟,用法确实和前文的函数类似,不同的是多出了一个n,也有一些不同。 strncpy() 函数参数及其返回类型: char* strncpy(char* destination , const char* source , size_t num); //返回值是目的字符串的起始地址 作用: 从源字符串中拷贝num个字符串到目的字符串中。 注意点: ①如果num大于源字符长度,在拷贝完源字符串后,在目标字符串中追加\0,直到num个。 ②如果num小于源字符长度,在拷贝完指定字符串后,不会在目标字符串中追加\0。 使用举例: strncat() 函数参数及其返回类型: char* strncat(char* destination , const char* source , size_t num); //返回值是目的字符串的起始地址 作用: 从源字符串中追加前num个字符串到目的字符串中,再追加个\0。 注意点: ①如果num大于源字符长度,只会将源字符串中到\0的字符串追加到目的字符串末尾。 ②相较于strcat()函数,strncat()可实现自追加(先用strlen()函数求出字符串长度,再追加),原因也很简单,strncat()每次追加完毕会自动追加一个\0。 使用举例: strncmp() 函数参数及其返回类型: int strncat(const char* str1, const char* str2 , size_t num); //返回值是大于:大于0的数、等于:0、小于:小于0的数 作用: 比较str1与str2前num个字符 注意点:无 使用举例: strtok()使用 函数参数及其返回类型: char* strtok(char* str, const char* sep ); //返回值是指向找到以sep中的字符分隔的字符串的首地址,如果没找到返回NULL 作用:

【数据结构】二叉搜索树——高阶数据结构的敲门砖

目录 树概述 二叉搜索树概述 概念 特性 元素操作 插入 删除 模拟实现 框架 查找 插入 删除 树概述 树——在计算机中是一种很常见的数据结构。 树是一种很强大的数据结构,数据库,linux操作系统管理和windows操作系统管理所有文件的结构就是一颗树形结构 每个树有且只有一个根节点——根节点个数只有一个,节点可存储数据。 根节点往下可以有多个叶子节点,每个叶子节点也可以有多个叶子节点 如下图 每一个节点都可以是父亲节点,每个父亲节点的叶子节点都是孩子节点 根节点的深度为0,最后一层节点的深度为lgN 如果每一层深度的孩子节点的个数小于等于2,便是二叉树 左边的节点称为左孩子节点,右边的节点称为右孩子节点 如下图 如何正确的看一颗二叉树呢? 3是根节点,6作为3的左孩子也可以是一颗子树,这颗树是以6为根节点的树,也是3的左子树。以22为根节点来作为3的右子树也是一样的。 最小的子树是左孩子和右孩子都为空的叶子节点。 也就是说每一个节点都可以作为根节点,从而成为父亲节点的子树,子树又可以拆成子树,直到左右都为空的叶子节点为止(叶子节点也可以看作一颗子树)。 遍历一颗树应该用递归的思维,如下是遍历顺序 二叉树前序遍历:根 ——> 左子树——>右子树 二叉树中序遍历:左子树——>根——>右子树 二叉树后序遍历:左子树——>右子树——>根 二叉树层序遍历:一条龙遍历,可参考【C++】详解STL的适配器容器之一:优先级队列 priority_queue-CSDN博客 二叉搜索树概述 概念 二叉搜索树是一种二叉树结构,二叉搜索树存储数据时需要符合如下规则(搜索树是支持泛型的,为了方便理解,小编以int类型为例): 左孩子节点的值 < 父亲节点的值 < 右孩子节点的值 如下示例: 特性 对于所有数据而言, 从整棵树的根节点开始,不断地找左子树,没有左孩子的左子树存的值最小 从整棵树的根节点开始,不断地找右子树,没有右孩子的右子树存的值最大 如果整棵树走中序遍历则是升序 那么用搜索二叉树找一个节点的效率如何呢? 查找的规则很简单,比根节点的值大往右子树走,比根节点的值小往左子树走。每查找一次就能“砍”掉一半数据,只需要查找次。类似于二分查找。 上述查找条件是:整棵树基本符合二叉树结构。如果是比较极端的结构,效率会接近。比如下述结构 二叉搜索树搜索的效率的上限很高,下限很低。 元素操作 插入 二叉搜索树中不允许有相等的值存在,因为要维持 “左树的值小于根小于右数的值” 这一特性。 如果要插入的值在树中不存在,这个值会插入到中间某个位置吗? 答案是不会,因为这个值一定会从整棵树的根节点比到叶子节点,然后插入到叶子节点的后面。如下示意图: 删除 删除的情况比较复杂,大致可以分为两种情况 孩子节点的个数是1或0 假设被删节点为cur,被删节点的父亲节点为fatherNode。 先找是否有cur,找不到,删除失败。 找到了,判断cur是fatherNode的左孩子还是右孩子 是左孩子,让fatherNode的左指针指向cur的孩子节点 是右孩子,让fatherNode的右指针指向cur的孩子节点

前端fetch 实现流式接口

遇到这样一个需求,通过ai动态生成大纲文本,前端在接收到后端的文本内容时,接收的文本是“动态”的,视角表现层面上逐字生成渲染的,效果如下,那么如何实现这种效果?这里就要用到流式接口,也就是流式传输。 什么是流式传输 先说说传统传输吧,我们日常接触的大多数是传统传输方式,就也是整段传输,前后端将数据一次性传送给对方;相比于传统传输方式,流式传输则采用分段的方式将要传输的数据分层n段,后端一次性传一段给前端,直到传输完成为止,当然在传输的过程中,前端也可以提前中断传输,后端收到中断传输的消息后,也不再继续往前端传输剩下没传完的数据段。 当然,前端流式传输需要在后端支持分块传输的情况下才能实现。 前端实现流式传输的几种主流方式 查阅了资料,目前前端实现流式传输主要有以下几种方式:fetch、SSE、websocket,详情移步另一位博主,没错我查阅的资料就是他的文章,链接chatGPT流式输出前端实现fetch、SSE、websocket_fetch sse-CSDN博客 我用的是fetch,fetch 本身不直接支持流式输出,但你可以使用fetch ai 中的 ReadableStream实现流式数据处理。 什么是fetch? 简单来说fetch 是一种 HTTP 数据请求的方式, XMLHttpRequest(以下简称 XHR)的一种替代方案。与基于回调的API的XMLHttpRequest不同,fetch是基于Promise的,可以链式分块化地处理数据,更重要的是Fetch API能够处理流式响应。 更多关于fetch 的文档可以参考以下文档,我们重点讲fetch 处理流式响应 fetch 官方文档: 官方文档 js ES6 fetch 方法_js fetch-CSDN博客 fetch实现流式输出的实现原理_fetch nodejs 客户端 流式输出-CSDN博客 fetch处理流式响应 要实现 fetch 的流式输出,关键在于如何正确地处理返回的 ReadableStream 对象。ReadableStream 是 HTML 标准的一部分,它代表了一个可以从内部读取数据的源头。在 Fetch API 中,Response 对象的 body 属性就是一个 ReadableStream 实例。 return fetch(input, { ...init, headers }) .then((res) => { console.log('res.body', res.body); if (res.ok) return Promise.resolve(res); }) 实现步骤: 1.