校园跑腿系统设计与实现

1.1 毕设背景及意义 随着社会的快速发展和人们生活水平的提高,人们对于生活质量以及时间效率的要求越来越高。而对于校园学生群体来说,他们的时间和精力往往被学习所占据,其他生活需求的满足成为了一项难题。因此,校园跑腿系统的设计应运而生。 校园跑腿系统是一种基于互联网技术的生活服务平台,它的主要目的是为校园学生提供便捷、快速、高效的生活服务。通过校园跑腿系统,学生可以方便地购买日常用品、快递物品、代领外卖等服务,从而将时间和精力更多地用于学习和生活的其他方面,提高了生活效率。 与此同时,校园跑腿系统的设计也为学生提供了一种参与经济活动的途径,可以提高学生的社会经验和创业精神。此外,校园跑腿系统也能够创造就业机会,降低了校园失业率,为社会经济发展起到积极的作用。 1.2 国内外的研究及应用的现状分析介绍 1.2.1 研究的应用范围介绍 校园跑腿系统是一种基于移动互联网技术的服务平台,它主要帮助校内师生完成各种生活需求的配送任务,如快递、外卖、家居用品购买等,为校内师生提供更加便捷、高效的生活方式。 该系统的应用范围主要是校园内部,旨在为校内师生提供更好的生活服务。它可以优化校内跑腿服务的流程,提高校内跑腿服务的效率与质量。同时,系统可适用于不同规模的高校,从小型本科院校到大型综合性大学,以及研究型大学等不同类型的高校。 此外,该系统也可以扩展到其他场景,在一些社区或商业区也可以实现类似的跑腿服务,为居民或商家提供更加便捷的生活服务。总之,校园跑腿系统能够在不同的场景中发挥重要作用,极大地提高服务效率,增强用户体验,为人们带来更加便捷的生活方式。 1.2.2 国内外的应用现状 校园跑腿系统是近年来在校园内逐渐受到关注并得到普及的一种服务形式。该系统通过APP平台或网站,为学生提供生活服务,如购买日常用品、代取快递、送餐等,旨在缓解学生生活中的烦恼和时间压力,提高生活品质和学习效率。在国内外,校园跑腿系统已有很多研究和应用案例,以下进行详细介绍: 美国:在美国的某些大学,如西北大学、伊利诺伊大学等,都存在学生跑腿服务的平台供学生选择。这些平台主要通过APP提供服务,如送外卖、代购等,其中,该系统的供需匹配过程通过算法自主完成,提高了系统的智能化。 新加坡:新加坡的SMU校园内也有校园跑腿进行服务,以从学生中招募志愿者为主,实现互帮互助服务方式,减少学生生活压力。 北京:北大、清华等大学均开展了跑腿服务,通过APP平台发布服务请求和接收任务,系统通过定位信息为任务匹配提供技术保障。 上海:各大高校如上海交通大学、复旦大学等也陆续开发出了跑腿APP,基本面对本校学生提供服务。同时,招募志愿者参与到校园跑腿系统的服务中,增加了系统的稳定性和灵活性。 总体来看,校园跑腿系统在国内外大学校园内已经开始得到广泛应用与探索,服务机制和技术手段也在不断地提升完善,然而在实际应用过程中,仍需解决一些问题,如服务质量、保障安全性等问题,以确保校园跑腿能够实现更好的服务效果。 1.3 毕业设计的主要内容 本校园跑腿系统采用基于web的设计,使用Java语言作为后端开发,并使用ssm框架和MySQL数据库作为技术支持。系统共设有四个角色:用户、商家、管理员和跑腿员,并为每个角色分别设置了相应的功能和权限: 用户:可以注册账号、登录系统并上传个人信息。用户能够发布跑腿项目并根据跑腿类型查看项目信息,还可以搜索相关信息。系统内还设有动态分享功能,用户可以查看和发布自己的帖子与其他用户进行交流,并能够查看系统发布的公告信息。为提高系统内用户的活跃度,用户还能进行跑腿项目管理,包括新增跑腿项目、查看和修改项目信息、发布时间、封面图片、要求时间、接单状态等;确认订单管理,包括查看订单编号、用户账号、用户手机、用户姓名、目标地点、跑腿员手机、接单时间、跑腿费用等信息,并能够确认订单并支付费用;动态分享管理,包括新增动态分享、查看和修改自己发布的动态,以及删除操作。 跑腿员:与用户类似,跑腿员需要在系统内进行注册、上传个人信息,并能够根据系统内用户发布的跑腿项目接单;查看自己接单信息、确认订单管理,包括查看用户确认订单信息、订单编号、用户账号、用户姓名、跑腿费用、跑腿姓名、确认时间、评分、是否支付等;交易反馈,包括新增交易反馈信息、修改和删除自己发布的交易反馈信息。 管理员:具有全面的系统管理权限,可以进行个人中心操作,更改自己的信息和密码;用户管理,包括新增修改和删除用户信息;跑腿员管理,包括新增修改和删除跑腿员信息;跑腿分类管理,包括新增修改和删除跑腿分类信息;跑腿项目管理,包括查看、修改和删除跑腿项目信息;接单信息管理,包括查看接单信息,修改和删除订单信息;确认订单管理,包括查看用户确认订单信息、修改和删除订单信息;动态分享管理,包括查看动态分享信息,修改和删除帖子;交易反馈管理,包括查看交易反馈信息,修改和删除反馈信息;系统管理,包括新增、修改和删除系统公告信息。 商家端拥有多个功能模块,包括个人信息、跑腿项目管理、接单信息管理、提醒信息管理等模块。个人信息模块是商家的基础信息模块,商家可以在这里查看和修改自己的个人信息。跑腿项目管理模块是商家发布和管理新的跑腿项目的模块,商家可以在此模块中创建和编辑跑腿项目,设置项目需求和报酬等。接单信息管理模块用来查看和处理商家收到的跑腿订单,商家可以在此模块中浏览所有的订单详情、接受订单、拒绝订单等。提醒信息管理模块用来提醒商家关于跑腿项目的相关信息,商家可以在此模块中查看订单状态变化、新建订单通知等信息。这些功能模块构成了商家端实用的功能体系。 以上就是本次校园跑腿系统的主要设计内容。 1.4 毕业设计组织结构 首先,本文将对在现有网络环境下的校园跑腿系统的适用范围和使用环境进行了详细的介绍。根据以上所述的研究目的以及软件工程的系统开发原理,本论文被分成以下几个部分。 第一章:首先,对校园跑腿系统的建设背景进行了阐述和分析,并对目前校园跑腿系统的发展和国内外校园跑腿系统的发展状况做了简单的概述,然后对校园跑腿系统的各个部分进行了详细的设计。 第二章:从需求出发,分析了该系统的可行性,并给出了具体的解决方案。对该系统的体系结构,各功能模块,分布式数据库等作了详细的介绍。 第三章:确定了每一个模块要完成的任务,根据不同的用户的具体需要,设计了一个具体的应用案例,并列举了全部的函数,说明了该软件的体系架构设计,以及在多数据源数据库技术中使用到的数据分割和数据分发设计,以及数据库的表结构设计。 第四章:重点说明和介绍了该软件的各功能模块,并对该软件的具体实施进行了详细的程序说明和说明,最后给出了该软件的详细程序,并给出了相应的图形说明。介绍了该系统中的出勤流程,工作原理,工作方法。 第五章:针对该软件的特点,对软件进行了详细的功能及性能试验,并用数据报表的方式给出了结果。 第六章:对全文及整个体系进行了概括,指出了本课题工作存在的缺陷,并对今后进一步的工作进行了预测。 2.1 功能需求分析 该校园跑腿系统的设计有四个用户角色:用户,商家,跑腿员和管理员。系统支持动态分享模块,在动态分享模块内,用户可以发布帖子并与系统内的其他用户进行交流,从而提高系统的用户活跃度。该校园跑腿系统基于web,使用了Java语言和ssm框架以及MySQL数据库等技术开发。 2.1.1 用户需求分析 用户角色的主要功能如下所示: 注册、上传个人信息、登录后修改个人信息浏览不同类型的跑腿项目,可以搜索关键字浏览动态分享并参与讨论查看系统发布的公告信息发布跑腿项目,包括跑腿类型、标题、目标地点、跑腿费用、收货地址、发布时间等信息 6.管理跑腿项目,并确认接单信息 7.确认订单,并支付跑腿费用 8.管理动态分享帖子 通过对用户角色的分析,用户用例图如图2.1所示。 图2.1 用户用例图 2.1.2 跑腿员需求分析 跑腿员角色的主要功能如下所示: 注册、上传个人信息、登录后修改个人信息浏览用户发布的跑腿项目,并可以接单管理接单信息,并确认用户的订单管理确认订单信息,包括确认时间、订单号、跑腿费用等发布、更新或删除交易反馈信息。 通过对跑腿员角色的分析,跑腿员用例图如图2.2所示。 图2.2 跑腿员用例图 2.1.3 管理员需求分析 管理员角色的主要功能如下所示: 修改个人信息和密码管理用户信息,包括新增、修改和删除管理跑腿员信息,包括新增、修改和删除管理商家信息,包括新增、修改和删除管理跑腿类型信息,包括新增、修改和删除管理跑腿项目信息 6.管理接单信息,并确认订单状态管理动态分享信息,包括新增、修改和删除管理交易反馈信息,包括新增、修改和删除管理系统公告信息,包括新增、修改和删除。 通过对管理员角色的分析,管理员用例图如图2.3所示。 图2.3 管理员用例图 2.1.3 商家需求分析 商家端拥有多个功能模块,包括个人信息、跑腿项目管理、接单信息管理、提醒信息管理等模块。 1.个人信息模块是商家的基础信息模块,商家可以在这里查看和修改自己的个人信息。

2023年十大最佳自动化测试工具(建议收藏)

Best Automation Testing Tools for 2023 对更快交付高质量软件(或"快速质量")的需求要求组织以敏捷,持续集成(CI)和DevOps方法论来寻找解决方案。测试自动化是这些方面的重要组成部分。最新的《 2018-2019年世界质量报告》表明,测试自动化是实现"快速质量"的最大瓶颈,因为它是成功采用敏捷和DevOps的推动力。 没有好的工具就无法实现测试自动化。因为它们决定了如何执行自动化以及是否可以实现自动化的好处。测试自动化工具是DevOps工具链中的关键组件。在应用人工智能和机器学习(AI / ML)来提供用于测试优化,智能测试生成,执行和报告的高级功能方面,当前的测试自动化趋势已经增长。有必要了解哪种工具最适合利用这些趋势。 这些顶级的自动化测试工具被认为可以最好地解决未来几年自动化领域的挑战。从以下条件中选择此列表中包括的工具: 支持API和服务测试提供一些AI / ML和分析功能知名度和成熟度 Top 5 Automation Testing Tools for 2023 1.Selenium Selenium是测试自动化的家喻户晓的名字。它被认为是Web应用程序用户界面自动化测试的行业标准。根据"测试自动化挑战调查"显示,十分之九的测试人员中有近九位在其项目中使用或曾经使用过硒。 对于具有编程和脚本编写经验和技能的开发人员和测试人员,Selenium提供了许多其他测试自动化工具和框架所不具备的灵活性。用户可以使用多种语言(例如Java,Groovy,Python,C#,PHP,Ruby和Perl)编写测试脚本,这些脚本可以在多种系统环境(Windows,Mac,Linux)和浏览器(Chrome,Firefox,IE和 无头浏览器)。 Selenium最近于2019年4月发布了其第一个alpha版本的Selenium。Selenium4正式版的发布尚未确定;目前,Selenium 4正式发布。但是您可以期望该版本将具有许多改进和丰富的功能。 为了有效地使用Selenium,用户必须具备高级编程技能,并且需要花费大量时间来构建自动化所需的自动化框架和库。这是Selenium的主要缺点,可通过Katalon Studio等集成工具解决。 许可证:开源 2. Katalon Studio Katalon Studio是功能强大且全面的自动化解决方案,用于测试API,Web,移动和桌面应用程序测试。它还为这些类型的测试提供了丰富的功能集,并支持包括Windows,macOS和Linux在内的多个平台。 利用Selenium和Appium引擎,Katalon Studio为那些难以集成和部署不同框架和库以使用Selenium和Appium的测试人员以及已经熟悉这些引擎的测试人员提供了一个独特的集成环境。 Katalon Studio赢得了Gartner Peer Insights客户的软件测试自动化大奖,获得了450多项正面评价,该评论获得了450多项正面评价,这再次证明该工具现在是市场上最大的公司之一。 该工具的重点包括: API / Web服务,Web和移动应用程序的测试自动化的完整功能集同时支持SOAP和RESTful的API和服务测试数百个用于创建测试用例的内置关键字可用于自动化和探索性测试可以通过Katalon Store上的插件扩展测试功能,深入了解Katalon TestOps上的报告 许可证:免费 3. UFT UFT是测试桌面,Web和移动应用程序的流行商业工具。它已扩展为包括一组用于API测试的功能。通过为被测目标应用程序(AUT)支持多个平台,UFT提供了一种方便的选择来测试可在台式机,Web和移动设备上运行的AUT。 UFT为智能对象检测,基于图像的对象检测和校正提供了几种高级功能。在2019年5月,Microfocus已发布具有新功能和增强功能的最新版UFT(v14.53) 该工具的特点包括: 直观的用户界面,用于创建,执行和报告API测试支持从WADL文档生成API测试测试的动作,活动和参数可以在图表中可视化 许可证:每年3,200美元起。 4. TestComplete 今年,TestComplete凭借其强大,全面的Web,移动和桌面应用程序测试功能继续名列前茅。测试人员可以使用JavaScript,VBScript,Python或C ++ Script编写测试脚本。 与UFT一样,TestComplete具有对象识别引擎,可以准确地检测动态用户界面元素。该引擎在具有动态且经常更改的用户界面的应用程序中特别有用。 最新的TestComplete版本14.2包括与Jenkins的本机集成,以加速CI / CD流程,对Web测试组件(如Shadow DOM和自定义元素)的支持以及对所有最新浏览器版本和移动平台的支持。 测试人员可以轻松使用TestComplete的记录和回放功能,例如Katalon Studio。他们可以将检查点插入测试步骤以验证结果。作为SmartBear的产品,TestComplete可以轻松地与SmartBear提供的其他产品集成。 许可:每位用户每年$ 9,114起

Android API Level一览表

API LevelAndroid版本正式名称首次发布日期后续Android版本备注14Upside Down Cake2023-4-133313Tiramisu2022-02-11附 API 33平台亮点3212L2021-12专门为折叠式设备和大屏幕设备带来多项优化和改进3112S2021-05-193011R2020-09-092910Q2019-06-05(Beta 4)-2022热门应用目标版本,50%设备为此版本及以上289Pie2018-08-06无278.1Oreo2017-12-05无268.0Oreo2017-08-21无257.1Nougat2016-10-047.1.1、7.1.2247.0Nougat2016-08-22无236.0Marshmallow2015-10-056.0.1225.1Lollipop2015-03-095.1.1215.0Lollipop2014-11-125.0.1、5.0.22022热门应用使用最低版本,支持98.0%以上设备204.4wKitkat Wear2014-06-254.4w.1、4.4w.2194.4Kitkat2013-10-314.4.1、4.4.2、4.4.3、4.4.4184.3Jelly Bean2013-07-244.3.1174.2Jelly Bean2012-11-134.2.1、4.2.2164.1Jelly Bean2012-07-094.1.1、4.1.2154.0.3IceCreamSandwich2011-12-164.0.4144.0IceCreamSandwich2011-10-184.0.1、4.0.2133.2Honeycomb2011-07-153.2.1、3.2.2、3.2.3、3.2.4、3.2.5、3.2.6123.1Honeycomb2011-05-10无113.0Honeycomb2011-02-22无102.3.3Gingerbread2011-02-092.3.4、2.3.5、2.3.6、2.3.72021-09-27日之后停止维护2.3.7版本92.3Gingerbread2010-12-062.3.1、2.3.282.2Froyo2010-05-202.2.1、2.2.2、2.2.372.1Eclair2010-01-12无62.0.12009-12-03无52.02009-10-26无41.62009-09-15无31.52009-04-27无21.12009-02-09无11.02008-09-23无 API 33 平台亮点 1.将支持在锁屏界面添加 QR 扫描器,更方便地扫描二维码。 2.点击流转媒体的功能。 3.将拥有更多改进,比如为单个 App 指定语言、蓝牙 LE Audi。 4.增加了一个系统照片选择器。 5.为通过 Wi-Fi 管理设备与附近接入点连接的应用程序引入了 NEARBY_WIFI_DEVICES 运行时权限(NEARBY_DEVICES 权限组的一部分)。调用许多常用的 Wi-Fi API 的应用程序将需要新的权限,并使应用程序能够通过 Wi-Fi 发现和连接附近的设备,而不需要位置权限。 6.将“隐私和安全”作为一个主要更新,重点是“通过在设备上提供更安全的环境和向用户提供更多控制,为所有人构建一个负责任的高质量平台”。这从开发者预览版 1 中的系统照片选择器开始,以提供“标准和优化的方式,让用户安全地分享本地和云端的照片”。 7.延续了Material You设计语言,支持用户打造个性化界面,允许用户对特定的APP进行语言设置。比如系统设定语言为英文,但是用户可以设定某个APP的语言为中文。 8.针对折叠屏、平板电脑等大屏设备进行了适配优化,谷歌强化了界面设计,让更多应用程序可以无缝适配不同尺寸的Android设备,让应用体验更佳。

基于微信小程序实现在线诗歌赏析系统的设计与实现演示【附项目源码+论文说明】

基于微信小程序实现在线诗歌赏析系统的设计与实现演示 摘要 随着智能应用程序开发的普及,各种应用程序在人们的视野中如雨后春笋般涌现。同时,带来了很多不便,功能多种多样,使人们无法选择。同时,它也对智能手机的存储容量进行了相当大的考验。硬件升级只是一个无奈的解决方案。由此,微信小程序应运而生。将传统的应用程序和微信小程序相比,微信小程序不占用手机的存储空间,节省了流量和安装的繁琐操作。尽管在使用层面上无法与传统应用相比,但它可以实现基本功能。用户界面和操作步骤非常简单,大大降低了用户的操作难度。适合多年龄段的用户。同时,微信应用程序的开发成本较低,因此开发团队可以将大部分成本投入运营和推广,从而专注于产品本身。 微信丰富的功能和在社会中的广泛使用,引发了对微信在在线诗词鉴赏中应用的研究和探讨,人们对此做了许多尝试。 本论文首先对基于微信小程序的在线诗词鉴赏进行了需求分析,从系统开发环境、系统目标、设计流程、功能设计等几个方面进行系统的总体设计,在此基础上实现了基于微信小程序的在线诗词鉴赏的多种功能,包括有诗词查找、诗歌分享、用户评论、诗词游戏等各项功能的设计,实现对在线诗词鉴赏展示。通过对系统的功能进行测试,测试结果证明该系统界面友好、功能完善,有着较高的使用价值,具有庞大的潜在用户群体和较广阔的应用前景。 关键词:微信小程序,诗词鉴赏,系统设计 课题的研究背景 古诗词作为中华文化独有的一种文体,是中华民族最精粹的文学样式,它语言精炼,意蕴含蓄,想象丰富,意境深远,有着特殊的格式及韵律,是中华文化艺术宝库中的一朵奇葩,是最灿烂辉煌的世界文化遗产。唐诗宋词是中华文化宝库中的一颗明珠,正得到越来越多人的喜爱与学习。随着《中国诗词大会》节目的火爆,赏中华诗词,寻文化基因,品生活之美逐渐被大众所接受和喜爱,节目通过对古诗词的赏析以及相关比拼,带领观众重新感受古诗词的魅力。本课题以微信小程序为基础设计与实现在线诗词赏析系统,着重于提高国民的诗词积累以及文化素养。 随着科学技术的发展和计算机的深入普及,中国的诗词已经不能单纯的靠纸质书籍传播。我们应该借助科技的发展,向全世界传播中华诗词,让更多的人领略到中华古诗词的魅力。长期以来,各式各样的古诗词鉴赏网站层出不穷,但是极大部分是将诗词鉴赏模块嵌入到网站中,很多人在复杂的网站中难以找到自己想要的诗词,网站基本也拥有留言系统,但是用来统计用户对其网站的意见,并没有针对诗词鉴赏,看是有用,实则无用。现在很少专门针对古诗词的鉴赏的网站,本人根据古诗词鉴赏网站的发展情况推出专门针对诗歌鉴赏的微信小程序,为广大用户提供真正的诗词交流的平台。有人说21世纪是注意力经济时代,如此多的网站内容势必会分散用户注意,难以得到良好的文化经济。本小程序秉持专而精的精神。服务用户,保护用户的注意,构建良好的交流平台,为用户带来真正的诗词鉴赏系统。 综上所述,随着网络文化的快速发展,制作独立的、功能全面诗词鉴赏小程序,将会成为诗词鉴赏发展的重点和热点。在移动互联网时代,利用移动终端进行中华古典诗词的弘扬和传承具有重要意义,不仅可以使青少年重拾古典诗词的文化魅力,而且可以使优秀的传统文化发扬光大。 本课题研究内容 本课题题目是基于微信小程序的在线诗词鉴赏的设计与实现,本人通过需求分析和设计出了在线诗词鉴赏客户端,主要实现功能包括: 1. 提供古代经典诗词的全文和赏析以及作者、朝代等数据。 2.实现诗歌的分类查找功能。 3.实现诗歌的收藏与分享功能。 4.实现用户点赞和评论功能。 5.提供飞花令,成语接龙,诗词填空等多种游戏手段。 ​​​​​​​微信小程序背景 在2016年底,微信应用程序的出现吸引了广大用户和开发者的关注,以及众多多媒体的关注,甚至很多企业都期待它。该应用程序颠覆了传统应用程序。首先,在便利性方面,APP应用程序需要下载并安装在软件应用程序商城中,而该应用程序仅需在微信中进行搜索和打开。其次,就手机负载而言,APP下载包或程序缓存将占用一部分手机内存,而微信小程序则不需要占用手机内存。最后,在功能级别上,尽管小程序可能无法取代应用程序的所有功能,但足以满足用户的核心需求。 “这是一个不需要下载或安装的应用程序。用户可以通过扫描或搜索来打开应用程序,实现应用程序“触手可及”的梦想。用户不必担心安装所需的空间太多的应用程序,反映了“用完了就去”的概念。应用程序无处不在,可以立即使用,但无需安装和卸载。“这是微信应用程序带来的梦想和想法。 由于微信平台的普及,微信本身吸引了足够的用户,开发人员和企业。微信小程序再加上小程序简单方便的功能,如“触手可及,用完就去”,无疑将为用户带来前所未有的体验。由于小程序开发的便利性和开发成本的降低,微信小程序是大多数开发人员的福音。同时,由于微信强大的流程渠道和沟通渠道,大大降低了开发的小程序的推广和操作难度,也为许多企业带来了很多好处和价值。 系统页面展示 用户进入小程序后,便可看到程序的主界面,具体如图5-1所示。图中中间部分包含搜索栏,可以对作者、题目、诗句进行搜索。 诗词查找模块界面,可以按照类型、朝代等不同关键词分类进行查找,如图5-2所示。 在诗词展示模块界面中,会展示诗词的具体内容以及诗词的解释、翻译和赏析,用户可以进行评论、收藏和分享,如图5-3所示。 如需要可扫取文章下方二维码联系得源码 

解读一下最近Midjourney开放的中国版

最近Midjourney在中国开放测试申请,吸引了众多朋友加入,但也存在许多问题需要解答。因此,我决定撰写一份使用指南,以帮助大家更好地理解与国际版的差异。 接下来,我将分为两个部分进行详细介绍,其中一部分涵盖了免费用户可使用的功能和限制,而一些基础功能也将在此呈现。另一部分则是介绍付费用户可使用的功能和相关费用。 一、免费用户 对于免费用户而言,其可生成的图片数量为25张,然而一旦使用完毕,将无法进行补充,同时,Variation变化和定向修改也将耗费次数。 进入QQ频道后,您可以在想象创作和主题创作分类下的任意一个分区中进行图像生成。 在生成图像的过程中,与Discord类似的使用/命令方式不同的是,QQ没有自动补全的功能,需要手动操作或复制。当你输入@Midjourney-测试中/想象加你的提示词时,会调用Midjourney模型;而当你输入@Midjourney-测试中/漫画加你的提示词时,则会调用Niji模型。这两种方法都是通过修改鼠标光标位置来实现的。与Discord类似,调整比例和更换模型的操作也采用了-ar16:9或-v5的方式。 一旦你生成了图片,机器人便会自动以@的方式与你联系,一旦你找到了所生成的图片,就可以开始进行后续的操作。这两种方法都是通过修改鼠标光标位置来实现的。与Discord相比,生成变体和放大图片的操作方式略有不同。由于QQ频道无法为消息添加额外的按钮操作,因此你需要右键选择回复相应的消息,然后手动输入U4或V4等文字来进行变体的生成。 以上是可供免费使用的功能和操作步骤,接下来我们将探讨订阅会员的流程、会员权益以及操作步骤。 二、付费用户 在此,我制作了一张对比图,展示了Midjourney在中国的各个等级权益,并加上了相应的价格以及对应的国际版本。在这张图片上我们可以看到,小程序和国际版的价格相差很多,但是功能却差不多。与国际版相比,该小程序的图像生成权限和图生图的权限略有不同,但在价格和功能方面都有显著的提升。 关于如何订阅? 关于订阅,一旦您在频道中输入或订阅,机器人将私信您一个订阅的二维码,随后您可以使用手机端扫码的小程序进行支付,并选择需要支付的会员进行付款即可。 关于如何使用小程序? 当你找到机器人私信它/画廊时,它会自动发送你的小程序二维码,只需长按该二维码,即可轻松拉起小程序。 在小程序的主页上,你可以找到两个部分,一个是过去生成的所有图片点,里面包含了大图和相应的提示词;另一个是生成台语片的功能输入框,其中输入了提示词,点击帆船图标即可开始生成。如果你的版本为68,那么你将无法观察到下方的输入框。 通过点击加号,您可以将图片上传至图生图中,以便更好地呈现图像。 当您点击三个点的图标时,您将获得三个选项,第一个是切换至Mid还是Niji模型,第二个是切换至模型版本,第三个则是切换生成图片的比例。 一旦生成了图片,它将在画廊中呈现,只需点击U4或V4即可继续操作,而生成的图像也将在画廊中展示。 以上所述即为所有指引的完整内容。 写在最后,赤辰最近All in Ai,一切工作流和生活流几乎都试着重塑一遍,持续输出更多自用案例及实践思考和最新学习技术资料,(公仲浩)赤辰AI运营变现实操记,欢迎关注!

vue3+ts ----element-plus使用日历等插件如何把语言环境英文改成中文

vue3+ts ----element-plus使用日历等插件如何把语言环境英文改成中文 全局更改element-plus语言环境 在main.ts中如下加入: //element-plus import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import locale from 'element-plus/lib/locale/lang/zh-cn' //中文 //element-plus app.use(ElementPlus, { locale }) PS:如果locale 路径报错的话 ,建议重新安装一下element-plus npm install element-plus --save

Flutter 底部抽屉,三阶滑动;

Flutter 底部抽屉,三阶滑动,但不跟随手指滑动、效果一般;Head布局可以触发抽屉滑动, 内部的Sliver布局单独滑动; 推荐看这篇文章,支持列表Sliver滑动;Flutter 底部列表抽屉,三阶滑动 , 支持列表Sliver布局_Choi晨的博客-CSDN博客 、、 import 'package:flutter/material.dart'; class SlidingPanel3Controller { _SlidingPanel3ViewState? onState; _addState(_SlidingPanel3ViewState? onState){ this.onState = onState; } void setPanel3State(Panel3State state){ onState?.setPanel3state(state); } Panel3State getPanel3State(){ return onState?._panel3state.value ?? Panel3State.CENTER; } } enum Panel3State { OPEN, CENTER, CLOSE, EXIT } class SlidingPanel3View extends StatefulWidget { final double heightOpen; //展开高度 final double heightCenter; //中间高度 final double heightClose; //闭合高度 final Widget headWidget; //标题布局(内含滑动操作) final Widget bodyWidget; //内容布局 final Panel3State initPanel3state; //初始状态 final Color backColor; //背景色 final SlidingPanel3Controller?

【VS CODE提示#include错误】

## 关于VS CODE编辑KEIL工程每次打开都提示#include错误 跟大家一样,用keil编辑代码太不舒服了,自然而然就想到了用VS CODE这款强大的编译器了,于是就到网上搜了教程,老是遇到一个问题就是提示#include错误,我在网上搜说是缺少MinGW,下载也配置了依然解决不了问题,其实重要原因就是所包含路径跟KEIL配置的头文件路径相关联。如下所示问题步骤: 点击黄色灯泡前面显示两行1:添加到。。。(这种就是手动添加可以临时解决,下一次打开又是这样)2.进入编辑“includePath”设置 这里我选择编译器路径就是之前安装的MinGW,点击c_cpp_properties.json 这里就能看到自己所能包含的所有头文件路劲,其中框起来的就是我所缺少的头文件路径(里面对应的是stm32f10x.h)无论是自己手动添加,还是gcc更新都只能管这一次的下一次还得添加 解决办法 打开keil工程点击魔术棒,点击C/C++ 点击Include Paths那三个点进入 添加VS CODE提示缺少的头文件路径,点击OK保存之后,这样VS CODE那边每次打开都会同步路径

linux系统suid提权

什么是suid ​suid(set uid)是linux中的一种特殊权限,suid可以让调用者以文件拥有者身份运行该文件,所以利用suid提权的核心就是运行root用户所拥有的suid的文件,那么运行该文件的时候就得获得root用户的身份了。 suid特点是用户运行某个程序时,如果该程序有suid权限,程序运行进程的属主不是发起者,而是程序文件所属的属主。 linux引入了3个文件来管理用户组: 1. /etc/passwd存放用户信息。 2. /etc/shadow存放用户密码信息。 3. /etc/group存放组信息。 在文件系统中的每个文件的文件头里面添加了用户和文件之间的关系信息。 用户信息/etc/passwd每行共有7个字段冒号隔开: 字段1为用户名。 字段2为用户的密码。 字段3为指UID,每个用户都有自己的uid。 字段4为组UID,每个用户都有不同的uid。 字段5为解释说明的字段。 字段6为指用户的家目录。 字段7为指登录shell,用户登录shell,当前为/bin/bash表示可以登录,/sbin/nologin标识不被授权登录。 利用特点​ 在执行过程中,调用者会暂时获得该文件的所有者权限,且该权限只在程序执行的过程中有效。 只有root用户的uid是0,如果黑客把一个普通用户的uid修改为0,那么他只要以普通用户的用户名和密码登录系统就会自动切换到root用户,在系统加固时一定要找出有哪些用户的uid为0。 假设可执行文件binexec其属主为root,当以非root身份登录时,如binexec设置了suid权限,就可以在非root身份下运行该可执行文件,可执行文件运行时该进程的权限为root权限。 利用此特性,就可通过suid进行提权。 设置suid 设置SUID权限 chmod u+s filename 设置SUID位 chmod u-s filename 去掉SUID设置 查看文件权限 chmod u+s binexec 可以看到binexec文件的权限描述符由-rwxr-xr-x变为-rwsr-xr-x,已经获得了suid权限。 可执行文件提权 具有suid权限的二进制可执行文件如下: nmap vim find bash more less nano cp awk 如下命令可以找到正在系统上运行的所有suid可执行文件。 这个命令将从/目录中查找具有suid权限位且属主为root的文件并输出它们,然后将所有错误重定向到/dev/null,列出该用户具有访问权限的那些二进制文件。 find / -user root -perm -4000 -print 2>/dev/null find / -perm -u=s -type f 2>/dev/null find / -user root -perm -4000 -exec ls -ldb {} ; 以上所有的二进制文件都将以root权限运行,随便找一个。

华为OD机试真题 Java 实现【跳房子II】【2023 B卷 100分】,附详细解题思路

一、题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏。 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格,然后获得一次选房子的机会,直到所有房子都被选完,房子最多的人获胜。 跳房子的过程中,如果有踩线等违规行为会结束当前回合,甚至可能倒退几步。 假设房子的总格数是count,小红每回合可能连续跳的步数都放在数据steps中,请问数组中是否有一种步数的组合,可以让小红三个回合跳到最后一格?如果有,请输出索引和最小的步数组合,数据保证索引和最小的步数组合是唯一的。 注意:数组中的步数可以重复,但数组中的元素不能重复使用。 二、输入描述 第一行输入为房子总格数count,它是整数类型int。 第二行输入为每回合可能连续跳过的步数,它是整数数组类型。 三、输出描述 返回索引和最小满足要求的步数组合。 注意:顺序保持steps中的原有顺序。 四、补充说明 count <= 10000;3 <= steps.length <= 10000;-100000 <= steps[i] <= 100000; 五、解题思路 这道题的【题目描述】优点复杂,说的也不是很清晰。 简而言之,就是: 第一行输入一个数count; 第二行输入若干个数steps; 将第二行中的数字,以任意组合的方式(保证三个回合跳到最后一格),等于count即可,看看一共有多少种,然后选出索引和最小的那一组数据,按顺序输出即可。 万丈高楼平地起,稳扎稳打,先理清思路,找准方向,再动手。 输入房子总格数count;输入每回合可能连续跳过的步数;递归选出索引和最小的那一组数据; 遍历steps数组中的数字,每三个数字进行依次递归;如果不满足条件,将第三个数字删除,再添加一个新的数字;再比较小红跳的步数集合是否等于count;循环往复 小红跳的步数集合等于count 且 选出索引和最小的那一组数据;返回索引和最小满足要求的步数组合; 六、Java算法源码 // 最小索引和 public static int min = 100000; // 三个回合跳到最后一格 public static int three = 3; // 房子总格数count public static int count; // 选出索引和最小的那一组数据 public static List<Integer> minIndexList; public static void main(String[] args) { Scanner sc = new Scanner(System.

【Flink】DataStream API使用之输出算子(Sink)

输出算子(Sink) Flink作为数据处理框架,最终还是需要把计算处理的结果写入到外部存储,为外部应用提供支持。Flink提供了很多方式输出到外部系统。 1. 连接外部系统 在Flink中我们可以在各种Fuction中处理输出到外部系统,但是Flink作为一个快速的分布式实时流处理系统,对稳定性和容错性要求极高。一旦出现故障,我们应该有能力恢复之前的状态,保障处理结果的正确性。这种性质一般被称为"状态一致性"。Flink内部提供了一致性检查点checkpoint来保障我们可以回滚到正确的状态,但是我们在处理过程中任意读写外部系统,发生故障后就很难回退到从前了。 所以Flink的DataStream API提供了专门向外部写入数据的方法,通过addSink实现,与addSource类似,addSink方法对应着一个Sink算子,主要就是来实现与外部系统连接,并将数据提交写入;Flink程序中所有对外的输出操作一般都是利用Sink算子完成的。比如我们经常使用的print 方法返回的就是一个 DataStreamSink。 Sink算子的创建主要是通过DataSream的.addSink()实现的,并且需要重写default void invoke(IN value, Context context) throws Exception 方法 Flink提供的连接器,这个是1.17版本的,比1.13版本的多很多 除了官方的,Flink也可以使用Apache Bahir的扩展连接器 2. 输出到文件 输出文件Flink有writeAsText()、writeAsCsv()可以直接输出到文件,但是这种不支持同时写一份文件,必须设定为并行度为1,所以Flink又提供了一个专门的流式文件系统的连接器StreamingFileSink。 SreamingFileSink继承自抽象类RichSinkFunction,而且集成Flink的检查点机制(checkpoint)用来保证精确一次的一致性语义。 StreamingFileSInk主要操作是将数据写入桶,每个桶中的数据都可以分割成一个个大小有限的分区文件,并且也可以通过各种配置来控制分桶的操作;默认的分桶方式是基于时间的。 StreamingFileSink(Row-encoded)支持行编码和批量编码(Bulk-encoded,比如 Parquet)格式,这两种不同的方式都有各自的构建器: 行编码:StreamingFileSink.forRowFormat(basePath,rowEncoder)批量编码:StreamingFileSink.forBulkFormat(basePath,bulkWriterFactory) 代码实例: public static void main(String[] args) throws Exception { // 1. 直接调用getExecutionEnvironment 方法,底层源码可以自由判断是本地执行环境还是集群的执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(2); // 2. 从集合中读取数据 ArrayList<Event> list = new ArrayList<>(); list.add(new Event("ming","www.baidu1.com",1200L)); list.add(new Event("xiaohu","www.baidu2.com",1200L)); list.add(new Event("xiaohu","www.baidu5.com",1267L)); list.add(new Event("gala","www.baidu6.com",1200L)); list.add(new Event("ming","www.baidu7.com",4200L)); list.add(new Event("xiaohu","www.baidu8.com",5500L)); // 3. 读取数据 DataStreamSource<Event> eventDataStreamSource = env.

轻松搞懂Java类加载与SPI机制

你知道Java的类加载机制吗?你了解双亲委派模型吗?你知道怎么打破双亲委派模型吗?这些都是面试经常出现的问题,今天我带大家从类加载机制出发,帮助大家快速掌握Java的SPI机制与Spring的SPI机制。 1.Java类加载机制 java的类加载如图,大概分为以下阶段: 1.1加载:加载.class文件进入内存,以双亲委派模式 1.2.验证:验证文件的正确性、合法性,确保.class文件格式的正确 1.3准备:将类变量分配内存,赋予初值(注意,初值是临时值,比如boolean类型变量会统一赋予false,int变量会统一赋予0) 1.4解析:符号引用替换成直接引用,什么意思呢,如果你一个类里面有引用另一个类。.class文件使用字符来去引用描述,在这个阶段会替换直接指向实际的物理内存地址。 1.5将初值替换为程序指定的值,初值只是赋予的临时值,这个阶段会变成你程序设置的实际数值。 初始化后,类方法执行顺序: 父类静态方法 -> 子类的静态方法 ->父类的非静态方法 ->父类的构造方法 ->子类的非静态方法 ->子类的构造方法。 2.双亲委派模式 上面提到,在加载阶段,会用双亲委派模式去加载.class文件。那么什么是双亲委派呢 当一个类加载器收到一个加载请求,它不会自己加载,它会委托父类加载器进行加载。如果父类加载器上面还有父类,它会继续向上委托,一直到顶部加载器。如果父类加载器能够进行加载,会直接加载任务返回,否则子类加载器才会自己尝试加载。 3.双亲委派模式怎么打破 3.1 继承ClassLoader,重写findClass方法 public class ClassLoaderTest extends ClassLoader{ @Override protected Class<?> findClass(String name) { //读取.class数据 String fileName="xxx/"+name.replace(".","/")+".class"; byte[] classData =null; try (InputStream fileInputStream = new FileInputStream(fileName)) { classData=new byte[fileInputStream.available()]; fileInputStream.read(classData); } catch (Exception e) { e.printStackTrace(); return null; } //定义类返回类对象,ClassLoader自带方法 return defineClass(fileName,classData,0,classData.length); } } 3.2 Java的SPI机制 Java的一种机制,在ClassPath路径下的META-INF/services定义文件,就会自动加载文件里所定义的类。最典型的就是jdbc的SPI机制。因为有Oracle,mysql等等各种第三方数据库,Java源码不可能把所有数据库厂商都对接一遍,所以使用SPI机制,让数据库厂商自己去实现对应的逻辑。mysql-connector.jar就是这么实现的 4.Spring SPI机制 Spring框架在实现时,无疑也采用了Java的设计。只要找到Spring-boot-autoConfigure包,照着这个文件复制,修改下,Springboot启动时就会自动加载第三方类。

C++:【数据结构】trie树

这篇文章来介绍一个比较重要的数据结构:字典树(TrieTree)。其中 trie 一词来自于英语单词 retrieval 【检索】。 目录 背景知识实现方式 背景知识 首先来谈谈为什么会出现这么个东西。现在有一堆单词(也可能是其他的东西),然后给出一个单词,让你检查一下它是不是在这一堆里面。当然我们可以直接遍历所有单词,一个一个去比较,作为一个程序员,这样很明显是十分愚蠢的。那么我们就得想办法优化一下。怎么优化呢,想想你去英语词典里找单词,难道你要从第一页开始一个词一个词找吗?显然不是。正常人的做法是先找首字母,找到一个范围,再去那个范围里找第二个字母,以此类推。那么我们的字典树就是这样一种数据结构。 所谓字典树,就是把前面几个字母一样的单词(不一定是单词,也可以是别的,因为单词较简单,这里用查找单词为例)放在一起,这样不但节省了空间,而且想找某个单词也比较容易,只要沿着字母顺序捋下来,看看有没有符合的就好。这样形成了一种树状结构,支持插入和删除操作。可能树状并不太好理解,那我们就画图来模拟一下。 首先我们插入单词 abc 和 bcd: 这时候我们再插入单词 abd,bc。这时候注意到前缀ab已经存在了,所以只需要在 ab 下面补上新的单词就行了。添加 bc 的时候我们发现,它就在字典树中,那这时候我们就要区分一下 bcd 和 bc 了,那么我们在每次插入单词的时候有意地去标记一下单词结尾: 差不多就是这个样子了。现在想要查询一下 abc,沿着红色的路径走下来,找到了 abc;想要查询一下 bc,沿着绿色的路径走下来找到了 bc。注意我们想要查询 ab 的时候就出了一些小问题:ab 在树里,但是 ab 并没有被标记成一个单词,所以也算是查询失败。 这就是大致思路了,下面我们来实现吧。 实现方式 首先我们自然想到用指针来实现,但是回过头想想,以存储单词(全是小写字母)为例,一个节点需要指出26个指针,那未免有点疯狂。所以我们这里选择用数组来建树。 我们直接用一道例题来说明:acwing.Trie字符串统计 维护一个字符串集合,支持两种操作: I x 向集合中插入一个字符串 x;Q x 询问一个字符串在集合中出现了多少次。 共有 N 个操作,所有输入的字符串总长度不超过 10^5,字符串仅包含小>写英文字母。 输入格式 第一行包含整数 N,表示操作数。 接下来 N 行,每行包含一个操作指令,指令为 I x 或 Q x 中的一种。 输出格式 对于每个询问指令 Q x,都要输出一个整数作为结果,表示 x 在集合中出现的次数。 每个结果占一行。 数据范围

C++:单调栈和单调队列及其应用

栈和队列是两个很重要的数据结构。其中单调栈和单调队列是栈和队列的“特别版”。下面就来介绍一下单调栈和单调队列以及它们可能的用处。 目录 一、单调栈1、栈2、单调栈①、寻找某一个数左边第一个小于它的数②、寻找某一个数右边第一个小于它的数的==下标==③、寻找某一个数右边第一个大于它的数④、寻找某一个数右边第一个大于它的数的下标 二、单调队列1、队列2、单调(双端)队列 一、单调栈 1、栈 栈是限制插入和删除操作只能在一个位置上进行的表,这个位置是表的末端,叫栈顶。对栈的基本操作有入栈(push)和出栈(pop)。通俗点说,就是一个有底的罐子,可以往里面放东西,放的时候只能放在最上面,拿的时候也只能拿最上面的东西。栈的实现很简单,这里我用数组来实现,并且由于这篇文章主要用来介绍单调栈和单调队列,所以只实现一些简单的操作。直接上代码: const int N = 100010; //算法题不需要考虑大型程序中变量名字冲突的问题,因此定义全局变量 //tail的首字母是t,就起名叫tt吧 int stk[N], tt = 0; //插入操作:向栈顶插入一个数 void push(int x) { stk[ ++ tt] = x; } //删除操作:弹出栈顶的数 void pop() { tt -- ; } //查询栈顶的值 int query() { return stk[tt]; } //判断栈是否为空,空的返回0,否则返回1 bool is_empty() { return tt; } 2、单调栈 所谓单调栈,就是字面意思,单调的栈(从栈底到栈顶)。单调栈分为两种:单调增加的栈和单调减少的栈。具体一点就是说,在每次增加元素的时候,在保证删除最少元素的情况下,保持栈的单调性。 我们举个例子,单调减少的栈: void insert(int x) { //判断栈是否为空,并且把小于等于x的数都弹出 while (tt && stk[tt] <= x) tt -- ; stk[ ++ tt] = x; } 那么单调栈有什么用呢,最典型的一种问题就是:在一串数中,找到某一个数左边(或右边)第一个比它小(大)的数的值或下标。其他问题用到的很少,基本不用考虑。

Java程序执行流程

Java程序执行的整个过程可以分为三个阶段:编译、加载和运行 1.编译 Java程序的源代码需要经过编译器(例如javac)的编译,将其转换成字节码(即.class文件),这个过程称为编译。编译器会对源代码中的语法进行检查和优化,并生成可在JVM上运行的字节码文件。 2.类加载 当Java程序启动时,JVM就会创建一个类加载器(ClassLoader)树来加载所有的类。类加载器负责在运行时将类的字节码文件加载到内存中,并创建对应的Class对象。类加载器会按照一定的顺序加载类,通常是先由系统类加载器(AppClassLoader)加载本地路径下的类,如果找不到则由扩展类加载器(ExtClassLoader)加载,最后由启动类加载器(BootstrapClassLoader)加载JRE中的核心类。 类加载器会执行以下三个步骤: 装载:查找并加载字节码文件;链接:对字节码文件进行验证、准备和解析;初始化:对类进行初始化,包括执行类的static块(如果有)和类变量的赋值。 3.执行 在加载完成后,JVM会执行main方法。具体执行过程如下: 创建主线程;将main方法所在类的字节码文件装载到JVM内存中;执行该类的static代码块(如果有);如果该类有父类,依次执行其父类的static代码块(如果有);执行main方法。 在执行main方法时,JVM将会按照程序员编写的语句依次执行,在执行完毕后,程序结束。 4.垃圾回收 在Java程序执行过程中,JVM需要管理内存,包括分配、使用和释放内存。当一个对象不再被引用时,JVM会通过垃圾回收机制将其回收并释放内存。垃圾回收器会定期扫描堆内存中的对象,标记不再被引用的对象为垃圾对象,然后清理掉这些对象所占用的内存空间。 有关垃圾回收机制可以参考我的另一篇博客:JVM内存回收机制_源末coco的博客-CSDN博客

scrapy--模拟登录--设置cookie

本文主要讲述模拟登录。 scrapy是怎么开始请求的 通过scrapy genspider 爬虫名.py 域名后观察对应的python文件 import scrapy class LoginSpider(scrapy.Spider): name = "login" allowed_domains = ["17k.com"] def parse(self, response, **kwargs): pass 思考start_urls = ["https://17k.com"]这个scrapy是怎么请求的。 可以看出类LoginSpider是继承scrapy.Spider。观察scrapy.Spider后发现scrapy.Spider中有一个方法start_requests。这个方法就是scrapy发送请求的地方。 def start_requests(self): if not self.start_urls and hasattr(self, "start_url"): raise AttributeError( "Crawling could not start: 'start_urls' not found " "or empty (but found 'start_url' attribute instead, " "did you miss an 's'?)" ) for url in self.start_urls: yield Request(url,dont_filter=True) 这个里面默认没有cookie,scrapy.spider给的start_requests()其实是不满足需求的。按住Request进入观察 def __init__( self, url: str, callback: Optional[Callable] = None, method: str = "

qt程序诡异bug一例,ctrl+c,ctrl+x,剪贴板无法使用

qt程序,写着写着发现ctrl+c复制不起作用,鼠标右键选中copy或者cut也不工作,写代码向剪贴板复制也不行,调试来调试去发现是com组件初始化造成的问题,我额外的多调用了两次CoUninitialize()就造成了QLineEdit不能复制或者剪切了,神奇,去掉多余的CoUninitialize()后问题解决。

linux 内存占用、内存泄漏

1. slab debug定位kernelspace内存泄露的方法¶ 以下为辅助定位内存泄漏的手段,主要是针对内存kmalloc。 在kernel中打开如下两个config 查看meminfo 如下图,若SUnreclaim一直增加即可初步判断为内核中kmalloc之后没有释放,导致内存泄漏。 slabinfo对比 开机启动时使用cat /proc/slabinfo备份,出现泄露后再使用cat/proc/slabinfo,将两者进行对比。 分析上图数据 图中kmalloc-8192的次数增加较多,在/sys/kernel/slab/kmalloc-8192/alloc_calls中查看调用kmalloc-8192的symbol和他调用的次数,定位到出现泄露的function。 2. kmemleak--Kernel space内存泄露分析工具¶ 2.1. kernel mode的memory申请¶ SDK里申请kernel mode的memory,主要有两种方式: vmalloc 分配大块内存,走budy system;通过cat/proc/vmallocinfo可以统计; 注:Cat vmallocinfo,如果有buffer块数一直在增加,则是内存泄露。 kmalloc/kmem_cache_create 分配小于pagesize,走slab机制;通过cat /proc/meminfo里的slab字段可以统计。 注:如果怀疑有kernel mode内存泄露,运行应用过程中每间隔一段时间cat/proc/meminfo留意slab。如果一直在增加,大概率有内存泄露的可能。具体模块的函数泄露可以用kmemleak debug。 2.2. 检查内存泄漏的方法 -- Kernel Space¶ Linux kernel 2.6.31后的版本,提供了 KMEMLEAK 的选项,可以拿来测试 kernel modules是否有 memory leakage,用法整理如下。 修改 .config 设定 KMEMLEAK,重新编译 kernel,重烧 image。 摘录 .config 如下: # # Memory Debugging # CONFIG_HAVE_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4096 确认板子上的 kernel 已经提供 kmemleak的功能 # mount -t debugfs nodev /sys/kernel/debug/ # cat /sys/kernel/debug/kmemleak 注:若存在 kmemleak,表示 kernel 已经支援 kmemleak

Flutter 底部列表抽屉,三阶滑动 , 支持列表Sliver布局

Flutter 底部是列表的抽屉,三阶滑动,支持列表Sliver布局,Head布局可以触发抽屉滑动, 内部的Sliver布局也可以触发抽屉滑动; 抽屉在最大高度时,Sliver布局可以滑动,其他高度会触发抽屉滑动; 、、 import 'package:flutter/material.dart'; class SliverPanel3Controller { _SliverPanel3ViewState? onState; _addState(_SliverPanel3ViewState? onState){ this.onState = onState; } void setPanel3State(Panel3State state){ onState?.setPanel3state(state); } Panel3State getPanel3State(){ return onState?._panel3state.value ?? Panel3State.CENTER; } } enum Panel3State { OPEN, CENTER, CLOSE, EXIT } class SliverPanel3View extends StatefulWidget { final double heightOpen; //展开高度 final double heightCenter; //中间高度 final double heightClose; //闭合高度 final Widget headWidget; //标题布局 final Widget Function(ScrollController sc , ScrollPhysics? physics)? bodyWidget; //内容布局 final Panel3State initPanel3state; //初始状态 final Color backColor; //背景色 final SliverPanel3Controller?

C/C++ 知识点:初始化操作由 case 标签跳过

一、初始化操作由 case 标签跳过 如果要在case里面定义变量,需要用括号括起来{},不然会出错,例如: #include <iostream> using namespace std; void main() { int val = 2; switch(val) { case 1: int x = 20; break; case 2: break; default: } } 上面的代码在编译时就会出现下面的错误 main.cpp(15): error C2360: “x”的初始化操作由“case”标签跳过

C++ 宏定义

一、宏定义 1.1、宏概念 宏定义简单点说就是查找替换(文本替换),C中的宏分为两类,对象宏和函数宏。宏定义的一般形式为: #define 宏名 字符串 注意: 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束 1.2、宏作用阶段 编译一个C语言程序的第一步骤就是预处理阶段,这一阶段就是宏发挥作用的阶段。C预处理器在源代码编译之前对其进行一些文本性质的操作,主要任务包括删除注释、插入被#include进来的文件内容、定义和替换由#define 定义的符号以及确定代码部分内容是否根据条件编译(#if )来进行编译。”文本性质”的操作,就是指只是简单粗暴的进行文本替换,而不考虑其中任何的语义内容。 1.3、宏函数 配合#、##一起使用函数宏可以节省大量的工作量,例如:获取环境变量的一系列操作,可以通过宏函数生成实际的函数定义,如下: #define ENV_MAX_LEN (256) #define DEFINE_FUNC_ENV(ENV, default) \ const char *CFG_Get##ENV() \ { \ do { \ static char ENV##Var[ENV_MAX_LEN] = {'\0'}; \ char *value = getenv(#ENV); \ if (IS_NULL(value)) { \ ASSERTEX_NO_RET(IS_NOT_NULL(value), LOG_LEVEL_WARN, "env (%s) not set, use value(%s)", \ #ENV, default); \ return default; \ } \ errno_t retCode = strncpy_s(ENV##Var, ENV_MAX_LEN, value, strlen(value)); \ ASSERTEX((retCode == EOK), "

安装银河麒麟操作系统

文章目录 一、安装银河麒麟操作系统1.1、简介1.2、银河麒麟高级服务器操作系统V101.3、下载银河麒麟镜像1.4、安装银河麒麟操作系统兼容版 一、安装银河麒麟操作系统 1.1、简介 银河麒麟(KylinOS)原是在863计划和国家核高基科技重大专项支持下,国防科技大学研发的操作系统,后由国防科技大学将品牌授权给天津麒麟 ,后者在2019年与中标软件合并为麒麟软件有限公司 ,继续研制的以Linux为内核的操作系统 。银河麒麟已经发展为银河麒麟服务器操作系统、桌面操作系统、嵌入式操作系统、麒麟云、操作系统增值产品为代表的产品线。 为攻克中国软件核心技术卡脖子的短板,银河麒麟建设自主的开源供应链, 发起中国首个开源桌面操作系统根社区openKylin, 银河麒麟操作系统以openKylin等自主根社区为依托,发布最新版本。 中文名银河麒麟类型Linux内核的操作系统外文名KylinOS最新版本V10 1.2、银河麒麟高级服务器操作系统V10 ​ 银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化、云计算、大数据、工业互联网时代对主机系统可靠性、安全性、性能、扩展性和实时性等需求,依据CMMI5级标准研制的提供内生本质安全、云原生支持、自主平台深入优化、 高性能、易管理的新一代自主服务器操作系统,同源支持飞腾、鲲鹏、龙芯、申威、海光、兆芯等自主平台;应用于政府、金融、教育、财税、公安、审计、交通、医疗、制造等领域。基于银河麒麟高级服务器操作系统,用户可构建数据中心、高可用集群和负载均衡集群、虚拟化应用服务、分布式文件系统等,并实现对虚拟数据中心的跨物理系统、虚拟机集群进行统一的监控和管理。银河麒麟高级服务器操作系统支持云原生应用,满足企业当前数据中心及下一代的虚拟化(含Docker容器)、大数据、云服务的需求。 1.3、下载银河麒麟镜像 麒麟软件官网 点击银河高级服务器操作系统V10 点击申请试用 输入对应的信息 选择银河麒麟高级服务器操作系统V10-兼容版 1.4、安装银河麒麟操作系统兼容版 点击创建新的虚拟机 选择自定义 选择稍后安装操作系统 选择语言–> 中文 点击-时间和日期 点击软件选择 点击安装目的地-也就是分配磁盘空间 点击网络和主机名

逆向工程思路

一、说明 对于逆向工程和大多数人一样接触始于看雪的《加密与解密》,但在相当长一段时间内对于逆向的认知都只停留在PE格式、OD下断点动态调试、IDA各种窗口静态调试这几个名词上。看了一遍又一遍的书和视频,看的时候觉得很有道理,过了之后则完全没懂到底说了些什么。到后来老师引入CTF,其他人津津有味地做了出来,而自己手足无措看网上的答案这么操作一下那么操作一下结果就出来了完全不懂在做什么为什么要这么做,由此陷入了深深的惶恐。 因为在个人看来凡事都是要有依据懂原理才能进行的,但自己成绩不落后别人动手编程能力不落后别人,完全不明白CTF这种自己感觉没头没脑的东西为什么别人却可以做得出来,世界观几要崩溃。时至今日也只能说按照自己的思路确实可以进行逆向,而至于别人为什么感觉没有章法也能逆向则还是没有想清楚。 二、逆向工程思路 在说明中提到“在相当长一段时间内对于逆向的认知都只停留在PE格式、OD下断点动态调试、IDA各种窗口静态调试这几个名词上”,这其中的问题是大多数教程都讲清楚了怎么做,而没向初学者解答一个问题,什么时候这么做。或者换一种说法就是,当我们进行逆向前我们要想清楚一个问题:当我们逆向的时候,我们到底是在做什么。 所谓逆向,其实我们就是在做以下三件事情: 第一步,借助PE格式解析可执行文件。一是指olldbg和ida按PE格式解析出可执行文件的各组成部份包括数据段代码段指令字符串等等;二是指我们自己要能把od和ida解析出来的数据段代码段指令字符串与PE格式对应上,对应上的意思首先是说我们要知道各窗口的东相都在PE文件的什么位置,然后是说我们要知道我们自己想要在的东西应该到哪个窗口去找。 第二步,通过各种手段逼近目标代码。目标代码,比如要去除nag窗口的目标代码弹窗代码,要去除次数限制的目标代码就要计数代码。逼近就是锁定目标代码的起始地址和/或结束地址。逼近手段,OD的逼近手段是各种窗口+断点,IDA的逼近手段是各种窗口+交叉引用。 第三步,是分析目标代码逻辑。就是指或是从锁定的起始地址向结束地址一条条指令地追踪,或是从结束地址往起始地址一条条指令地分析确定目标代码的逻辑,及决定跳过的对策。 在这三步中很多教程让人感觉逆向就是在操作od/ida,但其实od/ida复杂度顶多和burpsuite/wireshark一个级别也没有很多操作,工具操作背后的PE格式理解、汇编掌握才是逆向的真正关建点。下文三四五大点依次对应以上三步。 三、可执行文件格式 3.1 本文使用的示例程序 首先介绍本文使用的示例程序,这是密码学中用C++写的一个SHA1加密工具,操作过程就是使用小组组员姓名登录,认证通过和即可进入程序加密操作主界面。如下所示: 3.2、可执行文件格式的定义及作用 可执行文件----windows平台就是exe、dll等文件,linux平台就是各种命令和so文件,android平台就是dex文件。是磁盘状态的文件而不是加载到内存后的内存中的文件。 可执行文件格式----就是可执行文件的组织格式。对操作系统而言可执行文件格式指示系统如何正确解析、加载和运行可执行文件;对逆向工具而言可执行文件格式指导逆向工具解析出可执行文件的代码段数据段指令和字符串等各组成部份;对人而言,我们自己也得要掌握可执行文件格式能将逆向工具只是解析出的各部分与可执行文件格式对应上理解各成分的含义作用,不然只是工具解析出来几个窗口在那里并没有什么用,另外加壳脱壳等防护也需要我们掌握可执行文件格式从可执行文件格式入手 windows平台就是PE格式、linux平台就是ELF格式、安卓的dex也有其格式。其实扩展开去不只可执行文件,所有的文件都需要有格式都需要或多或少的一些头部指示其解析器如何对其进行解析,诸如视频、图片、pdf等等。数据包也需要以太头、ip头、tcp头等格式。 网络安全学习资源分享: 零基础入门 对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。 CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com) 同时每个成长路线对应的板块都有配套的视频提供: CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com) 因篇幅有限,仅展示部分资料,需要点击上方链接即可获取

xHE-AAC 简介

参考官方介绍,并整理一些技术特征,方便后面再查阅。 xHE-AAC (fraunhofer.de)https://www.iis.fraunhofer.de/zh/ff/amm/broadcast-streaming/xheaac.html 1.What is xHE-AAC ? xHE-AAC(Extended HE-AAC)是最新一代的MPEG AAC编解码器,由Fraunhofer IIS主导研发,它改变了语音和音乐内容必须采用不同编码格式的现状。xHE-AAC宽广的传输码率范围能够为所有信号类型(如语音、音乐和混合内容)带来始终如一的高水平音质——单声道低至6 kbit/s,立体声服务低至12 kbit/s,最高达到500 kbit/s及以上。这也使得它成为了数字广播和自适应流媒体应用的首选编解码器。目前,xHE-AAC已原生支持于数字调幅广播(DRM)和谷歌Android Pie操作系统; xHE-AAC是最新一代的AAC编解码器适用于任何类型的内容: 视频服务音乐有声读物播客 立体声传输码率范围:12 kbit/s 至500 kbit/s或更高可通过MPEG-DASH 或HLS进行自适应流媒体传输在网络环境恶劣或转好时都能无缝切换传输码率MPEG-D DRC提供强制性响度和动态范围控制功能,从而使音量始终保持一致原生支持于最新版本的苹果、安卓、亚马逊, 微软操作系统及设备xHE-AAC编码器具有适用于直播内容(例如音乐会、体育赛事或新闻等)的实时自动响度功能授权予苹果、微软和奈飞专利费用已包含在AAC专利授权许可之内,无额外支出成本 2.新特性 自适应流媒体传输 xHE-AAC专为自适应流媒体传输而设计:其宽广的码率范围使得MPEG-DASH或 HLS流媒体应用和流媒体播放器能够在网络条件不佳时切换至极低码率流,从而实现连续不间断的还放效果。当网络条件恢复后,xHE-AAC播放器能够无缝切换至更高的比特率,最高可达到透明音质。此外,凭借xHE-AAC卓越的编码效率所节省出的码率能够进一步提升视频部分的质量。 响度和动态范围控制 MPEG-D DRC(响度和动态范围控制)为xHE-AAC提供了强制性响度控制和动态范围控制处理,在保证内容还放时音量一致的同时,确保在任何平台和任何环境下都能给用户带来最佳音频体验 兼容性 xHE-AAC解码器能够兼容之前所有的版本的AAC编码器,包括AAC-LC、HE-AAC和HE-AACv2。它的码率范围涵盖了旧有数据流,令用户能够轻松将其集成到现有编码流程之中。 3.应用 xHE-AAC的技术特性能够满足数字广播、移动音视频流媒体应用的需求,并支持各种音频内容在极低码率下进行传输。 支持流媒体应用 xHE-AAC能够为全球数十亿网络用户带来服务:在新兴市场,2G/3G网络仍然大量存在,而在大城市中严重拥挤的4G/5G网络已经成为普遍现实。消费者在节省数据流量的同时还获得了更优质的聆听体验,与此同时,流媒体服务提供商受益于大幅降低的CDN成本和简化的编码资产管理。 用于直播流媒体的xHE-AAC xHE-AAC直播编码时可用到实时自动响度功能。它为现场信号提供全自动、无需人工操作的响度控制,同时还保留了信号的大部分动态范围和瞬态响度。直播内容与其他xHE-AAC内容保持一致的响度。xHE-AAC编码器已完全集成该功能,无需用户再进行额外适配。 为DRM量身打造 2013年,数字调幅广播(DRM)成为了首个将xHE-AAC列为指定音频编解码器并受益于其技术特性的数字广播标准。为了确保系统的兼容性, HE-AAC在现行DRM标准中仍可继续使用。DRM广播运营商借助xHE-AAC可以对所有类型的内容使用同一编解码器,这将大幅简化编解码器配置流程:编码器可以自动优化所有质量相关的参数,无需手动更改不同类型音频内容的编码器配置。此外,随着码率的降低,传输多个音频节目成为可能。 4.已经支持的平台 以下平台支持了面向DRM和流媒体应用的xHE-AAC编解码器: PC (Windows/Mac OS X/Linux)ARM(仅限于解码器)MIPS(仅限于解码器)Texas Instruments C6x, DaVinci, OMAP 仅限于解码器)ADI Sharc+ (仅限于解码器)Cadence Xtensa (仅限于解码器)Apple iOS® SDK(仅限于解码器)Apple iOS 13 (仅限于解码器)Fire OS 7 (仅限于解码器)Android™(解码器已包含在Android 10及更高版本中) 基于Fraunhofer ContentServer技术和第三方应用的DRM广播编解码器解决方案均支持xHE-AAC技术。市面上所有的DRM接收芯片均支持xHE-AAC技术。 5.专利许可 xHE-AAC是Via Licensing Alliance 管理的AAC专利池授权计划的一部分。欲了解更多信息,请访问Via LA Licensing或联系contracts@via-la.

执行时长2分钟的SQL,AI帮我优化到10毫秒。AI优化神器,你值得拥有

目录 前言 sql优化平台演示 复杂的子查询 复杂的聚合查询 复杂的联合查询 复杂的分组查询 复杂的嵌套查询 复杂的条件逻辑查询 SQL优化原理 原理流程 模型训练 优化预测 特征提取 数据收集 代码片段 大侠的AI网站 AI大侠后续功能计划 共建计划 写到最后 大家好,我是大侠,AI领域的专业博主 前言 AI大侠更新啦,耗时两个月终于上线SQL智能优化工具!!! 许多小伙伴在工作中写SQL 的时候最常遇到的问题就是SQL优化问题,特别是在面对数以千万计的数据,如何提高性能和简化复杂的SQL查询,更是需要耗费大量的时间和精力。 现在大侠给大家开发了一个SQL优化平台(https://aidaxia.net) 话不多说,直接开车~ sql优化平台演示 复杂的子查询 需求:检索所有部门名称类似于"Sales"的员工。 SELECT * FROM employee WHERE department_id IN ( SELECT id FROM department WHERE name LIKE '%Sales%' ); AI优化结果 AI模型使用INNER JOIN而非子查询,以避免使用子查询的性能问题。 复杂的聚合查询 需求:从表中检索每个部门的平均工资和员工数,并仅返回平均工资大于50000且员工数大于5的部门。 SELECT department_id, AVG(salary) AS avg_salary, COUNT(*) AS employee_count FROM employee GROUP BY department_id HAVING AVG(salary) > 50000 AND COUNT(*) > 5 ORDER BY department_id; AI优化后

Ubuntu Gnome美化

著名的Gnome美化插件网站: https://www.gnome-look.org/browse/cat/ 可以下载Cursors鼠标图标、Docks任务栏、GTK2/3/4 Themes主题、Wallpapers壁纸等等 1. 安装主题 推荐WhiteSur Gtk Theme模拟MacOS,进网站下载: https://www.gnome-look.org/p/1403328/ 选择WhiteSur-light-Gnome-3-28,下载压缩包并解压,将文件夹复制到文件夹/usr/share/themes/内部,该文件夹专用于存储主题文件: sudo cp ./WhiteSur-light/ /usr/share/themes/ -rf 2. 安装图标 推荐WhiteSur icon Theme模拟MacOS,进网站下载: https://www.gnome-look.org/p/1405756/ 选择01-WhiteSur.tar.xz,下载压缩包并解压,将文件夹复制到文件夹/usr/share/icons/内部,该文件夹专用于存储图标文件: sudo cp ./WhiteSur /usr/share/icons/ -rf 3. 下载壁纸 这里有MacOS的壁纸分享: https://www.pling.com/p/1398833/ 4. 开始美化: 安装工具tweak,用于美化操作: sudo apt-get install ​gnome-tweak-tool 4.1 更换主题和壁纸 进入Appearance,选取如下: applications WhiteSur-light和icons WhiteSur就是刚才安装的主题和图标,自带的Whiteglass的鼠标效果也还行。 4.2 更换壁纸 右键壁纸图片文件,选择Set as Wallpaper即可。 5. 最终效果 习惯了windows的任务栏,就没有专门修改左侧的Dock。

mmdetection修改backbone使用mmcls和timm已有模型

官方文档Tutorial 11: How to xxx — MMDetection 2.24.1 documentation对更换backbone已经有了比较详细的介绍,特别是较新的版本已经支持mmcls库以及timm库中的现有分类网络,一般直接拿来修改使用即可,但这里最重要的一点就是需要保证修改后的backbone要和后面的neck结构进行进行匹配,主要是通道数方面。目标检测模型的通用结构如下图所示,如果更改backbone后导致于neck的结构不适配,将导致模型失效报错。下面以mmdetection中的yolox模型为例子对官方文档更换backbone的方法进行补充说明,最后再举例yolov3模型替换swin transformer的例子。 1.Mmcls 骨干模型替换 使用命令pip install mmcls安装mmcls,之后导入mmcls.models可以查看支持的backbone,如下图所示。可以看出mmcls库基本囊括了主流、经典的模型,这也是openmmlab打造一体化生态的体现。 以ShuffleNetV2这一轻量化模型为例,将此模型替换yolox原本的cspdarknet骨干网络。首先查看一下mmcls.models.ShuffleNetV2的模型接口: 需要注意的是out_indices这一参数,默认为选取第四个stage的卷积输出,而在yolox是原有设计中输入了3个stage的特征图: #============== CSPDarknet ============== backbone=dict(type='CSPDarknet', deepen_factor=0.33, widen_factor=0.5), neck=dict( type='YOLOXPAFPN', in_channels=[128, 256, 512], out_channels=128, num_csp_blocks=1), #============== end ================= 根据这种思路,我们也可以输出特定的几个stage特征图,例如out_indices选择(1,2,3),下一步便需要确定这几个stage的输出通道,以此和neck的in_channels参数匹配,可以利用下列代码查看ShuffleNetV2模型的输出通道数: from mmcls.models import ShuffleNetV1, ShuffleNetV2, MobileNetV2, MobileNetV3 import torch # m = MobileNetV3(out_indices=(3, 8, 11)) m = ShuffleNetV2(out_indices=(0,1,2,3)) # m.eval() inputs = torch.rand(1, 3, 640, 640) level_outputs = m(inputs) for level_out in level_outputs: print(tuple(level_out.shape)) (1, 116, 80, 80) (1, 232, 40, 40) (1, 464, 20, 20) (1, 1024, 20, 20) 从以上结果可以看出indices(1,2,3)对应的输出通道数为(232,464,1024),

M.2 SSD接口详解

一、M.2简介 M.2接口是一种新的主机接口方案,可以兼容多种通信协议,如sata、PCIe、USB、HSIC、UART、SMBus等。 M.2接口是为超极本(Ultrabook)量身定做的新一代接口标准,以取代原来的mSATA接口。无论是更小巧的规格尺寸,还是更高的传输性能,M.2都远胜于mSATA。 M.2接口,是Intel推出的一种替代MSATA新的接口规范。其实,对于桌面台式机用户来讲,SATA接口已经足以满足大部分用户的需求了,不过考虑到超极本用户的存储需求,Intel才急切的推出了这种新的接口标准。 常见的M.2接口为Key A、Key B、Key E和Key M. 不同的key类型表示此m2接口支持的信号,见下表。Key B、Key M多用于硬盘,Key A、Key E多用于无线网卡,当然也有各种转接模块。 二、M.2分类 1.按照尺寸大小分类 目前M.2 SSD常见的Type有三种,就是2230、2242、2280; Type 2230则表示其宽度22nm,长度30nm; Type 2242则表示其宽度22mm,长度42mm; Type 2280则表示其宽度22nm,长度80nm。 2.按照接口类型分类 m.2接口分为Socket 2(B key——ngff)和Socket 3(M key——nvme) Socket 2也可以叫做B key,支持支持SATA、PCI-E X2接口,而如果采用PCI-E ×2接口标准,最大的读取速度可以达到700MB/s,写入也能达到550MB/s; Socket 3也可以叫做M key,支持支持PCI-E ×4接口,理论带宽可达4GB/s。 B key 的防呆键位于插槽的左方,M key 则在右方。两种类型的插槽其短边接脚数量有所差异: 一开始,B key的只能插在b key(Socket 2)的接口中,m key的只能插在m key(Socket 3)的接口中,但是随着m key接口的普及,越来越多电脑主板只有m key 接口,b key的ssd根本插不上去,于是厂商们又设计了一个b&m key接口的ssd。 b&m key接口即可以插上b key也可以插上m key。b&m key支持的通道和b key支持的通道一样,都是sata pcie x2,但是b&m key可以兼容m key 和b key两种,而b key只能兼容b key一种,这就导致了b key毫无优势,b key被b&m key取代,现在市面上只有b&m key和m key两种m2 ssd卖, b key的m2 ssd 已经绝迹。

eICIC和FeICIC

1 当前的eICIC技术及其缺陷 1.1eICIC技术简介 针对长期演进(LTE)无线接入网(RAN),频域上的同 频多小区间干扰协调称之为小区间干扰协调(ICIC),时域上的同频多小区间干扰协调称之为增强的小区间干扰协调(eICIC)。当前的(3GPP R10版本)eICIC仅针对同频组网时的单一频点(无载波聚合,Non-CA)。 通过宏小区把一个或多个子帧配置为“几乎 空白的子帧(ABS)”,微小区(为简单起见,这里的微小区包括了微微小区Pico和家庭基站Femto,不再另外列出)在ABS子帧上为小区边缘终端 (UE)提供服务,从而避免了来自宏小区的主要干扰,提升了小区边缘UE的服务速率,如图1所示。 当宏小区与微小区之间存在LTE基站之间的X2接口时,ABS配置信息通过X2接口传输;当宏小区与微小区之间没有X2接口时,ABS配置信息通过操作维护台(OAM)人为地告知。 1.2ABS子帧内容 在ABS子帧上可以有小区公共信号和信道的发射(如主同步信号PSS、辅同步信号SSS、物理广播信道PBCH、物理控制格式指示信道PCFICH、物 理混合自动重传请求指示信道PHICH、发送系统信息广播SIB时的物理下行控制信道PDCCH及对应的物理下行共享信道PDSCH、发送寻呼消息时的 PDCCH/PDSCH),但ABS子帧上不能发射UE专用的PDCCH(包括上行调度和下行调度分别使用的PDCCH)以及下行调度用的PDCCH所对 应的PDSCH。 此外,用于发射多媒体广播与多播业务(MBMS)和定位用参考信号(PRS)信息的子帧不能配置为ABS子帧。即,如果 ABS子帧刚好碰上了MBMS的单频网MBSFN子帧,则ABS无效,MBSFN子帧有效;如果ABS子帧刚好碰上了PRS子帧,则ABS无效,PRS子 帧有效。 由于PHICH是必须发射的,因此,ABS子帧上可以有PHICH。 由于上行调度的下行控制信息格式0、格式4(即DCI 0、DCI 4)和下行UE专用调度的DCI不是必须发射的,因此,ABS子帧上没有这些DCI,也没有对应的PDSCH和物理上行共享信道PUSCH。 1.3eICIC主要缺陷 ABS子帧是针对下行方向(从基站到终端)的概念。对于频分双工FDD-LTE系统,假定ABS子帧的子帧号为N,那么,(N+4)时刻就是上行方向 (从终端到基站)的ABS子帧。对于时分双工TDD-LTE系统,上行方向可能会没有ABS子帧(例如两个下行子帧D对应到同一个上行子帧U,或一个D加 一个特殊子帧S对应到同一个上行子帧U),或者存在多个上行方向的ABS子帧(例如一个D或一个S对应到多个上行子帧U)。 在实现上,的确 可以把PDCCH/PDSCH/PUSCH的发射功率降得很低,使得它对微小区没有干扰(或干扰很小),但这不是3GPP R10版本eICIC的本意。eICIC的本意是在时间上把干扰错开,3GPP R11版本(该版本将在2012年12月发布)则可降低功率来发射。 从上面的分析可以看出,当前eICIC的主要缺陷是:宏站在ABS子帧上不能调度UE,小区公共信道可能会受到干扰,ABS子帧上PDCCH之间的干扰难于协调等。 2 eICIC的未来发展 在未来,eICIC主要在宏站充分利用ABS子帧、公共信道的干扰规避和ABS子帧上PDCCH的小区间协调等方面进一步发展。 2.1宏站充分利用ABS子帧 在未来的3GPP R11版本中,宏站可以发射UE专用的PDCCH或PDSCH,而这在3GPP R10版本下是不可以的[1]。但前提条件是,宏站得在ABS子帧上降低发射功率以减少对微站的干扰,并且得把在ABS子帧上的发射功率大小相关信令告诉 微站。这一点是3GPP R11版本的eICIC(称为FeICIC)跟3GPP R10版本的eICIC的根本区别所在。 在FeICIC下,宏站可以在ABS子帧上调度UE专用的PDCCH或PDSCH;因此,一般来说,在这种情况下,宏站能够以很低的发射功率来调度其信道 条件好的UE,以避免对微站产生干扰。此时,PDCCH/PDSCH/PUSCH等信道都能够以很小的功率来发射,但又要使得这些信道能被可靠地解码。 在FeICIC下,宏站可以在ABS子帧上调度UE;因此,相对于eICIC,FeICIC能更为有效地跟CoMP(协调的多点发射和接收)结合起来使 用,如图2所示。图中,UE2处于微站的小区边缘,宏站帮助微站来为UE2服务。其中,资源块组RBG0和RBG1是微站预留给微站边缘UE使用的。 由于在FeICIC下,宏站需要在ABS子帧上降低发射功率;因此,一般来说,微站不能在ABS子帧为宏站的边缘UE提供服务。 2.2公共信道的干扰规避 在未来的FeICIC中,宏站可以帮助微站来给小区发射公共信道(PCCH/BCCH/CCCH)[2]。例如,在图2中,假定微站在ABS子帧上发送寻呼信息(PCCH)给UE2,那么宏站可以对微站的UE2提供CoMP服务。 相似地,在ABS子帧上,微站也可以帮助宏站来给小区发射公共信道(PCCH/BCCH/CCCH)。 2.3ABS子帧上PDCCH的小区间协调 在未来的FeICIC下,还可能引进增强的物理下行控制信道(ePDCCH)来进一步减少小区间的控制信道干扰[3-5]。PDCCH的正确解调是数据信道(PDSCH/PUSCH)得以正确解调的先决条件,因此,需要有一定的方法来减少小区之间的PDCCH干扰。 相关资料[3-5]显示,ePDCCH可能会使用类似于中继物理下行控制信道(R-PDCCH)[6]的结构,可能会用不兼容3GPP R8的载波类型,还可能有波束赋形(BF)和多层发射(MIMO)。 R-PDCCH的资源分配类型与3GPP R8的PDSCH的资源分配类型相同,包括Type 0(按RBG分配)、Type 1(按RB分配)、Type 2 LVRB(即PRB)和Type 2 DVRB。在每一种类型里面,R-PDCCH既可以是非交织类型的,也可以是交叉交织类型的。20MHz、Type 0(只分配了RBG 0)、非交织的R-PDCCH组成及分配如图3所示。 从图3可以看出,如果ePDCCH使用R-PDCCH的结构,那么小区之间的 PDCCH协调就变得容易多了。图2给出了两个小区之间如何进行协作,给边缘的UE2联合发射ePDCCH的例子;在图3中,RBG0和RBG1预留给边 缘用户使用,本区和邻区可对其承载的ePDCCH进行联合发射、波束赋形、资源预留和动态小区选择等。 在这种情况下,也可使用ePDCCH来调度公共信道(如SIB的发射),使得公共信道上的数据更为可靠,也可减少小区之间的干扰(包括控制信道和数据信道)。 3 结束语 本文给出了当前的eICIC技术工作原理,分析了其可能存在的缺陷,指出了未来可能的发展方向。总的来说,未来的FeICIC将比现在的ICIC更为高效和可靠。 

电子科技大学-操作系统实验课-遇到的问题以及查找的知识总结

文章目录 linux与windows的操作系统内核都是宏内核内核编程特点:编写的内核模块必须有下面两种函数`printk`的使用内核模块的两种形态内核的两种声明需要包含的头文件一个内核模块的简单示例Makefile文件简介Makefile文件干啥的`obj-m`与`obj-y``ifeq`and`ifneq`and`ifdef`and`ifndef`KERNELRELEASE`make -C $(KDIR) M=$(PWD)`Makefile中的`$@`、`$^`、`$<`、`$?`、 %、` +`、`$*` C语言编写问题[Error] ‘for‘ loop initial declarations are only allowed in C99 or C11 mode 解决方法initializer element is not constant 问题kmalloc函数使用kfree函数的使用 一些其他问题printk打印不出来的解决方法insmod第一次killed,第二次直接卡死的原因 系统调用内核下载`linux 5.15.0`等一系列内核的系统调用需要修改的目录为编写系统调用遇到的一些问题 linux内核模块调用其他模块导出的函数遇到的一些问题 linux字符设备驱动程序编写方式`mknod`命令用于创建字符设备文件和块设备文件Linux中/proc目录下文件详解/proc/cmdline/proc/cpuinfo/proc/devices/proc/filesystems/proc/meminfo 遇到的一些问题步骤 linux与windows的操作系统内核都是宏内核 内核编程特点: 不能使用C库函数,如外部头文件,printf,可以使用如printk函数可以使用汇编语言,GNU C和GCC编译器不能使用FPU可能会产生内存故障 编写的内核模块必须有下面两种函数 static int hello_int(void){...} // static int __init hello_init(void) module_init(hello_init); 通过module_init(...);来指定程序开始运行的函数 static void hello_exit(void){...} // static void __exit hello_exit(void) module_exit(hello_exit); 通过module_exit(...);来指定程序终结时运行的函数,一般在这个exit函数,会释放申请的各种系统资源,最后退出,整个模块从内核中卸载 printk的使用 … 内核模块的两种形态 静态编译进内核的模块 用insmod命令动态加载的模块 用rmmod来卸载模块 sudo insmod hello.ko var=XXX sudo rmmod hello.

GNU/POSIX

1.GNU GNU该系统的基本组成包括GNU编译器套装(GCC)、GNU的C库(glibc)、以及GNU核心工具组(coreutils)[14],另外也是GNU调试器(GDB)、GNU二进制实用程序(binutils)[15]的GNU Cash shell中[10] 和GNOME桌面环境。 参考GNU - 维基百科,自由的百科全书 (wikipedia.org)https://zh.wikipedia.org/wiki/GNU 2.POSIX POSIX:可移植操作系統接口(Portable Operating System Interface of UNIX,縮寫爲 POSIX),参考下面链接。 posix 是什麼都不知道,就別說你懂 Linux 了! - 閱坊 (readfog.com)https://www.readfog.com/a/1645003345925083136 POSIX 是一个标准,并不是软件库。 3.GNU 和 POSIX关系 GNU 库提供的API 遵从POSIX 标准。 glibc 是 Linux 下使用的開源的標準 C 庫,它是 GNU 發佈的 libc 庫,即運行時庫。這些基本函數都是被標準化了的,而且這些函數通常都是用匯編直接實現的。 glibc 爲程序員提供豐富的 API(Application Programming Interface),這些 API 都是遵循 POSIX 標準的,API 的函數名,返回值,參數類型等都必須按照 POSIX 標準來定義。 POSIX 兼容也就指定這些接口函數兼容,但是並不管 API 具體如何實現。 4.系统开销 有些库函数需要最终调用系统调用,比如fread/fwrite 等,有些库函数不用系统调用,比如strlen 等。 系统调用,需要在用户态和内核态之间进行切换,因此,系统调用的系统开销更大,单纯的库函数调用,系统开销较小。 5.trace 调用过程 在执行可执行程序时,带上strace 可以列出调用过程,比如 //source code #include <stdio.

【单片机】基于STM32的UART串口通信

基于STM32的UART串口通信 一、前言二、UART相关知识1、UART简介2、UART通信协议3、UART功能说明(1)正常 USART 模式下,通过这些引脚以帧的形式发送和接收串行数据:(2)在同步模式下连接时需要以下引脚: 4、UART工作原理(1)发送接收(2)波特率产生(3)数据收发(4)中断控制(5)FIFO操作(6)回环操作 三、STM32CubeMx配置四、UART发送1、初始化说明2、HAL库函数说明3、代码实现UART发送(1)直接发送(2)字符串发送 五、UART接收1、初始化说明2、函数说明(1)CubeMx生成的UART中断处理函数(在stm32f1xx_it.c中)(2)HAL库函数HAL_UART_Transmit(在stm32f4xx_hal_uart.c中)(3)HAL库函数HAL_UART_Receive(在stm32f4xx_hal_uart.c中) 3、代码编写:实现UART接收(1)直接接收(不建议)(2)中断接收(接收并发送)(不推荐)(3)中断接收(先接收完,后处理)(推荐) 一、前言 简单讲解一下UART通信协议,以及UART能够实现的一些功能,还有有关使用STM32CubeMX来配置芯片的一些操作。实验内容基于正点原子精英板开发板,单片机芯片为STM32F103ZET6。 在后面我会以我使用的STM32F429开发板来举例讲解(其他STM32系列芯片大多数都可以按照这些步骤来操作的),如有不足请多多指教。 二、UART相关知识 1、UART简介 嵌入式开发中,UART串口通信协议是我们常用的通信协议(UART、I2C、SPI等)之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输,它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外部设备进行全双工数据交换。 类似的,USART(Universal Synchronous Asynchronous Receiver and Transmitter通用同步异步收发器)串口的,USART相当于UART的升级版,USART支持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。因为USART的使用方法上跟UART基本相同,所以在此就以UART来讲该通信协议了。 2、UART通信协议 起始位 当未有数据发送时,数据线处于逻辑“1”状态;先发出一个逻辑“0”信号,表示开始传输字符。数据位 紧接着起始位之后。资料位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟定位。奇偶校验位 资料为加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。停止位 它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。空闲位或起始位 处于逻辑“1”状态,表示当前线路上没有资料传送,进入空闲状态。 处于逻辑“0”状态,表示开始传送下一数据段。波特率 表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。 常用的波特率有:9600、115200…… 时间间隔计算:1秒除以波特率得出的时间,例如,波特率为9600的时间间隔为1s / 9600(波特率) = 104us。 3、UART功能说明 接口通过三个引脚从外部连接到其它设备。任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX): RX:接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。 TX:发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O 用于发送和接收数据(USART 电平下,随后在 SW_RX 上接收数据)。 (1)正常 USART 模式下,通过这些引脚以帧的形式发送和接收串行数据: 发送或接收前保持空闲线路起始位数据(字长 8 位或 9 位),最低有效位在前用于指示帧传输已完成的 0.5 个、1 个、1.

STM32开发——简介、开发环境(Keil5、CubeMX)、HAL库

目录 1.简介-初识STM32 2.开发环境 2.1使用Keil5 2.2使用STM32CubeMX 3.标准库与HAL库区别 4.推挽输出与开漏输出 1.简介-初识STM32 什么是单片机? 单片机(Single-Chip Microcomputer)是一种集成电路芯片,把具有数据处理能力的中央处 理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功 能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成 到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。 STM系列单片机命名规则 ST -- 意法半导体M -- Microelectronics 微电子32 -- 总线宽度 项目 介绍内核 Cortex-M3Flash64K x 8bitSRAM 20K x 8bitGPIO 37个GPIO,分别为PA0-PA15、PBO-PB15、PC13-PC15、PDO-PD1ADC2个12bit ADC合计12路通道,外部通道: PAO到PA7+PBO到PB1内部通道: 温度传感器通道ADC Channel 16和内部参考电压通道ADC Channel 17定时器/计数器4个16bit定时器/计数器,分别为TIM1、TIM2、TIM3、TIM4TM1带死区插入,常用于产生PWM控制电机看门狗定时器2个看门狗定时器 (独立看门狗IWDG、窗口看门狗WWDG)滴答定时器1个24bit向下计数的滴答定时器systick工作电压、温度2V —3.6V、-40°—C85°C通信串口2 * IIC,2 * SPI,3 * USART,1 * CAN系统时钟内部8MHz时钟HSI最高可倍频到64MHZ,外部8MHZ时钟HSE最高可倍频到72MHZ 2.开发环境 2.1使用Keil5 1.安装MDK 地址选择 2.破戒 3.安装芯片对应的固件包——F1固件包 双击固件包直接安装即可 4.创建STM32F1模板工程 在魔术棒中的C/C++需要添加文件头文件路径 5.接线 烧录工具有很多种,比如:串口、J-Link、ST-Link、U-Link 等等,本教程使用 ST-Link。 安装驱动 官网下载(慢)https://www.st.com/en/development-tools/stsw-link009.html资料包 接线 6.编译及下载 后两个编译生成hex文件 LOAD就是下载程序到开发板 需要程序运行,需要按一下开发班的复位按钮。

Android-Fragment详解

Fragment是Android最常使用的控件之一。一般情况下,我们会在首页使用到,有的小伙伴也会单Activity和多Fragment的App。我总结了一下我了解的Fragment知识,希望对看这篇文章的小伙伴有所帮助。 Fragment的概念 Fragment是Android3.0新增的概念,中文意思是“碎片”,它与Activity非常相似,用一个Activity中描述一些行为或者一部分用户界面,使用多个Fragment可以在一个单独的Activity中建立多个UI面板,也可以在多个Activity中使用Fragment。 Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视。针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应其他尺寸的。难道无法做到一个App可以同时适应手机和平板么,当然了,必须有啊。 Fragment的出现就是为了解决这样的问题。你可以把Fragment当成Activity的一个界面的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成,更帅气的是Fragment拥有自己的生命周期和接收、处理用户的事件,这样就不必在Activity写一堆控件的事件处理的代码了。更为重要的是,你可以动态的添加、替换和移除某个Fragment。 Fragment的创建 一个Fragment必须总是被嵌入到一个Activity中,它的生命周期直接被其所属的宿主Activity生命周期影响,它的状态会随宿主的状态变化而变化。 要创建一个Fragment 必须创建一个Fragment的子类,或者继承自另一个已经存在的Fragment的子类.并重写onCreateView()方法加载UI。 Fragment生命周期 Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。下面这张图很好的说明了两者生命周期的关系: 图片来源于网络,Fragment生命周期 在图中我们会发现Fragment比Activity多5个生命周期回到方法: onAttach(Activity); // 当Activity与Fragment发生关联时调用 onCreateView(LayoutInflater,ViewGroup,Bundle); // 创建该Fragment的视图 onActivityCreate(bundle); // 当Activity的onCreate();方法返回时调用 onDestoryView(); // 与onCreateView相对应,当改Fragment被移除时调用 onDetach(); // 与onAttach()相对应,当Fragment与Activity的关联被取消时调用 注意:除了onCreateView,其他所有的方法如果你重写了,必须调用父类对于该方法的实现。 Fragment常用的API Fragment常用的三个类 android.app.Fragment 主要用于定义Fragment;android.app.FragmentManager 主要用于在Activity中操作Fragment;android.app.FragmentTransaction 保证一些列Fragment操作的原子性。 获取FragmentManager的方式 getFragmentManager()方法v4中FragmentActivity的getSupportFragmentManager()方法在Fragment中·getChildFragmentManager()`方法 主要操作的都是FragmentTransaction的方法 开启一个事务:FragmentTransaction transaction = fm.benginTransaction();往Activity中添加一个Fragment:transaction.add();从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁:transaction.remove();使用另外一个Fragment替代当前的,实际上就是remove()然后add()的结合体:transaction.replace();当你的Fragment数量固定很少时隐藏当前的Fragment,仅仅是设为不可见的,并不会销毁。多的时候,可能会出现OOM异常:transaction.hide();显示之前隐藏的Fragment:transaction.show();会将view从UI中移除,和remove()不同,此时的Fragmengt的状态依然由FragmentManager维护:detach();创建View视图,附加到UI上并显示:attach();提交一个事务:transaction.commit(); Activity中添加Fragment 方法一(Activity的布局文件中加入标签) 在XML中配置更加简单一点,但是灵活性不够,不能在同一个位置去切换多个不同的Fragment <fragement android:id="@+id/myfragment" android:name="包名.Fragment类名" android:layout_width="match_parent" android:layout_height="match_parent"/> 注意:fragment必须设置id或者tag,并且要指定name类名 方法二(使用FragmentTransaction的add()方法加入fragment) 1.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。 FragmentManager fragmentManager = getFragmentManager(); 2.开启一个事务,通过调用beginTransaction方法开启。 FragmentTransaction fragmentTransaction =fragmentManager.beginTransaction(); 3.向容器内加入Fragment,一般使用add或者replace方法实现,需要传入容器的id和Fragment的实例。 fragmentTransaction.replace(Activity设置的布局中的ViewGroup组件id, 需要替换的Fragment实例); fragmentTransaction.replace(Activity设置的布局中的ViewGroup组件id, 需要替换的Fragment实例); // 也可以使用三参的方法,传递一个Tag 4.提交事务,调用commit方法提交。

Spring Boot 系列 - WebSocket 简单使用(建立一个网页聊天室)

在实现消息推送的项目中往往需要 WebSocket,以下简单讲解在 Spring boot 中使用 WebSocket。 1、pom.xml 中引入 spring-boot-starter-websocket <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> 2、往 spring 容器中注入 ServerEndpointExporter package com.example.mywebsocket.common.websocket; /** * 类功能说明 * * @author * @date 2023/6/1 16:56 */ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * WebSocket配置 * <p> * 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint * 要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。 * * @author sam * @since 2017/9/13 */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } 3、Endpoint 具体实现 package com.

一文学会如何在Mac上安装brew

相信有很多的小伙伴刚开始用Mac的时候会遇到安装brew的问题、今天小编整理下如何在Mac上安装brew、希望对大家有帮助 一、在终端执行brew --version,主要是为了查看brew的版本,也可以验证brew是否安装。 二、确认没有安装以后,执行以下代码 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 三、选择下载源,这里我选择的是2 四、之后点击Y即可开始安装 五、输入开机密码 六、Brew本体安装成功,选择以后安装的国内镜项,这里我依然选择2 七、重启终端之后按提示运行代码 八、安装git出现的问题也按提示输入一边代码即可 九、检查是否安装成功 查看brew --version 好了以上就是我自己安装brew的过程、希望对您有用、附上官网地址: brew官网

干货来了!端到端测试中的测试种类及工具的说明!

单元测试 即Unit Testing,简称 UT,是指对软件中的最小可测试单元进行检查和验证,这是最低级别的测试活动,前端开发中单元可以是一个function也可以是一个class,也可以是一个组件。 对他们的输出做断言检查,是一个白盒测试,一般由开发者进行编写,开发者可以通过编写执行 UT 来判断自己的逻辑是否正确。 集成测试 Integration Testing,其实集成测试就是根据业务功能需要把多个单元整合起来进行测试。 引用 React 官网上的说法:“单元测试”和“集成测试”之间的差别可能会很模糊。 如果你在测试一个表单,用例是否应该也测试表单里的按钮呢?一个按钮组件又需不需要有他自己的测试套件?重构按钮组件是否应该影响表单的测试用例?不同的团队或产品可能会得出不同的答案。 端到端测试 end-to-end,简称 e2e,也被称作功能测试(Functional Testing)或者浏览器测试或者冒烟测试,是指从使用者的角度出发,对真实系统进行测试。 e2e测试本质上是一种黑盒测试,相当于模拟用户访问应用程序,主要检查界面或功能是否正确,自动化测试不完善的时候通常是由人工来完成这项测试工作。 界面测试 User Interface Testing,简称 UI 测试,与 e2e 测试存在大量重叠,通常在做 e2e 的时候就能够覆盖 UI 测试。 TDD Test Drive Development即测试驱动开发。简单的说就是先根据需求写测试用例,再代码实现,接着测试,循环此过程直到产品的实现。 可以看出来,TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析、设计、质量控制量化的过程。 BDD Behavior Drive Development即行为驱动开发,BDD 可以看作是对 TDD 的一种补充,或者说是 TDD 的一个分支。 在 TDD 中,我们并不能完全保证根据设计所编写的测试就是用户所期望的功能。BDD 将这一部分简单和自然化,用自然语言来描述,让开发、测试、BA 以及客户都能在这个基础上达成一致。 BDD 更加依赖于需求行为和文档来驱动开发,这些文档的描述跟测试代码很相似。e2e 测试更多是和 BDD 的开发模式进行结合。 综上所述,后文主要会针对单元测试和端到端测试常用的工具进行使用说明和对比。 前端测试工具 前端测试工具有很多,可以分为几类: 断言库测试覆盖率工具测试框架 断言库 测试的时候我们需要使用断言来判断代码是否到达目的,如果没有断言,我们的测试也将失去意义。 01 assert assert 是 Node.JS 内置的断言库,下面是一个简单的例子: const assert = require('assert'); assert(1 === 2); const test = 'hello world'; assert.

简单的SSM项目(门店维修管理系统)

第一个ssm项目 结束spring,springMVC,mybatis的学习之后,将期末的java项目通过ssm框架进行复写,本章内容是基于ssm框架的门店维修管理系统,实现数据的增删改查。 目标:用ssm框架将原来的java项目进行复写,保证项目的正常运行,巩固学习 目标效果: 开发环境: idea:2023 jdk:1.8 mysql:8 tomcat:9 maven:3.9 数据库代码:(数据库的名称自建) CREATE TABLE tb_task( task_id INT PRIMARY KEY AUTO_INCREMENT, task_no VARCHAR(20) UNIQUE, task_item VARCHAR(20), cus_name VARCHAR(20), cus_phone VARCHAR(20), task_status INT ) CREATE TABLE tb_fit( fit_id INT PRIMARY KEY AUTO_INCREMENT, fit_no VARCHAR(20) COMMENT '编号', fit_name VARCHAR(20) COMMENT '名称', fit_qty INT COMMENT '数量', fit_city VARCHAR(20) COMMENT '产地' ) 基本环境搭建 项目结构: 项目搭建: 1.新建一个maven工程,然后添加以下依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.

在SpringBoo 2.6.15引入knife4j 4.1的依赖包后,项目启动时报错`Failed to start bean ‘documentationPluginsBootstrapper‘

问题描述 在SpringBoot引入knife4j的maven依赖包后,项目启动时报错Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null。 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency> 版本说明 SpringBoot 2.6.15knife4j 4.1.0 完整日志 org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) at java.base/java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:937) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:423) at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at org.

Ei国际学术会议投稿教程

会议介绍 Ei国际会议(International Conference on Innovation, ISI)是由美国国家科学基金会(NSF)资助,在国际上具有广泛影响的学术会议,代表着当前该领域的最新研究进展。目前已在全球120多个国家和地区召开了350余次,是科技论文被引用率最高的国际会议之一。ISI是国际著名出版集团斯德哥尔摩大学出版社(University of Stockholm, Stockholm)出版的国际学术期刊,主要栏目有: (1)基础研究。 (3)技术、产品和服务。 投稿类型 会议论文投稿类型有:论文集(以会议的方式发表),大会报告(以会议的方式发表),口头报告(以会议的方式发表),分会场报告(以会议的方式发表),主题论文(以会议的方式发表)等。对于准备参加 Ei国际学术会议的作者,首先需要参加 Ei国际学术会议并提交论文摘要。如果您已经在 Ei国际学术会议上提交过论文摘要,您可以在您所在大学或机构的网站上下载 Ei国际学术会议论文摘要,并按照以下格式进行准备: A. 用英文写一份标题。 按照要求排版。选择提交哪种类型的论文提交之后等待评审即可。 投稿 选择会议,点击“开始投稿”,进入投稿页面。选择会议类型,点击“编辑”,然后根据页面提示,输入会议信息、作者通讯地址、姓名等内容。填写论文题目、作者姓名、工作单位(中文和英文)、关键词等内容,如有相关的参考文献也要全部填写。论文篇幅以3000字符左右为宜,如有参考文献,应按实际情况填写。在“论文标题”栏中输入会议名称,“作者姓名”栏中输入姓名和工作单位(中文和英文),在“摘要”栏中输入关键词等。点击“提交”按钮,完成投稿。 提交 如果您是第一次投稿,请先在“我的投稿”中对您的论文进行注册,然后按提示的步骤完成投稿。如果您已经注册,但还未投稿,请先在“我的投稿”中对您的论文进行投稿,然后在“我的投稿”中选择“Ei Conference on New English Proposal”或“Ei Conference on New English Text”,并按提示完成投稿。请将论文发送到您的 Ei电子邮箱中(注意:仅支持 ISSN或 CN的电子邮件)。如有必要,可在“我的投稿”中增加附件(附件大小不超过1M)。在提交后,请在“我的论文”中查看论文是否已被接受。 录用 会议编辑部会在收到论文后的7个工作日内,以电子邮件的形式通知作者对论文的录用与否,作者可在邮件中提供相应信息,以便编辑部进一步处理。 录用通知通常是一封简短的邮件,包含论文的录用信息、作者姓名、会议名称、会议时间。作者应提供论文的完整信息,包括摘要、关键词、正文等。论文中如有插图,应在图表中列出其编号及图名。会议通知中注明了会议编辑部的电子信箱地址和联系人姓名以及通讯地址、电话号码等。会议通知中还提供了会议举办地点(或会议日程安排)以及主办单位联系方式等信息。 编辑审稿 通过点击【论文投稿】-【论文投稿系统】进入到投稿界面,并在左侧点击【选择期刊】在左侧选择好期刊之后,在右侧点击【开始投稿】如果你选择的是在线投稿,则会跳转到在线投稿界面,在此界面,您需要将稿件以 PDF的形式发送到会议编辑邮箱中如果您是第一次投稿,请点击左侧【投稿】按钮进入到投稿页面如果您已经将稿件发送至会议编辑邮箱中,则会有相应的邮件通知您的邮箱 修改编辑意见和意见回复 编辑审稿结束后,会给出修改意见和回复,在这部分主要是针对论文的问题进行修改,包括文章格式、实验数据、参考文献等等。 在这里我们可以看到有一些修改意见,包括“对论文进行润色”、“建议进行一定的修改”、“请修改参考文献”等等。 当我们需要对论文进行进一步修改时,需要点击对应的选项,在这里主要针对论文中的研究方法和结果两个方面。 研究方法这一项主要是针对研究方法,如果对于研究方法不太熟悉的作者,可以点击右侧的“选项”,然后在弹出的窗口中选择对应的选项即可。 而结果部分则是针对论文中的实验数据部分进行修改。 Ei国际学术会议推荐: 目前艾思科蓝征稿方式为系统在线投稿,实时查看审稿进度和论文状态,有意向详细咨询~ #艾思科蓝 #Ei国际学术会议 #论文投稿 #硕博毕业生

Android输出csv文件乱码

问题:Android输出csv文件乱码 解决方案: output.write(new byte[]{(byte) 0xEF, (byte) 0xBB,(byte) 0xBF}); //代码中的这个是为了解决乱码用的 //往SD卡写入文件的方法 public static String savaFileToSD(String fileName, ArrayList<String> list,Context context) throws Exception { //如果手机已插入sd卡,且app具有读写sd卡的权限 Log.d(TAG,"come in saveFileToSD"); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // fileName = context.getExternalFilesDir(null).getAbsolutePath() + "/" + fileName; //内部存储 fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/" + fileName; Log.d(TAG,"savaFileToSD fileName:"+fileName); //这里就不要用openFileOutput了,那个是往手机内存中写数据的 File file = new File(fileName); if (!file.exists()){ file.createNewFile(); } FileOutputStream output = null; OutputStreamWriter oStreamWriter = null; try { output = new FileOutputStream(fileName); output.

Linux安装nvidia遇到的问题you appear to be running an x server please exit x before installing

一.下载nvidia驱动 到NVIDIA 官网上下载驱动文件(.run 格式) :https://www.nvidia.com/en-us/drivers/results/133571/ 下载自己对应的版本即可 二.安装 sudo ./NVIDIA-Linux-x86_64-*.run 三.可能遇到的问题 1.you appear to be running an x server please exit x before installing的问题 遇到这个问题关闭X 服务即可,可输入一下命令: sudo /etc/init.d/lightdm stop sudo /etc/init.d/lightdm status 对于其他的 linux 版本,如果桌面系统是基于 gdm 类型,应该把命令中的 lightdm 改为 gdm 即可;非这两种桌面系统类型的,百度一下你的 linux 版本关闭 X 服务的相关命令吧。 关闭了 X 服务后图形桌面可能会关闭,因为我是通过 ssh 连接的服务器进行的操作,所以也没有看到具体的变化,然后输入一下命令: ps aux | grep X 查看还有没有X服务的进程,若有直接sudo kill -9 进程号 杀死X服务进程即可: sudo kill -9 [‘pid’] 2.An NVIDIA kernel module 'nvidia-uvm' appears to already be loaded in your kernel的问题 很简单,就像原文所述,'nvidia-uvm'程序因故未退出导致按照无法正常进行,直接:

Mac 下使用ll命令(linux 自定义命令bash)

Mac 下使用ll命令(自定义命令bash)_index_ling的博客-CSDN博客 目录 1、打开文件bash_profile 2、键入命令别名,保存退出 3、测试:新打开一个命令行或刷新bash文件立即生效 1、打开文件bash_profile vim ~/.bash_profile 2、键入命令别名,保存退出 alias ll='ls -alF' alias la='ls -A' 3、测试:新打开一个命令行或刷新bash文件立即生效 source命令:更新可以执行 source ~/.profile 更新系统环境变量,bash命令立即生效 # 刷新bash命令立即生效 source .bash_profile # 测试自定义命令 ll admin@bogon ~ % ll total 160 drwxr-xr-x+ 37 admin staff 1184 6 25 21:54 ./ drwxr-xr-x 6 root admin 192 5 10 05:30 ../ -r-------- 1 admin staff 9 3 29 17:23 .CFUserTextEncoding Mac 下使用ll命令(自定义命令bash)_index_ling的博客-CSDN博客

WSL 修改 hostname

进入 /etc 目录,编辑 wsl.conf,如果没有该文件就创建一个: sudo vim /etc/wsl.conf 输入以下参数: [network] hostname = <hostname> generateHosts = false 其中,<hostname>是你需要更改的主机名。 具体解释如下表: 配置说明hostname设置当前 wsl 的主机名称generateHosts是否自动生成 hosts 文件 在设置完成后退出 wsl。 注意在直接退出 wsl 之后配置并没有直接生效,而是在 wsl 重启之后才会生效。 使用命令使 wsl 先关闭,然后再重新进入。具体命令如下: wsl --list --running wsl --shutdown wsl 可以看到,此时hostname已经成功改为lk了。

vue项目播放海康,大华等rtsp视频流-webrtc

1.下载webrtc 网盘链接:https://pan.baidu.com/s/1QmUbL2lR2DVqezGq8PDhuw 提取码:lygw 下载后直接运行 后台开着就行 2.前端代码 在index.html引入 webrtc/html/lib下的两个文件(我把这两个文件copy了一份放在了public) <script type="text/javascript" src="/webrtc/adapter.min.js"></script> <script type="text/javascript" src="/webrtc/webrtcstreamer.js"></script> 然后就是页面代码 <!-- Description: 监控视频 Author: 李亚光 Date: 2023-05-18 --> <script lang="ts" setup name="EditPerson"> const webRtcServer = ref(null) onMounted(() => { webRtcServer.value = new WebRtcStreamer('video', 'http://127.0.0.1:8000') //这里ip和端口不用修改 webRtcServer.value.connect( 'rtsp://admin:1234qwer@192.168.11.301', //替换成自己的地址 ) }) onBeforeUnmount(() => { webRtcServer.value.disconnect() }) </script> <template> <div className="home"> <video id="video" autoPlay width="800" height="400" style="margin-left: -20px;" /> </div> </template> <style lang="scss" scoped> .demo-video { max-width: 880px; max-height: 660px; } </style> 需注意视频输出格式需要H264

零入门kubernetes网络实战-34->将物理网卡eth0挂载到虚拟网桥上使得内部网络能够跨主机ping通外网的方案

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 本篇文章模拟一下啊,将宿主机的对外的物理网卡,挂载到虚拟网桥上,测试一下, 网桥管理的内部网络如何跟宿主机的本局域网内的其他节点通信? 1、测试环境介绍 两台centos虚拟机 # 查看操作系统版本 cat /etc/centos-release # 内核版本 uname -a uname -r # 查看网卡信息 ip a s eth0 2、网络拓扑 将物理网卡eth0挂载到虚拟网桥br0,从master节点的ns1命名空间里向slave节点发起icmp请求 3、操作实战 3.1、在master上执行下面的命令 brctl addbr br0 ip link set br0 up ip addr add 10.211.55.122/24 dev br0 ip netns add ns1 ip link add veth1a type veth peer name veth1b ip link set veth1a netns ns1 ip netns exec ns1 ip addr add 10.244.1.2/24 dev veth1a ip netns exec ns1 ip link set veth1a up ip link set veth1b up brctl addif br0 veth1b brctl addif br0 eth0 ip netns exec ns1 route add default dev veth1a 在具体执行这些命令前,最好前提前多打开几个xshell终端,

YOLO8自定义检测实战

文章目录 资料模型介绍(或者叫weights)安装安装ultralytics(yolo)Torch测试命令 CLI命令行通过COCO128数据集体验yolov8标签predictsegment下载COCO 2017数据集ValTrain 自定义数据集标注标注软件labelimg分析训练结果 获得最佳训练结果提示 资料 Docs: https://docs.ultralytics.comCommunity: https://community.ultralytics.comGitHub: https://github.com/ultralytics/ultralyticsCOCO数据集 https://cocodataset.org/#downloadkaggle 云平台数据集 模型介绍(或者叫weights) 模型仓库 安装 安装ultralytics(yolo) https://docs.ultralytics.com/quickstart/#install 方式一:https://docs.ultralytics.com/quickstart/ git clone https://github.com/ultralytics/ultralytics cd ultralytics pip install -e . 方式二: pip install ultralytics yolo -v 8.0.105 Torch torch测试, False说明驱动还没好, 进入python命令行 # cuda支持检查 import torch print(torch.cuda.is_available()) https://pytorch.org/get-started/previous-versions/ 执行类似命令安装某个版本cuXXX pip install torch==2.0.0+cu118 torchvision==0.15.1+cu118 torchaudio==2.0.1 --index-url https://download.pytorch.org/whl/cu118 测试命令 yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg Downloading https:\github.com\ultralytics\assets\releases\download\v0.0.0\yolov8n.pt to yolov8n.pt... 100%|█████████████████████████████████████████████████████████████████████████████| 6.23M/6.23M [00:01<00:00, 4.59MB/s] Ultralytics YOLOv8.0.105 Python-3.10.11 torch-2.

大大大大大模型部署方案抛砖引玉

借着热点,简单聊聊大模型的部署方案,作为一个只搞过CV部署的算法工程师,在最近LLM逐渐改变生活的大背景下,猛然意识到LLM部署也是很重要的。大模型很火,而且确实有用(很多垂类场景可以针对去训练),并且和Vision结合的大模型也逐渐多了起来。所以怎么部署大模型是一个超级重要的工程问题,很多公司也在紧锣密鼓的搞着。 目前效果最好讨论最多的开源实现就是LLAMA,所以我这里讨论的也是基于LLAMA的魔改部署。 基于LLAMA的finetune模型有很多,比如效果开源最好的vicuna-13b和较早开始基于llama做实验的alpaca-13b,大家可以看: https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard 开源LLMhttps://lmsys.org/blog/2023-05-03-arena/ 基于llama的开源对比https://github.com/camenduru/text-generation-webui-colab 一些开源LLM的notebook 至于为啥要选LLAMA,因为当前基于LLAMA的模型很多,基础的llama的效果也不错,当然RWKV也很不错,我也一直在看。 具体的可以看这里,https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard Github上较多的是实现是直接python推理然后基于gradio的网页端展示,还不能被当成服务调用(或者说不大优雅),一般来说作为服务: 响应速度要快,每秒的tokens越多越好稳定性,出现core了不会影响推理或者可以及时恢复支持各种形式,http、sse、grpc等形式 其实最重要的一点还是要快,其次必须要量化,因为大模型的权重往往很大,量化可以有效减小权重(省显卡),是非常必要的。要做成服务的话,需要稍稍花一点功夫和魔改一下,幸运的是网上已经有不错的demo实现供我们尝试,这篇文章主要是总结下以LLAMA为例的LLM部署方案,希望能抛砖引玉。 PS:我们常用的ChatGPT据说是居于Python服务搭建的,相比模型的耗时,python环境的开销可以忽略不计。 以LLAMA为例 LLM很大,比如GPT3-175B的大模型,700GB的参数以及运行过程中600GB的激活值,1.3TB总共,正常来说,得32个A100-40GB才能放的下。 但实际应用中,消费级显卡要比专业显卡便宜的多(比如3090相比A10,同样都是24G显存),所以用消费级显卡部署LLM也很有钱途。一张卡放不下那就放两张,如果没有nvlink,那么PCIE的也凑合用。 回到LLAMA模型,有7B、13B、30B、65B的版本,当然是越大的版本效果最好,相应的也需要更多的显存(其实放到内存或者SSD也是可以的,但是速度相比权重全放到显存里头,肯定要慢)。 LLAMA的实现很多,简单列几个我看过的,都可以参考: https://github.com/juncongmoo/pyllama 原始llama的实现方式https://github.com/qwopqwop200/GPTQ-for-LLaMa 支持量化,INT4、INT8量化的llamahttps://github.com/tpoisonooo/llama.onnx.git 以ONNX的方式运行llama 量化和精度 对于消费级显卡,直接FP32肯定放不下,一般最基本的是FP16(llama的7B,FP16需要14G的显存,大多数的消费级显卡已经说拜拜了),而INT8和INT4量化则就很有用了,举几个例子: 对于3080显卡,10G显存,那么13B的INT4就很有性价比,精度比7B-FP16要高很多对于3090显卡,24G显存,那么30B的INT4可以在单个3090显卡部署,精度更高 可以看下图,列举了目前多种开源预训练模型在各种数据集上的分数和量化精度的关系: 我自己也测试了几个模型,我使用的是A6000显卡,48G的显存,基于GPTQ-for-LLAMA测试了各种不同规格模型的PPL精度和需要的显存大小。 执行以下命令CUDA_VISIBLE_DEVICES=0 python llama.py ${MODEL_DIR} c4 --wbits 4 --groupsize 128 --load llama7b-4bit-128g.pt --benchmark 2048 --check测试不同量化精度不同规格模型的指标: # 7B-FP16 Median: 0.03220057487487793 PPL: 5.227280139923096 max memory(MiB): 13948.7333984375 # 7B-INT8 Median: 0.13523507118225098 PPL: 5.235021114349365 max memory(MiB): 7875.92529296875 # 7B-INT4 Median: 0.038548946380615234 PPL: 5.268043041229248 max memory(MiB): 4850.73095703125 # 13B-FP16 Median: 0.

2023年最新react面试题 附详细答案

1. 什么是React? React是一个用于构建用户界面的JavaScript库。它由Facebook开发,现已成为最受欢迎的前端库之一。 2. React的特点是什么? React的主要特点包括: 组件化虚拟DOM单向数据流JSX语法高效的性能生态系统丰富 3. 什么是JSX? JSX是一种JavaScript的语法扩展,它允许我们在JavaScript中编写类似HTML的代码。它是React的核心之一,用于描述UI组件的结构和样式。 4. React中的组件有哪些类型? React中的组件可以分为两种类型: 函数组件:使用函数来定义组件。类组件:使用ES6类来定义组件。 5. 什么是props? props是React中传递给组件的属性。它们是只读的,不能在组件内部更改。可以将props视为组件的配置。 6. 什么是state? state是React中用于存储组件内部状态的对象。它们是可变的,可以在组件内部更改。当state发生变化时,组件将重新渲染。 7. 什么是生命周期方法? 生命周期方法是React中的一组特殊方法,它们在组件的生命周期中被调用。这些方法使我们能够在组件的不同阶段执行特定的操作,例如初始化组件、更新组件、卸载组件等。 8. React中有哪些生命周期方法? React中有三个生命周期阶段: 挂载阶段:组件被创建并添加到DOM中。更新阶段:组件的props或state发生变化时,组件被重新渲染。卸载阶段:组件被从DOM中移除。 在这些阶段中,React提供了以下生命周期方法: constructor()static getDerivedStateFromProps()render()componentDidMount()shouldComponentUpdate()getSnapshotBeforeUpdate()componentDidUpdate()componentWillUnmount() 9. 什么是constructor()方法? constructor()方法是React组件的构造函数。它在组件被创建时被调用,并且可以用于初始化组件的状态和绑定方法。 10. 什么是render()方法? render()方法是React组件的核心方法之一。它返回组件的虚拟DOM结构,并负责处理组件的渲染。 11. 什么是componentDidMount()方法? componentDidMount()方法是React组件的生命周期方法之一。它在组件被添加到DOM中后被调用,并且可以用于执行一些初始化操作,例如获取数据或添加事件监听器。 12. 什么是shouldComponentUpdate()方法? shouldComponentUpdate()方法是React组件的生命周期方法之一。它在组件的props或state发生变化时被调用,并且可以用于决定是否需要重新渲染组件。 13. 什么是componentDidUpdate()方法? componentDidUpdate()方法是React组件的生命周期方法之一。它在组件的props或state发生变化后被调用,并且可以用于执行一些更新操作,例如更新DOM或重新获取数据。 14. 什么是componentWillUnmount()方法? componentWillUnmount()方法是React组件的生命周期方法之一。它在组件被卸载之前被调用,并且可以用于执行一些清理操作,例如取消事件监听器或清除定时器。 15. 什么是setState()方法? setState()方法是React组件的方法之一。它用于更新组件的状态,并且会触发组件的重新渲染。 16. 什么是React Router? React Router是一个用于构建单页应用程序的React库。它允许我们在应用程序中定义路由,并且可以根据URL的变化来渲染不同的组件。 17. React Router中有哪些组件? React Router中有以下组件: BrowserRouter:用于在应用程序中启用HTML5历史路由。HashRouter:用于在应用程序中启用哈希路由。Route:用于定义应用程序中的路由规则。Switch:用于在多个路由规则中选择一个。Link:用于在应用程序中导航到其他页面。 18. 什么是Redux? Redux是一个用于管理应用程序状态的JavaScript库。它是一个单向数据流的架构,可以让我们更好地组织和管理应用程序的状态。 19. Redux中有哪些核心概念? Redux中有以下核心概念: Store:用于管理应用程序的状态。Action:用于描述发生的事件。Reducer:用于处理Action并更新状态。Dispatch:用于将Action发送到Reducer。 20.

Spring AOP通知(Advice)详解

Spring 的 AOP 功能中一个关键概念是通知(Advice),与切点(Pointcut)表达式相关联在特定节点织入一些逻辑,Spring 提供了五种类型的通知。 理解 AOP 概念参阅: 《Spring的AOP和动态代理》 配置 AOP 参阅: 《Spring基于注解配置AOP》 《Spring基于XML配置AOP》 一、概述 AOP 中的通知是基于连接点(Join point)业务逻辑的一种增强,Spring AOP 提供了下面五种通知类型: Before advice(前置通知):连接点前面执行,不能终止后续流程,除非抛异常 After returning advice(后置通知):连接点正常返回时执行,有异常不执行 Around advice(环绕通知):围绕连接点前后执行,也能捕获异常处理 After advice(最终通知):连接点退出时执行,无论是正常退出还是异常退出 After throwing advice(异常通知):连接点方法抛出异常时执行 AOP 的连接点一般是指目标类的方法,五种通知类型执行的节点如下: 二、通知的定义 Spring AOP 可以基于 XML 方式和基于注解方式定义,只是写法不同,这里只使用注解的方式来讲解通知的详细用法。 1. 前置通知 在 @Aspect 切面类中使用 @Before 注解简单地定义一个前置通知。 @Aspect @Component public class DemoAspect { @Before("execution(* cn.codeartist.spring.aop.advice.*.*(..))") public void doBefore() { // 自定义逻辑 } } 2. 后置通知 方法正常返回,会执行后置通知,使用 @AfterReturning 注解定义后置通知。 @AfterReturning("execution(* cn.