《博主简介》
小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。
✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~
👍感谢小伙伴们点赞、关注!
《------往期经典推荐------》
一、AI应用软件开发实战专栏【链接】
项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【YOLOv8多目标识别与自动标注软件开发】8.【基于YOLOv8深度学习的行人跌倒检测系统】9.【基于YOLOv8深度学习的PCB板缺陷检测系统】10.【基于YOLOv8深度学习的生活垃圾分类目标检测系统】11.【基于YOLOv8深度学习的安全帽目标检测系统】12.【基于YOLOv8深度学习的120种犬类检测与识别系统】13.【基于YOLOv8深度学习的路面坑洞检测系统】14.【基于YOLOv8深度学习的火焰烟雾检测系统】15.【基于YOLOv8深度学习的钢材表面缺陷检测系统】16.【基于YOLOv8深度学习的舰船目标分类检测系统】17.【基于YOLOv8深度学习的西红柿成熟度检测系统】18.【基于YOLOv8深度学习的血细胞检测与计数系统】19.【基于YOLOv8深度学习的吸烟/抽烟行为检测系统】20.【基于YOLOv8深度学习的水稻害虫检测与识别系统】21.【基于YOLOv8深度学习的高精度车辆行人检测与计数系统】22.【基于YOLOv8深度学习的路面标志线检测与识别系统】22.【基于YOLOv8深度学习的智能小麦害虫检测识别系统】23.【基于YOLOv8深度学习的智能玉米害虫检测识别系统】24.【基于YOLOv8深度学习的200种鸟类智能检测与识别系统】25.【基于YOLOv8深度学习的45种交通标志智能检测与识别系统】26.【基于YOLOv8深度学习的人脸面部表情识别系统】 二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
《------正文------》
效果展示 1.rembg插件安装方法 打开SD软件后,在扩展菜单点击从网址安装,输入下面地址,然后点击安装即可。
https://github.com/AUTOMATIC1111/stable-diffusion-webui-rembg.git
安装完成后,点击已安装菜单,然后点击应用更改并重启按键,上面安装的插件即可生效。
返回后期处理界面,即可看到移除背景插件,如下图所示:
2.进行一键抠图 在后期处理界面,将需要进行抠图的图片上传。然后在移除背景选择u2net选项,然后点击生成,结果如下:
抠图前后对比如下:
可以看到,效果还是挺不错的,但是图片边缘有黑边,现在我们希望将黑边部分尽量消除。需要进行一点参数设置。经过博主多次尝试,以下参数设置,消除黑边的效果比较理想。小伙伴们也可以自行尝试。
勾选alpha遮罩选项,设置以下参数,然后点击生成,结果如下:
可以发现,之前的黑边明显消除了很多,看起来也好多了。
最终对比如下:
好了,这篇文章内容就到这里,后期更多精彩内容持续更新,欢迎点赞关注哦~
如果文章对你有帮助,欢迎✌关注、👍点赞、✌收藏、👍订阅专栏!
欢迎关注下方GZH:阿旭算法与机器学习,共同学习交流~
C++大作业——学生选课系统 前言1.系统概述2.系统设计2.1概要设计2.2详细设计2.2.1学生类和课程类模块设计2.2.2文件信息读取和录入模块设计2.2.3增删改查模块设计2.2.4登入模块设计2.2.5选课模块设计2.2.6退选模块设计 3.完整代码4.总结与展望4.1设计总结4.2设计展望 前言 本次课程设计是我第一次独自完成这样一个相对完整的项目,收获很多。但是我更想说一下本次设计中存在的不足。
首先就是在最初设计课程类和学生类时,没有考虑的那么全面,导致出现了很多冗余的接口,和公有私有混着用的情况。其次就是,虽然是用C++写的,却没有把封装体现出来,使用了很多friend友元函数也破坏了类的封装效果。
由于我最开始是在Linux系统上编写的代码,没有装中文包,所以很多注释和输出语句都是用英文写的。后来又转到Windows下的VS环境下编程,也写了一些中文的语句。导致会有中英文混用的情况,可能会影响观感。
在学习这个系统之前,建议先把学生成绩管理系统熟练掌握,掌握最基本的增删改查操作,我在本文中就不再赘述了,把重点放在选课和退选的功能讲解上。
在最后面,我也会把整个项目代码都放出来,大家可以拿去在自己的电脑上运行,应付下作业铁定是没问题的(手动狗头)。
1.系统概述 本系统是学生选课系统,主要是实现大学生的选课需求。进入系统,需要先选择用户(学生或管理员),选择管理员,需要输入对应的密码。选择完身份后,进入主菜单,会出现两个子菜单,学生菜单和课程菜单,选择相应的选项,就会进入相应的菜单,其中0选项是返回上级目录。
进入课程菜单,会看到增删改查相应的操作,还有显示全部课程信息。其中,学生用户没有对课程进行增删改的权利。管理员是超级用户,有所有操作的权利。里面的细节我们在模块的具体实现时再说。
进入学生菜单,也会看到增删改查相关的操作,还有显示全部学生的信息。不同的是,学生菜单中可以进行选课和退选的相关操作。学生用户只有查看信息,选课退选的权利,没有增删改的权利。具体细节也是放在模块中详谈。
2.系统设计 2.1概要设计 2.2详细设计 2.2.1学生类和课程类模块设计 int flag = 0; // default is student class Course { public: friend void Input_course(vector<Course>& cour); friend void Delete_course(vector<Course>& cour); friend void Modify_course(vector<Course>& cour); friend void Lookup_course(vector<Course>& cour); friend void Show_course(vector<Course>& cour); friend void Add_course(vector<Course>& cour); friend int Read_course(vector<Course>& cour); friend void Write_course(vector<Course>& cour, int n); const char* c_id() { return id; } const char* c_name() { return name; } const bool c_nature() { return nature; } Course() : id("
目录
1、什么是WebSocket
2、为什么需要WebSocket
3、WebSocket的特点
1、什么是WebSocket 1、WebSocket是一种在单个TCP连接上进行全双工通信的协议。
2、WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
3、在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
示例:WebSocket是一种双向网络通信协议,与HTTP不同,它以ws://或wss://开头。它是一个有状态协议,这意味着客户端和服务器之间的连接将保持活动状态,直到被客户端或服务器中的任何一方关闭连接之后,连接将从两端终止。
WebSocket使用了HTTP/1.1的协议升级特性,一个WebSocket请求首先使用非正常的HTTP请求以特定的模式访问一个URL,这个URL有两种模式,分别是ws和wss,对应HTTP协议中的HTTP和HTTPS。
①在请求头中有一个Connection:Upgrade字段,表示客户端想要对协议进行升级。
②另外还有一个Upgrade:websocket字段,表示客户端想要将请求协议升级为WebSocket协议。
③这两个字段共同告诉服务器要将连接升级为WebSocket这样一种全双工协议。
如果服务端同意协议升级,那么在握手完成之后,文本消息或者其他二进制消息就可以同时在两个方向上进行发送,而不需要关闭和重建连接。此时的客户端和服务端关系是对等的,它们可以互相向对方主动发送消息。
2、为什么需要WebSocket 初次接触 WebSocket的人,都会问同样的问题:我们已经有了HTTP协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为HTTP协议有一个缺陷:通信只能由客户端发起。
举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询",每隔一段时候,就发出一个询问,了解服务器有没有新的信息。轮询的效率低,非常浪费资源。因此,工程师们一直在思考,有没有更好的方法,WebSocket就是这样发明的。
WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
因为一般的请求都是HTTP请求(单向通信),HTTP是一个短连接(非持久化),且通信只能由客户端发起,HTTP协议做不到服务器主动向客户端推送消息。举个例子:前后端交互就是前端发送请求,从后端拿到数据后展示到页面,如果前端没有主动请求接口,那后端就不能发送数据给前端。然而,WebSocket确能很好的解决这个问题,服务端可以主动向客户端推送消息,客户端也可以主动向服务端发送消息,实现了服务端和客户端真正的平等。
轮询
轮询是最简单的一种解决方案,所谓轮询,就是客户端在固定的时间间隔下不停地向服务端发送请求,查看服务端是否有最新的数据,若服务端有最新的数据,则返回给客户端,若服务端没有,则返回一个空的JSON或者XML文档。轮询对开发人员而言实现方便,但是弊端也很明显:客户端每次都要新建HTTP请求,服务端要处理大量的无效请求,在高并发场景下会严重拖慢服务端的运行效率,同时服务端的资源被极大的浪费了,因此这种方式并不可取。
长轮询
长轮询是传统轮询的升级版,当聪明的工程师看到轮询所存在的问题后,就开始解决问题,于是有了长轮询。不同于传统轮询,在长轮询中,服务端不是每次都会立即响应客户端的请求,只有在服务端有最新数据的时候才会立即响应客户端的请求,否则服务端会持有这个请求而不返回,直到有新数据时才返回。这种方式可以在一定程度上节省网络资源和服务器资源,但是也存在一些问题,例如:
如果浏览器在服务器响应之前有新数据要发送,就只能创建-一个新的并发请求,或者先尝试断掉当前请求,再创建新的请求。
TCP和HTTP规范中都有连接超时一说,所以所谓的长轮询并不能一直持续, 服务端和客户端的连接需要定期的连接和关闭再连接,这又增大了程序员的工作量,当然也有一些技术能够延长每次连接的时间,但毕竟是非主流解决方案。
3、WebSocket的特点 和传统的解决方案相比,WebSocket主要有如下特点:
1、较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
2、更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
3、保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
4、更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
5、可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
6、更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
7、WebSocket使用时需要先创建连接,这使得WebSocket成为一种有状态的协议,在之后的通信过程中可以省略部分状态信息( 例如身份认证等)。
8、WebSocket连接在端口80 (ws)或者443 (wss)上创建,与HTTP使用的端口相同,这样,基本上所有的防火墙都不会阻止WebSocket连接。
WebSocket使用HTTP协议进行握手,因此它可以自然而然地集成到网络浏览器和HTTP服务器中,而不需要额外的成本。
9、心跳消息(ping 和pong)将被反复的发送,进而保持WebSocket连接一直处于活跃状态。
使用该协议,当消息启动或者到达的时候,服务端和客户端都可以知道。
10、WebSocket连接关闭时将发送一个特殊的关闭消息。
11、WebSocket支持跨域,可以避免Ajax的限制。
12、HTTP规范要求浏览器将并发连接数限制为每个主机名两个连接,但是当我们使用WebSocket的时候,当握手完成之后,该限制就不存在了,因为此时的连接已经不再是HTTP连接了。
13、WebSocket协议支持扩展,用户可以扩展协议,实现部分自定义的子协议。
14、更好的二进制支持以及更好的压缩效果。
文章目录 版本无账号密码使用 Selenium 实现 HTTP 代理万万没想到加上账号密码会难度升级 + NGPT 提供的带账号密码的 HTTP 代理解决方案代理 IP如何获取 Selenium-Chrome-HTTP-Private-Proxy HTTP 代理解决方案如何实现 总结总结个人简介 版本 Python 3.x 无账号密码使用 Selenium 实现 HTTP 代理 最近一个朋友私聊了我一个问题,Selenium 如何使用代理 IP 进行爬虫,我心想这不是很简单,马上让 GPT 帮忙写一个: 完整代码如下: from selenium import webdriver from selenium.webdriver.common.proxy import Proxy, ProxyType # 设置代理IP proxy_ip = "your_proxy_ip" proxy_port = "your_proxy_port" # 设置代理 proxy = Proxy() proxy.proxy_type = ProxyType.MANUAL proxy.http_proxy = f"{proxy_ip}:{proxy_port}" proxy.ssl_proxy = f"{proxy_ip}:{proxy_port}" # 配置浏览器选项 chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--proxy-server=http://{}:{}'.format(proxy_ip, proxy_port)) # 启动浏览器 driver = webdriver.
1、通过 homebrew 安装的 通过 node -v 查看版本好
然后使用指令删除: brew uninstall node@版本号 --force
例:安装的是 v16.20.0,使用brew uninstall node@16 --force 进行删除;
2、通过官网 pkg 安装包下载的 直接使用:
sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*}
一、Map 1. 构建 语法: map (key1, value1, key2, value2, …)
说明:根据输入的key和value对构建map类型
--> 1. 一般创建方法 select map('key1_name','张三','key2_age',20) as map_col -- 结果: {"key1_name":"张三","key2_age":"20"} --> 2. 根据SQL查询结果构建map select map('k_name',name,'k_age',age) as map_col from ( select '张三' as name, 23 as age union select '李四' as name, 24 as age union select '王五' as name, 25 as age ) -- 结果: {"k_age":"25","k_name":"王五"} {"k_age":"23","k_name":"张三"} {"k_age":"24","k_name":"李四"} 2. 读取 语法: M[key]
操作类型: M为map类型,key为map中的key值
说明:返回map类型M中,key值为指定值的value值。
with base_tb as ( select map('k_name',name,'k_age',age) as map_col from ( select '张三' as name, 23 as age union select '李四' as name, 24 as age union select '王五' as name, 25 as age ) ) select map_col['k_name'] as col from base_tb -- 结果: 王五 张三 李四 3.
一:打开控制面板→卸载程序 选中Android Studio,卸载。
这个一定要勾上哦!
点完后有个下一步,有个弹窗,点击确定删除。
接下来,如果你是和我一样装在别的位置,我们需要找到它。
如图:我装在了E盘。
第一个文件是安装文件,在控制面板卸载后就没有了。
第二第三个是我创建的项目,这里需要手动删除。
第四个文件是JDK储存路径。我都放一起了。都找到手动删除一下。
接下来打开C盘。
按照以下路径依此选择C盘,用户,用户名的文件夹,删除一下选中文件。
如果你是直接装在C盘,那这里还会有一个文件夹叫Android Studio Project,找到删掉。
加下来打开AppData。
在这两个文件夹中分别找到Google里面的你安装的AndroidStudio版本,并删掉。
Ok,这样Android Studio就卸载干净了。你可以重新开始安装了。
有时候我们下载苹果系统的软件,会让我们选择软件包是arm版本还是intel版本,比如:
查看CPU 版本 点屏幕左上角苹果图标,点击关于本机
处理器一栏看 Intel 还是arm
如果是 Intel 就是选x64 下载
如果是 Apple M1 就选arm64来下载。
升级到Xcode 15运行项目报错,报错信息如下:
SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a'; try increasing the minimum deployment target
解决 下载libarclite 文件前往文件夹 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/将下载的arc 文件夹复制到lib文件夹下
感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!
“List of Devices Attached”:Android设备连接问题解析 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,我们将聚焦于一个在Android开发和移动设备管理中经常遇到的问题,那就是"list of devices attached"。让我们一起深入了解这个话题,了解其中的奥秘和解决方法。
1. 什么是"List of Devices Attached"? 在进行Android应用程序开发或设备管理时,我们经常会使用ADB(Android Debug Bridge)工具。当我们执行adb devices命令时,如果一切正常,会看到输出中包含"List of devices attached",然后列出已连接的Android设备。
2. 常见问题及解决方法 2.1 问题:设备未被识别 有时,执行adb devices后,设备列表为空,无法识别连接的Android设备。
解决方法:
确保USB调试已开启:在设备的开发者选项中,启用USB调试。安装正确的驱动程序:确保在计算机上安装了正确的USB驱动程序,使其能够识别Android设备。重新连接设备:尝试重新连接USB并执行adb devices。 2.2 问题:设备连接多台 有时,可能会出现多个设备连接,而无法确定要与之交互的是哪一个设备。
解决方法:
使用adb -s <设备序列号>:在执行命令时,通过指定设备的序列号,确保指定设备而非其他设备执行命令。 3. ADB常用命令 为了更好地处理"List of Devices Attached"问题,以下是一些ADB常用命令,帮助你更好地管理Android设备:
adb devices:列出连接的设备。adb -s <设备序列号> <命令>:指定设备执行命令。adb kill-server:停止ADB服务器。adb start-server:启动ADB服务器。 4. 结语 "List of Devices Attached"是Android开发中一个常见的提示信息,通过理解和掌握相关的ADB命令,我们能够更有效地进行设备管理和应用程序调试。希望本文能为你解决在Android开发中遇到的设备连接问题提供一些有用的信息。
总结 Spark 和 MapReduce 的区别及优缺点 1、Spark处理数据是基于内存的,而MapReduce是基于磁盘处理数据的
MapReduce是将中间结果保存到磁盘中,减少了内存占用,牺牲了计算性能。
Spark是将计算的中间结果保存到内存中,可以反复利用,提高了处理数据的性能。
2、Spark在处理数据时构建了DAG有向无环图,减少了shuffle和数据落地磁盘的次数
Spark计算比MapReduce快的根本原因在于DAG计算模型。一般而言,DAG相比MapReduce在大多数情况下可以减少shuffle次数。Spark的DAGScheduler相当于一个改进版的MapReduce,如果计算不涉及与其他节点进行数据交换,Spark可以在内存中一次性完成这些操作,也就是中间结果无须落盘,减少了磁盘IO的操作。但是,如果计算过程中涉及数据交换,Spark也是会把shuffle的数据写磁盘的。
3、Spark比MapReduce快
有一个误区,Spark是基于内存的计算,所以快,这不是主要原因,要对数据做计算,必然得加载到内存,Hadoop也是如此,只不过Spark支持将需要反复用到的数据Cache到内存中,减少数据加载耗时,所以Spark跑机器学习算法比较在行(需要对数据进行反复迭代)。
4、Spark是粗粒度资源申请,而MapReduce是细粒度资源申请
粗粒度申请资源指的是在提交资源时,Spark会提前向资源管理器(YARN,Mess)将资源申请完毕,如果申请不到资源就等待,如果申请到就运行task任务,而不需要task再去申请资源。
MapReduce是细粒度申请资源,提交任务,task自己申请资源自己运行程序,自己释放资源,虽然资源能够充分利用,但是这样任务运行的很慢。
5、MapReduce的Task的执行单元是进程,Spark的Task执行单元是线程
进程的创建销毁的开销较大,线程开销较小。
6、Spark优缺点
优点:
1)Spark把中间数据放到内存中,迭代运算效率高。
Spark支持DAG图的分布式并行计算的编程框架,减少了迭代过程中数据的落地,提高了处理效率。
2)Spark 容错性高
Spark 引进了弹性分布式数据集 RDD (Resilient DistributedDataset) 的抽象,它是分布在一组节点中的只读对象集合,这些集合是弹性的,如果数据集一部分丢失,则可以根据“血统”(即允许基于数据衍生过程)对它们进行重建。另外在RDD 计算时可以通过 CheckPoint 来实现容错。
3)Spark更加通用
Spark提供的数据集操作类型分为:Transformations和Actions两大类。Transformations包括Map、Filter、FlatMap、Sample、GroupByKey、ReduceByKey、Union、Join、Cogroup、MapValues、Sort等多种操作类型,同时还提供Count, Actions包括Collect、Reduce、Lookup和Save等操作。
缺点:
1)内存问题
JVM的内存overhead太大,1G的数据通常需要消耗5G的内存。
2)性能问题
由于大量数据抄被缓存在RAM中,Java回收垃圾缓慢的情况严重,导致Spark性能不稳定。
7、MapReduce优缺点
优点:
1)MapReduce 易于编程
它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的 PC 机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。就是因为这个特点使得 MapReduce 编程变得非常流行。
2)良好的扩展性
当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。
3)高容错性
MapReduce 设计的初衷就是使程序能够部署在廉价的 PC 机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行, 不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由Hadoop内部完成的。
4)适合 PB 级以上海量数据的离线处理
可以实现上千台服务器集群并发工作,提供数据处理能力。
缺点:
1)不擅长实时计算
MapReduce无法像MySQL一样,在毫秒或者秒级内返回结果。
2)不擅长流式计算
流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。这是因为 MapReduce 自身的设计特点决定了数据源必须是静态的。
3)不擅长 DAG(有向无环图)计算
macOS 提示:“应用程序” 已损坏,无法打开的解决方法总结
请访问原文链接:https://sysin.org/blog/macos-if-crashes-when-opening/,查看最新版。原创作品,转载请保留出处。
作者主页:sysin.org
说明:本文描述问题同样适用于其他版本的 macOS,因历史原因在 Catalina 中出现问题的情况最多。
现象 提示:“应用程序” 已损坏,无法打开。您应该将它移到废纸篓。
提示:无法打开 “应用程序”,因为无法验证开发者。macOS 无法验证此 App 不包含恶意软件。
提示:“应用程序” 将对您的电脑造成伤害。您应该将它移到废纸篓。
解决方法 一般情况下,只需要 1 和 2 两步即可。
1. 允许 “任何来源” 下载的 App 运行 打开 “终端” 执行如下命令(根据提示输入您的密码即可):
sudo spctl --master-disable 打开 “系统偏好设置…” - “安全性与隐私”,“通用” 标签页,如图勾选:
macOS Ventura 略有变化,位于:系统设置 – 隐私和安全性,“安全性”(参看下述第 3 点截图)。
2. 移除应用的安全隔离属性 打开 “终端” 执行如下命令(根据提示输入您的密码即可):
sudo xattr -dr com.apple.quarantine /Applications/name.app /Applications/name.app 如果不知道该如何输入,将 App 直接拖拽 sudo xattr -rd com.apple.quarantine(中间有个空格)后面即可。
一般情况下,多余的扩展属性都可以清除(个别应用例外):
可以直接输入:sudo xattr -cr /Applications/*
第一部分:使用ESP32进行WiFi扫描和网络连接
引言
欢迎来到我们深入探讨使用ESP32进行WiFi功能的第一部分,ESP32是一款多功能且强大的微控制器,非常适用于物联网应用。在本节中,我们将重点关注WiFi扫描和连接到网络,这是任何物联网开发者的基本技能。本指南将向您介绍ESP32上WiFi技术的基础知识,演示如何扫描可用网络,并解释如何建立与WiFi网络的连接。
了解ESP32上的WiFi扫描
WiFi扫描是ESP32搜索附近可用WiFi网络的过程。这个功能对需要在不同位置连接到不同网络的物联网设备非常重要。
为什么WiFi扫描很重要:
网络选择的灵活性:使设备能够选择并连接到最强的可用网络。网络分析:用于分析给定区域内网络的强度和可用性。 设置ESP32进行WiFi扫描:
在进行扫描之前,必须正确配置ESP32并包括必要的WiFi库。 实施WiFi扫描:
编写代码以将ESP32初始化为Station模式。实施扫描可用网络并检索它们的详细信息,如SSID、RSSI和加密类型。 示例代码:WiFi网络扫描
以下是一个简单的程序,用于扫描可用的WiFi网络并打印它们的详细信息:
#include <WiFi.h> void setup() { Serial.begin(115200); // 初始化WiFi为Station模式 WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); Serial.println("正在扫描WiFi网络..."); int networkCount = WiFi.scanNetworks(); if (networkCount == 0) { Serial.println("未找到任何网络"); } else { Serial.print(networkCount); Serial.println(" 个网络已找到:"); for (int i = 0; i < networkCount; ++i) { Serial.print("网络名称:"); Serial.println(WiFi.SSID(i)); Serial.print("信号强度:"); Serial.println(WiFi.RSSI(i)); Serial.println("-----------------------"); } } } void loop() { // 暂时没有内容 } 这段代码初始化ESP32以执行WiFi扫描,并打印每个可用网络的SSID和RSSI(信号强度)。
连接到WiFi网络
一旦识别到可用网络,下一步就是连接到其中之一。
网络连接基础:
一、运行效果图
二、完整代码
#!/usr/bin/env python # -*- coding: utf-8 -*- # author:Wangdali time:2021年1月20日16:08:44 #python实现:贪吃蛇 ''' 游戏玩法:回车开始游戏;空格暂停游戏/继续游戏;方向键/wsad控制小蛇走向 ''' ''' 思路:用列表存储蛇的身体;用浅色表示身体,深色背景将身体凸显出来; 蛇的移动:仔细观察,是:身体除头和尾不动、尾部消失,头部增加,所以,新添加的元素放在列表头部、删除尾部元素; 游戏结束判定策略:超出边界;触碰到自己的身体:蛇前进的下一格子为身体的一部分(即在列表中)。 ''' #注:因为在列表中需要频繁添加和删除元素,所以用deque容器代替列表;是因为deque具有高效的插入和删除效率 #初始化蛇,长度为3,放置在屏幕左上角; #导包 import random import sys import time import pygame from pygame.locals import * from collections import deque #基础设置 Screen_Height=480 Screen_Width=600 Size=20#小方格大小 Line_Width=1 #游戏区域的坐标范围 Area_x=(0,Screen_Width//Size-1) #0是左边界,1是右边界 #注:python中//为整数除法;/为浮点数除法 Area_y=(2,Screen_Height//Size-1) #食物的初步设置 #食物的分值+颜色 Food_Style_List=[(10,(255,100,100)),(20,(100,255,100)),(30,(100,100,255))] #整体颜色设置 Light=(100,100,100) Dark=(200,200,200) Black=(0,0,0) Red=(200,30,30) Back_Ground=(40,40,60) #文本输出格式设置 def Print_Txt(screen,font,x,y,text,fcolor=(255,255,255)): #font.render参数意义:.render(内容,是否抗锯齿,字体颜色,字体背景颜色) Text=font.render(text,True,fcolor) screen.blit(Text,(x,y)) #初始化蛇 def init_snake(): snake=deque() snake.
目录
队列的定义
普通顺序队列的劣势——与链队列相比 顺序队列实现方法:
一、动态增长队列
1、初始化队列
2、元素入队
3、判断队列是否为空
4、元素出队
5、获取队首元素
6、获取队尾元素
7、获取队列元素个数
8、销毁队列
总结:
动态增长队列完整测试代码:
二、固定长度队列 1、与动态增长队列的差异
2、判断是否队满 固定长度队列完整测试代码:
本节我们采用数组(顺序表)形式实现队列,学习单链表实现请点击下方链接:
队列—单链表实现(C语言版)-CSDN博客
为了减少数组初始长度过大对内存空间的浪费,本节我们采用动态内存管理,相关函数请的介绍点击下方链接:
动态内存函数(malloc,free,calloc,realloc)-CSDN博客
循环队列的实现:
循环队列(数组实现)-CSDN博客
队列的定义 队列是一种基本的数据结构,它是一种先进先出(First In First Out,FIFO)的线性结构。队列只允许在表的一端进行插入,而在另一端进行删除操作。这就相当于把数据排成一排,先插入的排在前面,后插入的排在后面,之后进行删除操作时也只能从前面依次删除。这种数据结构一般用于需要按照先后顺序进行处理的问题,如模拟系统、计算机网络中的缓存、操作系统中的进程调度等。队列的基本操作包括入队(插入元素到队尾)和出队(从队头删除元素),队列还有一个重要的特性就是队列的长度是动态变化的,随着入队和出队的操作进行不断变化。
普通顺序队列的劣势——与链队列相比 长度固定:普通数组队列的长度是固定的,一旦数组被分配,其长度无法改变。当队列元素数量超过数组长度时,需要进行数组的扩容操作,这会导致性能上的开销。
内存的浪费:因为普通数组队列的长度固定,可能会出现队列中存在空闲的位置,导致内存的浪费。
为了解决上述 问题1,我们在本节中对顺序表采取动态内存管理,在必要时更新数组的长度,以保证顺序队列的长度足够使用。
(补充:问题2 的解决需要使用循环队列,本节内容先为大家介绍一般队列的实现,等同学们对队列有了充分的理解之后,我们下节再进行循环队列的学习。)
顺序队列实现方法: 一、我们首先定义一个数组,数组的头部为队首,尾部为队尾。每当插入一个元素时,就将元素放在队尾,当删除一个元素时,将队首的元素删除。当队列为空时,不能再删除元素。
二、我们采用双指针法时刻记录队列的队首和队尾:
定义一个固定大小的数组作为队列的存储空间,并定义两个指针front和rear分别指向队列的队首和队尾。
初始化队列时,将front和rear都设置为0,表示队列为空。
插入元素时,将元素放入rear指针指向的位置,并将rear指针后移一位。
删除元素时,将front指针后移一位。
判断队列是否为空,只需要判断front和rear是否相等即可。
一、动态增长队列 1、初始化队列 初始化队列时,将front和rear都设置为0,表示队列为空。
typedef int DataType; typedef struct Queue { DataType* a; // 队列的数组 int front, rear; // 队列的头部和尾部位置索引 int size; // 队列中元素的数量 int capacity; // 队列的容量 } Queue; // 初始化队列 void InitQueue(Queue* q) { q->a = NULL; // 数组指针初始化为NULL q->front = q->rear = 0; // 头部和尾部位置索引初始化为0 q->size = q->capacity = 0; // 元素数量和容量都初始化为0 } 2、元素入队 // 入队 void QueuePush(Queue* q, DataType x) { assert(q); // 断言q不为NULL if (q->capacity == q->rear) { // 如果队列已满,进行扩容操作 int new_capacity = q->capacity == 0 ?
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
本文未经允许,不得转发!!!
目录 🎄一、fcntl 函数介绍🎄二、复制文件描述符(F_DUPFD、F_DUPFD_CLOEXEC)✨2.1 F_DUPFD(int)✨2.2 F_DUPFD_CLOEXEC(int) 🎄三、获取/设置文件描述符标志(F_GETFD、F_SETFD)🎄四、获取/设置文件状态标志(F_GETFL、F_SETFL)🎄五、获取/设置记录锁(F_GETLK、F_SETLK、F_SETLKW)🎄六、总结 🎄一、fcntl 函数介绍 函数原型:
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); // arg表示可变参数,由cmd决定 fcntl()对打开的文件描述符fd执行下面描述的操作之一。操作由cmd决定。
fcntl()的第三个参数是可选。是否需要此参数由cmd决定。所需的参数类型在每个cmd名称后面的括号中指示(在大多数情况下,所需的类型是int,我们使用名称arg来标识参数),如果不需要参数,则指定void。
以下某些操作仅在特定的Linux内核版本之后才受支持。检查主机内核是否支持特定操作的首选方法是使用所需的cmd值调用fcntl(),然后使用EINVAL测试调用是否失败,这表明内核无法识别该值。
本文主要介绍下面4个功能:
1、复制文件描述符(F_DUPFD、F_DUPFD_CLOEXEC);2、获取/设置文件描述符标志(F_GETFD、F_SETFD);3、获取/设置文件状态标志(F_GETFL、F_SETFL);4、获取/设置记录锁(F_GETLK、F_SETLK、F_SETLKW); 🎄二、复制文件描述符(F_DUPFD、F_DUPFD_CLOEXEC) ✨2.1 F_DUPFD(int) F_DUPFD(int) 表示使用 F_DUPFD 作为cmd时,第三个参数需要传入int型数据。
cmd为F_DUPFD表示复制文件描述符fd。调用成功会返回新的描述符。新描述符使用大于或等于arg参数的编号最低的可用文件描述符复制文件描述符fd。新描述符与f似共享同一文件表项。但是,新描述符有它自己的一套文件描述符标志,其FD_CLOEXEC文件描述符标志被清除〈这表示该描述符在 exec 时仍保持打开状态)。
// fcntl_F_DUPFD.c #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> int main() { int fd = open("./fcntl_F_DUPFD", O_RDWR | O_CREAT | O_TRUNC, 0775); int fcntlFd = fcntl(fd, F_DUPFD, 0); // 指定从 0 开始分配最小的可用描述符作为新描述符 int dupFd = dup(fd); // 等效于 fcntl(fd, F_DUPFD, 0); close(fd); close(fcntlFd); close(dupFd); return 0; } ✨2.
目录 一、简单CASE WHEN函数:二、CASE WHEN条件表达式函数三、常用场景 场景1:不同状态展示为不同的值场景2:统计不同状态下的值场景3:配合聚合函数做统计场景4:CASE WHEN中使用子查询场景5:经典行转列,结合max聚合函数 一、简单CASE WHEN函数: CASE SCORE WHEN 'A' THEN '优' ELSE '不及格' END # 使用 IF 函数进行替换 IF(SCORE = 'A', '优', '不及格') THEN后边的值与ELSE后边的值类型应一致,否则会报错。
如下:
CASE SCORE WHEN ‘A’ THEN ‘优’ ELSE 0 END’优’和0数据类型不一致则报错:
[Err] ORA-00932: 数据类型不一致: 应为 CHAR, 但却获得 NUMBER
简单CASE WHEN函数只能应对一些简单的业务场景,而CASE WHEN条件表达式的写法则更加灵活。
二、CASE WHEN条件表达式函数 类似JAVA中的IF ELSE语句。
格式:
CASE WHEN condition THEN result [WHEN...THEN...] ELSE result END SQL语言演示:
CASE WHEN SCORE = 'A' THEN '优' WHEN SCORE = 'B' THEN '良' WHEN SCORE = 'C' THEN '中' ELSE '不及格' END # 等同于 CASE score WHEN 'A' THEN '优' WHEN 'B' THEN '良' WHEN 'C' THEN '中' ELSE '不及格' END condition是一个返回布尔类型的表达式,
作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳
本文涉及的基础知识点 C++算法:滑动窗口总结
单调双向队列 二叉树
题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
一小池勺 ❤️❤️❤️ ❤️❤️❤️❤️ 胸有惊雷而面如平湖者,可拜上将军也。 axios详解以及完整封装方法 一、axios是什么 Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
axios有以下特性: 从浏览器创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据
客户端支持防御XSRF
axios可以请求的方法: get:获取数据,请求指定的信息,返回实体对象
post:向指定资源提交数据(例如表单提交或文件上传)
put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
delete:请求服务器删除指定的数据
head:获取报文首部
请求方法别名 为了方便起见,axios为所有支持的请求方法提供了别名:
axios(config)
axios.request(config)
axios.get(url [,config])
axios.post(url [,data [,config]])
axios.put(url [,data [,config]])
axios.delete(url [,config])
axios.patch(url [,data [,config]])
axios.head(url [,config])
二.axios实例及配置方法 1.创建axios实例 axios.create([config])
可以同时创建多个axios实例。
示例代码
const instance = axios.
Hadoop配置文件模板core-site.xmlhadoop-env.shhdfs-site.xmlyarn-env-shyarn-site.xmlmapred-site.xmlslaves Hadoop配置文件模板 参考官方配置文档:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/ClusterSetup.html#Configuring_Environment_of_Hadoop_Daemons
Hadoop的配置文件都在$HADOOP_HOME/etc/hadoop下面。比如我这里是:
Hadoop主要配置文件:
配置文件功能描述hadoop-env.sh配置Hadoop运行所需的环境变量yarn-env.sh配置Yarn运行所需的环境变量core-site.xmlHadoop核心全局配置文件,可在其他配置文件中引用该文件hdfs-site.xmlHDFS配置文件,继承core-site.xml配置文件mapred-site.xmlMapReduce配置文件,继承core-site.xml配置文件yarn-site.xmlYarn配置文件,继承core-site.xml配置文件 core-site.xml 参考官方core-default.xml配置字段信息:hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/core-default.xml
该文件是Hadoop的核心配置文件,其目的是配置HDFS地址、端口号,以及临时文件目录。
<configuration> <!-- 用于设置Hadoop的默认文件系统,由URI指定 --> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop1:9000</value> </property> <!-- 配置Hadoop的临时目录,默认/tmp/hadoop-${user.name} --> <property> <name>hadoop.tmp.dir</name> <value>file:/app/hadoop/hadoop-2.6.4/tmp</value> </property> <!-- 指定哪些主机可以充当代理用户 hduser。在这里,设置为 * 表示任何主机 --> <property> <name>hadoop.proxyuser.hduser.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hduser.groups</name> <value>*</value> </property> </configuration> hadoop-env.sh hadoop-env.sh用来保证Hadoop系统能够正常执行HDFS的守护进程NameNode、Secondary NameNode和DataNode。
修改 HADOOP_CONF_DIR 和JAVA_HOME 环境变量值,并添加HADOOP_LOG_DIR 环境变量项。
export JAVA_HOME=/usr/lib/java/jdk1.7.0_79 export HADOOP_LOG_DIR=/app/hadoop/hadoop-2.6.4/tmp export HADOOP_CONF_DIR=/app/hadoop/hadoop-2.6.4/etc/hadoop 修改完之后source编译该文件,让修改生效。
hdfs-site.xml 参考官方hdfs-default.xml配置字段信息:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
该文件用于设置HDFS的NameNode和DataNode两大进程。
<configuration> <!-- 指定secondary namenode的HTTP地址和端口 --> <property> <name>dfs.namenode.secondary.http-address</name> <value>hadoop1:9000</value> </property> <!-- 指定namenode名称空间的存储地址 --> <property> <name>dfs.