Spring boot框架 JWT实现用户账户密码登录验证

目录 1、JWT定义 1、1 JWT工作流程 1、2 JWT优点 2、添加依赖项到pom.xml 3、创建用户实体类 4、实现认证服务 5、登录请求处理 6、生成JWT 1、JWT定义 JWT(JSON Web Token)是一种用于在网络应用间传递信息的安全传输方式。它是一种紧凑且自包含的方式,通过使用数字签名来验证数据的完整性和真实性。 JWT由三部分组成,使用.进行分隔: Header(头部):包含JWT的类型(typ)和使用的签名算法(alg)等信息。Payload(负载):包含要传输的数据,例如用户身份信息、权限等。它是JWT的主要内容,可以自定义添加其他需要的字段。Signature(签名):使用指定的算法对Header和Payload进行签名,以确保数据在传输过程中没有被篡改。 1、1 JWT工作流程 用户使用有效的身份凭证(如用户名和密码)向服务器发送登录请求。服务器验证用户身份信息,如果验证通过,生成一个JWT并将其返回给客户端。客户端在后续的请求中将JWT添加到请求的头部、查询参数或Cookie中进行传递。服务器接收到请求后,使用密钥验证JWT的签名和完整性,并从中提取出有效的用户信息和权限等数据进行处理。如果JWT验证通过,服务器处理请求并返回响应给客户端。 1、2 JWT优点 优点包括: 简单:JWT使用JSON格式存储信息,易于理解和使用。自包含:JWT中携带了用户的信息和权限等数据,避免了频繁查询数据库的开销。可扩展:JWT的负载部分可以自定义添加需要的字段。跨平台和语言支持:JWT在各种平台和编程语言中都有对应的实现和支持。无状态:JWT本身是无状态的,服务器不需要保存用户的会话信息,提高了可伸缩性。 2、添加依赖项到pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> 3、创建用户实体类 创建一个表示用户的实体类,例如User,其中包含用户名和密码等属性。 如下: 4、实现认证服务 创建一个类实现Spring Security的UserDetailsService接口,用于加载用户信息。在该类中,根据用户名查询数据库,获取用户信息,包括密码。 public List<UserEntity> findAllService() { return userMapper.findAllUser(); } public ResultResponse login(String name,String password) { UserEntity user=userMapper.checkPassword(name,password); if(user != null){ //不等于null就开始颁发jwt String token = jwtUtils.generateToken(name); System.out.println(token); return ResultResponse.returnToken(ResultResponse.success("颁发token成功",token)); } return ResultResponse.illegalToken(); } public ResultResponse info(String token) { String tokenString = token; String subject = JwtUtils.

华为机试(JAVA)真题Od【A卷+B卷】2023

目录 华为OD机试是什么?华为OD面试流程?华为OD机试通过率高吗?华为OD薪资待遇?华为OD晋升空间? 大家好,我是哪吒。 本专栏包含了最新最全的华为OD机试真题,有详细的分析和Java代码解答。已帮助1000+同学顺利通过OD机考,发现新题目,随时更新。 华为机试有三道题,第一道和第二道属于简单或中等题,分值为100分,第三道为中等或困难题,分值为200分。总分400分,150分钟的考试时间,150分通过。大家只要多刷题,争取拿高分,毕竟分数越高,评级越高,工资自然也就越高。OD的工资一般都很可观,大概在20K-30K左右,大家一起刷题,冲。 很多题是哪吒群里的小伙伴反馈的,感谢大家的分享,大家可以作为参考,学习。 本栏准备了200+的华为OD真题,全刷完应该十拿九稳了,大家一起加油。 每道题都是哪吒精心准备,并通过idea运行,算法100%准确,通过率100%,部分题附带详细解题思路。大家有什么不懂的,想看的,都可以留言,或者私信哪吒。 华为OD机试是什么? 华为OD机试是指华为公司的在线笔试,是华为公司用于筛选招聘岗位候选人的一种考核方式。 华为OD机试通常由多个题目组成,包括算法设计、编程、调试等多个环节,考察候选人的基础知识、实际能力和算法编写能力等多个方面,是华为招聘流程中非常重要的一环。 华为OD面试流程? 华为OD面试流程一般包括以下几个步骤: 笔试:考察候选人的基础知识、算法设计和编程能力等多个方面。题目通常包括算法题、编程题、数据结构题等。性格测试:这部分是用来评估候选人的性格特质,以便更好地了解其适应能力、沟通能力和团队合作能力等。技术一面:该面试官通常是该项目组的技术负责人,主要考察候选人对技术的理解和实际应用能力。面试内容通常包括代码题和项目问题解决。群面:这是华为面试中比较特殊的一环,通常会组织多个候选人进行小组面试,以便更全面地了解其团队合作、沟通能力和领导能力等。终面:终面是在参加完所有面试后进行的最后一轮面试,由公司的高层领导或者HR部门的负责人进行面试。主要考察候选人的综合素质和领导潜力。 其中,笔试和性格测试是比较常见的部分,而技术一面和群面则比较特殊,通常会根据不同的岗位和项目有所不同。最终的面试结果也会根据个人的表现和竞争情况而定,不会限制通过人数。 华为OD机试通过率高吗? 据华为官方公布的数据,华为OD机试的通过率约为75%。具体来说,华为OD机试一共有五个级别,从D1到D5,对应13到17级,每个级别的题目数量和难度都有所不同。在过去的招聘中,据说只有25%左右的候选人能够通过第一轮机试。第二轮性格测试也是招聘流程中的重要环节,会刷掉一部分人。不过,华为表示,最终的通过率取决于候选人的实际表现和竞争情况,不会限制通过人数。 此外,华为还将机试分为上机考试和在线作业两部分,上机考试主要考察算法设计和编程能力,在线作业主要考察算法思维和解决问题的能力。华为表示,在线作业部分是考察候选人的综合能力,包括解决问题的能力、沟通能力和团队合作能力等。 综合来看,华为OD机试的通过率虽然不是100%,但是也是在高水平范围内的。对于候选人来说,需要全面提升自己的能力,才能更好地通过机试。 华为OD薪资待遇? 在华为od岗的薪资问题,并没有比市场上多多少,具体根据个人职级和绩效而定,初入职场的应届生薪资大概在20K-30K左右,相对于其他行业来说,华为的起薪是比较高的。 此外,华为的薪资结构包括基本工资、年终奖、分红等多个部分,其中年终奖的比例一般在15%以上,具体数额因个人绩效而定。此外,华为还有一些股票和期权等长期激励方式,可以让员工分享公司的成长红利。 总的来说,华为的薪资待遇相对较好,但是具体的薪资水平还是要根据个人的职级和绩效而定。 华为OD晋升空间? 华为OD岗位的晋升空间取决于个人的能力和表现,以及公司的发展战略和需求。根据华为公司的招聘信息和应聘者的反馈,OD岗位的晋升通常有以下几个方向: 技术专家:可以继续深入学习和研究技术,成为该领域的专家,具备带领团队的能力。管理岗位:可以从技术专家向管理方向发展,承担更多的管理工作,带领团队完成项目。跨部门转岗:有些候选人可以通过在不同部门的工作经验,积累跨部门工作的经验,然后转到其他部门,进行业务拓展或管理。内部培训和发展:公司会定期组织内部培训和发展计划,为员工提供提升自身能力的机会,支持员工在公司内部寻找更适合自己的发展道路。 总的来说,OD岗位的晋升空间相对较广,但是需要候选人不断提升自身能力,积极参与公司的内部培训和发展计划,才能在职业生涯中获得更好的发展机会。 以下为华为OD机试真题题库。 1、华为OD机试真题 Java 实现【最多提取子串数目】【2023Q1 100分】 2、华为OD机试真题 Java 实现【不爱施肥的小布】【2023Q2 100分】 3、华为OD机试真题 Java 实现【猜字谜】【2023Q1 100分】】 4、华为OD机试真题 Java 实现【微服务的集成测试】【2023Q1 100分】 5、华为OD机试真题 Java 实现【字符串重新排序】【2023Q1 100分】 6、华为OD机试真题 Java 实现【知识图谱新词挖掘1】【2023Q1 100分】 7、华为OD机试真题 Java 实现【寻找关键钥匙】【2023Q1 100分】 8、华为OD机试真题 Java 实现【静态代码扫描服务】【2023Q1 100分】 9、华为OD机试真题 Java 实现【新员工座位安排系统】【2023Q1 100分】 10、华为OD机试真题 Java 实现【贪心的商人】【2023Q1 100分】 11、华为OD机试真题 Java 实现【MVP争夺战】【2023Q2 100分】

【nnunet】个人数据训练心得

安装: pip install nnunetv2 ## 或者是把他下载下来,自行安装 git clone https://github.com/MIC-DKFZ/nnUNet.git cd nnUNet pip install -e . GitHub代码: GitHub - MIC-DKFZ/nnUNet 十项医学分割数据集: Medical Segmentation Decathlon 注意:安装时一定不能使用魔法,否则会被伏地魔(False) 配置: 这里有几个铁汁,可以一起参考,以他们的为主,我的为辅,一起食用 (四:2020.07.28)nnUNet最舒服的训练教程(让我的奶奶也会用nnUNet(上))(21.04.20更新)_nnuet_花卷汤圆的博客-CSDN博客 nnUNet实战一使用预训练nnUNet模型进行推理_Tina姐的博客-CSDN博客 nnUNet 使用不完全指南(上) - No Visitor Website(这里有自定义生成json的代码) 我引用一下吧: from collections import OrderedDict from batchgenerators.utilities.file_and_folder_operations import save_json def main(): foldername = "Task128_LungLobe" numTraining = 80 numTest = 6 numClass = 6 json_dict = OrderedDict() json_dict['name'] = foldername json_dict['description'] = foldername json_dict['tensorImageSize'] = "4D" json_dict['reference'] = "

从0开始学大数据14-BigTable的开源实现:HBase

14 | BigTable的开源实现:HBase 我们知道,Google发表GFS、MapReduce、BigTable三篇论文,号称“三驾马车”,开启了大数据的时代。那和这“三驾马车”对应的有哪些开源产品呢?我们前面已经讲过了GFS对应的Hadoop分布式文件系统HDFS,以及MapReduce对应的Hadoop分布式计算框架MapReduce,今天我们就来领略一下BigTable对应的NoSQL系统HBase,看看它是如何大规模处理海量数据的。 在计算机数据存储领域,一直是关系数据库(RDBMS)的天下,以至于在传统企业的应用领域,许多应用系统设计都是面向数据库设计,也就是 先设计数据库然后设计程序,从而导致 关系模型绑架对象模型,并由此引申出旷日持久的业务对象贫血模型与充血模型之争。 业界为了解决关系数据库的不足,提出了诸多方案,比较有名的是对象数据库,但是这些数据库的出现似乎只是进一步证明关系数据库的优越而已。直到人们遇到了关系数据库难以克服的缺陷——糟糕的海量数据处理能力及僵硬的设计约束,局面才有所改善。从Google的BigTable开始,一系列的可以进行海量数据存储与访问的数据库被设计出来,更进一步说,NoSQL这一概念被提了出来。 NoSQL,主要指非关系的、分布式的、支持海量数据存储的数据库设计模式。也有许多专家将 NoSQL解读为Not Only SQL,表示NoSQL只是关系数据库的补充,而不是替代方案。其中,HBase是这一类NoSQL系统的杰出代表。 HBase之所以能够具有海量数据处理能力,其根本在于和传统关系型数据库设计的不同思路。传统关系型数据库对存储在其上的数据有很多约束,学习关系数据库都要学习数据库设计范式,事实上,是在数据存储中包含了一部分业务逻辑。而NoSQL数据库则简单暴力地认为,数据库就是存储数据的,业务逻辑应该由应用程序去处理,有时候不得不说,简单暴力也是一种美。 HBase可伸缩架构 我们先来看看HBase的架构设计。HBase为可伸缩海量数据储存而设计,实现面向在线业务的实时数据访问延迟。HBase的伸缩性主要依赖其可分裂的HRegion及可伸缩的分布式文件系统HDFS实现。 HRegion是HBase负责数据存储的主要进程,应用程序对数据的读写操作都是通过和HRegion通信完成。上面是HBase架构图,我们可以看到在HBase中,数据以HRegion为单位进行管理,也就是说应用程序如果想要访问一个数据,必须先找到HRegion,然后将数据读写操作提交给HRegion,由 HRegion完成存储层面的数据操作。 HRegionServer是物理服务器,每个HRegionServer上可以启动多个HRegion实例。当一个 HRegion中写入的数据太多,达到配置的阈值时,一个HRegion会分裂成两个HRegion,并将HRegion在整个集群中进行迁移,以使HRegionServer的负载均衡。 每个HRegion中存储一段Key值区间[key1, key2)的数据,所有HRegion的信息,包括存储的Key值区间、所在HRegionServer地址、访问端口号等,都记录在HMaster服务器上。为了保证HMaster的高可用,HBase会启动多个HMaster,并通过ZooKeeper选举出一个主服务器。 下面是一张调用时序图,应用程序通过ZooKeeper获得主HMaster的地址,输入Key值获得这个Key所在的HRegionServer地址,然后请求HRegionServer上的HRegion,获得所需要的数据。 数据写入过程也是一样,需要先得到HRegion才能继续操作。HRegion会把数据存储在若干个HFile格式的文件中,这些文件使用HDFS分布式文件系统存储,在整个集群内分布并高可用。当一个HRegion中数据量太多时,这个HRegion连同HFile会分裂成两个HRegion,并根据集群中服务器负载进行迁移。如果集群中有新加入的服务器,也就是说有了新的HRegionServer,由于其负载较低,也会把HRegion迁移过去并记录到HMaster,从而实现HBase的线性伸缩。 先小结一下上面的内容,HBase的核心设计目标是解决海量数据的分布式存储,和Memcached这类分布式缓存的路由算法不同,HBase的做法是按Key的区域进行分片,这个分片也就是HRegion。应用程序通过HMaster查找分片,得到HRegion所在的服务器HRegionServer,然后和该服务器通信,就得到了需要访问的数据。 HBase可扩展数据模型 传统的关系数据库为了保证关系运算(通过SQL语句)的正确性,在设计数据库表结构的时候,需要指定表的schema也就是字段名称、数据类型等,并要遵循特定的设计范式。这些规范带来了一个问题,就是僵硬的数据结构难以面对需求变更带来的挑战,有些应用系统设计者通过预先设计一些冗余字段来应对,但显然这种设计也很糟糕。 那有没有办法能够做到可扩展的数据结构设计呢?不用修改表结构就可以新增字段呢?当然有的,许多NoSQL数据库使用的列族(ColumnFamily)设计就是其中一个解决方案。列族最早在Google的BigTable中使用,这是一种面向列族的稀疏矩阵存储格式,如下图所示。 这是一个学生的基本信息表,表中不同学生的联系方式各不相同,选修的课程也不同,而且将来还会有更多联系方式和课程加入到这张表里,如果按照传统的关系数据库设计,无论提前预设多少冗余字段都会捉襟见肘、疲于应付。 而使用支持列族结构的NoSQL数据库,在创建表的时候,只需要指定列族的名字,无需指定字段(Column)。那什么时候指定字段呢?可以在数据写入时再指定。通过这种方式,数据表可以包含数百万的字段,这样就可以随意扩展应用程序的数据结构了。并且这种数据库在查询时也很方便,可以通过指定任意字段名称和值进行查询。 HBase这种列族的数据结构设计,实际上是把字段的名称和字段的值,以Key-Value的方式一起存储在HBase中。实际写入的时候,可以随意指定字段名称,即使有几百万个字段也能轻松应对。 HBase的高性能存储 还记得专栏第5期讲RAID时我留给你的思考题吗?当时很多同学答得都很棒。传统的机械式磁盘的访问特性是 连续读写很快,随机读写很慢。这是因为机械磁盘靠电机驱动访问磁盘上的数据,电机要将磁头落到数据所在的磁道上,这个过程需要较长的寻址时间。如果数据不连续存储,磁头就要不停地移动,浪费了大量的时间。 为了提高数据写入速度,HBase使用了一种叫作 LSM树 的数据结构进行数据存储。LSM树的全名是Log Structed Merge Tree,翻译过来就是Log结构合并树。数据写入的时候以Log方式连续写入,然后异步对磁盘上的多个LSM树进行合并。 LSM树可以看作是一个N阶合并树。数据写操作(包括插入、修改、删除)都在内存中进行,并且都会创建一个新记录(修改会记录新的数据值,而删除会记录一个删除标志)。这些数据在内存中仍然还是一棵排序树,当数据量超过设定的内存阈值后,会将这棵排序树和磁盘上最新的排序树合并。当这棵排序树的数据量也超过设定阈值后,会和磁盘上下一级的排序树合并。合并过程中,会用最新更新的数据覆盖旧的数据(或者记录为不同版本)。 在需要进行读操作时,总是从内存中的排序树开始搜索,如果没有找到,就从磁盘 上的排序树顺序查找。 在LSM树上进行一次数据更新不需要磁盘访问,在内存即可完成。当数据访问以写操作为主,而读操作则集中在最近写入的数据上时,使用LSM树可以极大程度地减少磁盘的访问次数,加快访问速度。 小结 最后,总结一下我们今天讲的内容。HBase作为Google BigTable的开源实现,完整地继承了BigTable的优良设计。架构上通过数据分片的设计配合HDFS,实现了数据的分布式海量存储;数据结构上通过列族的设计,实现了数据表结构可以在运行期自定义;存储上通过LSM树的方式,使数据可以通过连续写磁盘的方式保存数据,极大地提高了数据写入性能。 这些优良的设计结合Apache开源社区的高质量开发,使得HBase在NoSQL众多竞争产品中保持领先优势,逐步成为NoSQL领域最具影响力的产品。 思考题 HBase的列族数据结构虽然有灵活的优势,但是也有缺点。请你思考一下,列族结构的缺点有哪些?如何在应用开发的时候克服这些缺点?哪些场景最好还是使用MySQL这类关系数据库呢? 欢迎你写下自己的思考或疑问,与我和其他同学一起讨论。如果你学完今天的内容有所收获的话,也欢迎你点击“请朋友读”,把今天的文章分享给你的朋友。

从0开始学大数据13-同样的本质,为何Spark可以更高效?

13 | 同样的本质,为何Spark可以更高效? 上一期我们讨论了Spark的编程模型,这期我们聊聊Spark的架构原理。和MapReduce一样, Spark也遵循移动计算比移动数据更划算这一大数据计算基本原则。但是和MapReduce僵化的Map与Reduce分阶段计算相比,Spark的计算框架更加富有弹性和灵活性,进而有更好的运行性能。 Spark的计算阶段 我们可以对比来看。首先和MapReduce一个应用一次只运行一个map和一个reduce不同,Spark可以根据应用的复杂程度,分割成更多的计算阶段(stage),这些计算阶段组成一个有向无环图DAG,Spark任务调度器可以根据DAG的依赖关系执行计算阶段。 还记得在上一期,我举了一个比较逻辑回归机器学习性能的例子,发现Spark比MapReduce快100多倍。因为某些机器学习算法可能需要进行大量的迭代计算,产生数万个计算阶段,这些计算阶段在一个应用中处理完成,而不是像MapReduce那样需要启动数万个应用,因此极大地提高了运行效率。 所谓DAG也就是有向无环图,就是说不同阶段的依赖关系是有向的,计算过程只能沿着依赖关系方向执行,被依赖的阶段执行完成之前,依赖的阶段不能开始执行,同时,这个依赖关系不能有环形依赖,否则就成为死循环了。下面这张图描述了一个典型的Spark运行DAG的不同阶段。 从图上看,整个应用被切分成3个阶段,阶段3需要依赖阶段1和阶段2,阶段1和阶段2互不依赖。Spark在执行调度的时候,先执行阶段1和阶段2,完成以后,再执行阶段3。如果有更多的阶段,Spark的策略也是一样的。只要根据程序初始化好DAG,就建立了依赖关系,然后根据依赖关系顺序执行各个计算阶段,Spark大数据应用的计算就完成了。 上图这个DAG对应的Spark程序伪代码如下。 rddB = rddA.groupBy(key) rddD = rddC.map(func) rddF = rddD.union(rddE) rddG = rddB.join(rddF) 所以,你可以看到Spark作业调度执行的核心是DAG,有了DAG,整个应用就被切分成哪些阶段,每个阶段的依赖关系也就清楚了。之后再根据每个阶段要处理的数据量生成相应的任务集合(TaskSet),每个任务都分配一个任务进程去处理,Spark就实现了大数据的分布式计算。 具体来看的话,负责Spark应用DAG生成和管理的组件是DAGScheduler,DAGScheduler根据程序代码生成DAG,然后将程序分发到分布式计算集群,按计算阶段的先后关系调度执行。 那么Spark划分计算阶段的依据是什么呢?显然并不是RDD上的每个转换函数都会生成一个计算阶段,比如上面的例子有4个转换函数,但是只有3个阶段。 你可以再观察一下上面的DAG图,关于计算阶段的划分从图上就能看出规律,当RDD之间的转换连接线呈现多对多交叉连接的时候,就会产生新的阶段。一个RDD代表一个数据集,图中每个RDD里面都包含多个小块,每个小块代表RDD的一个分片。 一个数据集中的多个数据分片需要进行分区传输,写入到另一个数据集的不同分片中,这种数据分区交叉传输的操作,我们在MapReduce的运行过程中也看到过。 是的,这就是shuffle过程,Spark也需要通过shuffle将数据进行重新组合,相同Key的数据放在一起,进行聚合、关联等操作,因而每次shuffle都产生新的计算阶段。这也是为什么计算阶段会有依赖关系,它需要的数据来源于前面一个或多个计算阶段产生的数据,必须等待前面的阶段执行完毕才能进行shuffle,并得到数据。 这里需要你特别注意的是, 计算阶段划分的依据是shuffle,不是转换函数的类型,有的函数有时候有shuffle,有时候没有。比如上图例子中RDD B和RDD F进行join,得到RDD G,这里的RDD F需要进行shuffle,RDD B就不需要。 因为RDD B在前面一个阶段,阶段1的shuffle过程中,已经进行了数据分区。分区数目和分区Key不变,就不需要再进行shuffle。 这种不需要进行shuffle的依赖,在Spark里被称作窄依赖;相反的,需要进行shuffle的依赖,被称作宽依赖。跟MapReduce一样,shuffle也是Spark最重要的一个环节,只有通过shuffle,相关数据才能互相计算,构建起复杂的应用逻辑。 在你熟悉Spark里的shuffle机制后我们回到今天文章的标题,同样都要经过shuffle,为什么Spark可以更高效呢? 其实从本质上看,Spark可以算作是一种MapReduce计算模型的不同实现。Hadoop MapReduce简单粗暴地根据shuffle将大数据计算分成Map和Reduce两个阶段,然后就算完事了。而Spark更细腻一点,将前一个的Reduce和后一个的Map连接起来,当作一个阶段持续计算,形成一个更加优雅、高效的计算模型,虽然其本质依然是Map和Reduce。但是这种多个计算阶段依赖执行的方案可以有效减少对HDFS的访问,减少作业的调度执行次数,因此执行速度也更快。 并且和Hadoop MapReduce主要使用磁盘存储shuffle过程中的数据不同,Spark优先使用内存进行数据存储,包括RDD数据。除非是内存不够用了,否则是尽可能使用内存, 这也是Spark性能比Hadoop高的另一个原因。 Spark的作业管理 我在专栏上一期提到,Spark里面的RDD函数有两种,一种是转换函数,调用以后得到的还是一个RDD,RDD的计算逻辑主要通过转换函数完成。 另一种是action函数,调用以后不再返回RDD。比如 count()函数,返回RDD中数据的元素个数; saveAsTextFile(path),将RDD数据存储到path路径下。Spark的DAGScheduler在遇到shuffle的时候,会生成一个计算阶段,在遇到action函数的时候,会生成一个作业(job)。 RDD里面的每个数据分片,Spark都会创建一个计算任务去处理,所以一个计算阶段会包含很多个计算任务(task)。 关于作业、计算阶段、任务的依赖和时间先后关系你可以通过下图看到。 图中横轴方向是时间,纵轴方向是任务。两条粗黑线之间是一个作业,两条细线之间是一个计算阶段。一个作业至少包含一个计算阶段。水平方向红色的线是任务,每个阶段由很多个任务组成,这些任务组成一个任务集合。 DAGScheduler根据代码生成DAG图以后,Spark的任务调度就以任务为单位进行分配,将任务分配到分布式集群的不同机器上执行。 Spark的执行过程 Spark支持Standalone、Yarn、Mesos、Kubernetes等多种部署方案,几种部署方案原理也都一样,只是不同组件角色命名不同,但是核心功能和运行流程都差不多。 上面这张图是Spark的运行流程,我们一步一步来看。 首先,Spark应用程序启动在自己的JVM进程里,即Driver进程,启动后调用SparkContext初始化执行配置和输入数据。SparkContext启动DAGScheduler构造执行的DAG图,切分成最小的执行单位也就是计算任务。 然后Driver向Cluster Manager请求计算资源,用于DAG的分布式计算。Cluster Manager收到请求以后,将Driver的主机地址等信息通知给集群的所有计算节点Worker。 Worker收到信息以后,根据Driver的主机地址,跟Driver通信并注册,然后根据自己的空闲资源向Driver通报自己可以领用的任务数。Driver根据DAG图开始向注册的Worker分配任务。 Worker收到任务后,启动Executor进程开始执行任务。Executor先检查自己是否有Driver的执行代码,如果没有,从Driver下载执行代码,通过Java反射加载后开始执行。 小结 总结来说,Spark有三个主要特性: RDD的编程模型更简单,DAG切分的多阶段计算过程更快速,使用内存存储中间计算结果更高效。这三个特性使得Spark相对Hadoop MapReduce可以有更快的执行速度,以及更简单的编程实现。 Spark的出现和流行其实也有某种必然性,是天时、地利、人和的共同作用。首先,Spark在2012年左右开始流行,那时内存的容量提升和成本降低已经比MapReduce出现的十年前强了一个数量级,Spark优先使用内存的条件已经成熟;其次,使用大数据进行机器学习的需求越来越强烈,不再是早先年那种数据分析的简单计算需求。而机器学习的算法大多需要很多轮迭代,Spark的stage划分相比Map和Reduce的简单划分,有更加友好的编程体验和更高效的执行效率。于是Spark成为大数据计算新的王者也就不足为奇了。 思考题 Spark的流行离不开它成功的开源运作,开源并不是把源代码丢到GitHub上公开就万事大吉了,一个成功的开源项目需要吸引大量高质量开发者参与其中,还需要很多用户使用才能形成影响力。

蓝桥杯题单day3【题目】

拓扑排序 [2017年蓝桥杯国赛] 发现环 LCA与树上差分 砍树 景区导游 最短路及其应用 [模板] Dijkstra? [2022年数据结构期末笔试 - 附加题] 得到要求路径的最小带权子图 树与图的DFS和BFS [模板] Longest path in a tree Two Paths 最小生成树及其应用 Make It Connected Road Reform

Node.js 多进程

我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。 每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象。 Node 提供了 child_process 模块来创建子进程,方法有: exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。 spawn - child_process.spawn 使用指定的命令行参数创建新进程。 fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['./son.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。 exec() 方法 child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。 语法如下所示: child_process.exec(command[, options], callback) 参数 参数说明如下: command: 字符串, 将要运行的命令,参数使用空格隔开 options :对象,可以是: cwd ,字符串,子进程的当前工作目录env,对象 环境变量键值对encoding ,字符串,字符编码(默认: 'utf8')shell ,字符串,将要执行命令的 Shell(默认: 在 UNIX 中为/bin/sh, 在 Windows 中为cmd.exe, Shell 应当能识别 -c开关在 UNIX 中,或 /s /c 在 Windows 中。 在Windows 中,命令行解析应当能兼容cmd.

基于jQuery的在线商城设计与实现

哔哩哔哩视频视频 #1 网站需求分析 商城 1.1 主体说明 该网页包括了十一个页面,具体如下: Index.html(首页)、reg.html(注册页面)、login.html(登录页面)、about.html(关于页面)、info.html(提交订单信息)、member.html(个人信息)、message.html(留言页面)、payply.html(付款页面)、shopcar.html(购物车页面)、Product.html(商品列表页)、pwd.html(管理密码页面), 图1.1 网页HTML文件 网站中Css文件夹为网站的所有样式文件: 图1.2 网页样式目录 网站的总体结构如下图: 图1.3 网页目录 网站JS文件: 图1.4 网页javascript文件目录 网站图片文件(imgs、pic): 图1.5 网页图片文件 具体说明: 网页是通过HTML+CSS+jQuery来实现的一个在线购物商城网页,模拟出某宝某东等大型购物系统来实现一个简单的静态购物网页,里面包括了首页、登录、注册、购物车、关于页、留言页、修改密码、个人中心(可查看账户信息)、付款页、商品列表页、填写信息页等十一个模块,里面每个模块通过标签来一一链接,可以实现点击跳转到指定的页面了。 1.2 设计思路 该网页设计,是基于jQuery来实现的一个家乡在线商城购物网页,主要就是通过HTML来布局整个网页,通过CSS文件来渲染整个网页,达到一个视觉效果,加上jQuery的强大功能来模拟出后台效果。主页整体效果如图: 下拉菜单: 图1.6 下拉菜单 导航栏: 图1.7 导航栏 轮播图: 图1.8 轮播图 登录注册按钮: 图1.9 登录注册 产品列表: 图1.10 产品列表 关于页面链接: 图1.11 关于我们 其他功能页面在分页说明部分。 1.3 网站总体结构(流程图) 图1.12 网页总体流程图 2 站点地图说明(画出树形图) 图2.1 站点地图 3 使用技术及运行环境说明 使用技术:HTML+CSS+jQuery框架 集成环境:Visual Studio Code 运行环境:Windows 7 /10 (64位/32位) 或者 Linux系统 浏览器: Google、火狐、QQ浏览器、IE等 4 主页详细说明(含截图、部分代码) 4.

GameFramework框架

官网 Game Framework | 基于 Unity 引擎的游戏框架 介绍 对常用模块封装,规范开发过程,保证产品质量,内置19个模块。 组成 框架主要分两部分:GameFramework(简称GF),UnityGameFramework(简称UGF)。框架各模块主要实现在GF且完全不依赖unity。依赖unity的部分在UGF,具体逻辑实现如GameObject、AssetBundle、Editor。 目标 在项目中使用到GF大部分模块。 作者 ellan做事风格非常低调,属于实干派,几乎没有宣传过框架,但是多年持续维护更新,框架实际是提炼于知名的商业项目。虽然框架文档十分匮乏,新人上手相对困难,但是GF依然靠着过硬的代码质量吸引开发者使用和学习。 每个模块的xxxManager都会实现对应的IxxxManager接口,UGF只会直接引用接口,不会直接引用Manager GF层 框架中各个模块的具体实现 各个模块若需引擎传递参数,可通过UGF层的component在初始化时传入 如果需要调用依赖于引擎实现的接口,可以定义对应的IHelper接口并在UGF层实现接口,GF层只管调用不管具体实现 UGF层 实现框架中需要依赖unity的逻辑,把框架与引擎解耦 作为Game层与GF层之间的桥梁 实例化并初始化框架的各个模块 借助unity的editor扩展,实现各个模块的可视化配置 Game层 游戏逻辑,只与UGF层直接接触 我是看了B站沉寂轩梦的视频,只尝试了几个。 做完打了几个包链接:https://pan.baidu.com/s/1WmY5gza4rpWxVqaVoalsyQ?pwd=5t7r 第一课: 1替换源码操作 a(这样不行): 导入UGF,删掉dll,报错GF文件夹里的GameFrame文件夹拖到unity里,在里面新建一个Assembly Definition--GameFramework,应用不安全代码在UGF里找到Scripts里Runtime里的UnityGameFramework.Runtime,在里面指定好创建的,应用不安全代码在UGF里找到Scripts里Editor里的UnityGameFramework.Editor,在里面指定好创建的,应用不安全代码报错消失创建GF文件夹,把GF和UGF两部分放进去 b(这个可以): GameFramework:GameFramework.dll替换GF源码_gameframework替换dll_谢谢希望的博客-CSDN博客 2使用框架操作: 新建空物体GameEntry,把预制体GameFramework放到下面去创建Scripts文件夹,创建GameEntry.Init.cs脚本。把官网Game Framework | 基于 Unity 引擎的游戏框架第三章的GameEntry代码给他粘过来,(去掉.Init,加partial关键字),把命名空间Tutorial去掉在Scripts文件夹下,创建GameEntry.cs脚本。加partial关键字,在Start()方法里初始化GameEntry.Init.cs里的InitBuiltinComponents()方法找到GameEntry.cs脚本,点击Execution Order脚本排序,加上GameEntry.cs脚本脚本给他改成-108的顺序,Applyprocedure流程组件是游戏框架的核心,流程是贯穿游戏生命周期的有线状态机,通过流程能够对同一场景的不同逻辑进行解耦。在Scripts文件夹下,创建ProcedureStart.cs流程开始脚本继承ProcedurBase.cs脚本,using GameFramework.Procedure;既然ProcedureStart.cs继承ProcedureBase.cs,就重写ProcedureBase.cs生命周期方法,重写OnInit()方法 using GameFramework.Fsm;再执行一句话 Log.Debug("瑶瑶游戏开始啦"); using UnityGameFramework.Runtime;这时候Procedure组件下面就有了一个 □ ProcedureStart,给他勾选上。Entrance Procedure流程入口选择ProcedureStart然后运行他妈的就是不打印啊,他妈的就是不打印,换了版本他妈的也不打印 第二课: 3加载UI 在UI组件下创建canvas,然后把EventSystem放到画布下面,在画布下新建射线机,设置只渲染UI,颜色和-5 5 ,正交;修改模式指定相机新建一个panel名字改为UITestForm,在底下创建一个900*100大小的button,text改为切换流程,size50新建UI文件夹,把UITestForm做成预制体放到UI文件夹里,删掉Hierarchy视图里的就可以了UI组件下面游一个Instance Root实例根目录,把画布指定过来;UI groups 分组size先给1组,Name名字随便起一个Normal,Depth深度给一个10在Scripts文件夹下创建UITestFormLogic.cs脚本,继承UIFormLogic using UnityGameFramework.Runtime; private Button m_BtnChange;给按钮注册事件,然后打印Log.Debug("收到UI按钮"); 点击按钮之后打印的语句。ProcedureStart.cs脚本里 OnEnter()方法里执行语句:UIComponent ui = UnityGameFramework.

H5、jquery实现滚动加载下一页+瀑布流布局

效果如图: 需求描述:图片不固定高度,滑动到底部加载下一页数据。 瀑布流插件: 1、masonry.pkgd.js,官网地址 2、判断图片是否加载成功:imagesloaded.pkgd.js,官网地址,(坑:5.0.0的版本有问题,代码会报错) 加载下一页插件: dropload.js,githup上2.6+k的star html代码: <div class="floor3-con grid"> <!-- 瀑布流内容放这 --> </div> js代码: <script> var page = 0; // 当前页 var totalPage = 3 // 总页数 // 监听是否到底了 $('#floor3').dropload({ scrollArea : window, // 滚动区域 // distance : 200, threshold : 50, domDown : { // 自定义加载下一页样式 domClass : 'dropload-down', domRefresh : '<div class="dropload-refresh">↑上拉加载更多</div>', domLoad : '<div class="dropload-load"><span class="loading"></span>加载中...</div>', domNoData : '<div class="dropload-noData">没有更多数据啦~</div>' }, loadDownFn : function(me){ // 触底了的话会自动触发这个方法 if(page<totalPage) { page++; console.

远程桌面连接不上解决方法

远程桌面连接是一种方便快捷的技术,可以让用户在不同的设备之间共享桌面和访问远程计算机。然而,有时候我们可能会遇到远程桌面连接无法正常连接的问题。在本篇文章中,我们将详细介绍远程桌面连接无法连接的常见原因,并提供相对应的解决方法来解决这些问题。 1. 网络连接问题: 网络连接是远程桌面连接能否正常工作的关键。首先,确保本地计算机和远程计算机都连接到互联网。我们可以尝试通过打开网页浏览器访问互联网来验证网络连接是否正常。如果网络连接存在问题,可以尝试重新启动路由器或调整网络设置来解决问题。 2. 防火墙设置: 防火墙是保护计算机安全的重要组成部分,但是有时候它可能会阻止远程桌面连接的正常运行。我们可以尝试暂时关闭防火墙来确定是否是防火墙引起的问题。如果远程桌面连接可以正常工作,那么就可以修改防火墙设置,允许远程桌面连接通过防火墙。 3. 远程桌面设置: 远程桌面连接有一些设置选项,我们首先检查一下这些选项是否正确。 首先,我们要确保远程计算机有没有启用远程桌面功能。 右键点击"计算机"图标,选择"属性",然后点击"远程设置"来查看并启用远程桌面功能。此外,要确保远程计算机的用户名和密码设置正确,并且允许其他计算机通过远程桌面连接到它。 4. IP地址和端口: 在某些情况下,远程桌面连接无法连接是因为远程计算机的IP地址或端口设置不正确。您可以尝试使用命令提示符窗口来检查远程计算机的IP地址。 首先win+R打开命令提示符,输入cmd,在弹出的窗口中输入"ipconfig",然后查找远程计算机的IPv4地址。查找远程计算机的IP地址和端口号,然后正确输入。 5. 更新和修复: 有时候远程桌面连接无法连接是因为操作系统或远程桌面应用程序存在错误或缺陷。我们需要确保使用的操作系统和远程桌面应用程序是最新版本,并且已安装所有可用的更新和修补程序。 我们可以访问操作系统和远程桌面应用程序的官方网站来获取最新的更新和修补程序,并按照说明进行安装。这样可以修复可能导致连接问题的错误和漏洞。 6. 网络带宽: 远程桌面连接需要足够的网络带宽才能正常工作。如果您的网络带宽不足,可能会导致连接不稳定或无法连接。 我们可以尝试在连接时关闭其他带宽占用高的应用程序或设备,以提高远程桌面连接的性能。 7. 远程计算机状态: 确保远程计算机处于打开状态并且可供访问。如果远程计算机处于睡眠或待机状态,远程桌面连接可能无法正常连接。 我们可以尝试唤醒远程计算机或将其从待机模式切换到活动状态,然后再次尝试远程桌面连接。 8. 第三方软件冲突: 某些第三方软件与远程桌面连接冲突,可能导致连接无法正常工作。 如果您在远程计算机上安装了类似于防病毒软件、安全防护软件或VPN等应用程序,可以尝试禁用或卸载这些应用程序,然后重新尝试远程桌面连接。 9. 远程桌面连接工具: 如果以上的方法仍然无法解决连接问题,可以尝试使用其他远程桌面连接工具。除了Windows自带的远程桌面连接工具外,还有许多第三方工具可供选择,如RayLink等。这些工具可以简单快速的解决远程桌面连接问题。 通过仔细检查和尝试上述解决方法,您应该能够解决大多数远程桌面连接无法连接的问题。

qrcode.js 生成二维码

qrcode.js 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库。 安装: 通过 npm 安装:npm install --save qrcodejs2 方法: makeCode(text):设置二维码内容。clear():清除二维码。 容错级别:是指QR码被遮挡或残破时依然能被识别的几率,容错级别越高抗残破或遮挡的能力就越强,但同时,提高容错级别会增大点阵密度,识别速度随之降低。 分为四个等级: L(低):容错率为 7% M(中):容错率为 15% Q(较高):容错率为 25% H(高):容错率为 30% 假如在生成二维码时设定他的容错率为L,意味着生成的二维码最多有7%残破或遮挡以后仍可识别,但超过7%就无法识别了。 使用: // 在 Vue2 中实现: <template> <--存储二维码的DOM元素--> <div id="qrcode"></div> </template> <script> //引入qrcodejs2 import QRCode from 'qrcodejs2' export default { name: 'Test', mounted(){ this.init() }, methods:{ init(){ new QRCode(document.getElementById('qrcode'), { text: location.href, //要生成二维码的网址 width: 256, //图像宽度 height: 256, //图像高度 colorDark: '#000000', //前景色 colorLight: '#ffffff', //背景色 margin:0, //外边距 correctLevel: QRCode.

应用市场上架注意事项以及问题记录

注意事项 1.根据应用市场上架隐私政策,启动app之后需要弹窗显示隐私协议,用户点击确定之后才可以登录。 2.所有获取用户设备信息等需要用户同意隐私协议登录之后去获取(比如三方SDK初始化等都需要放在之后,不可以启动app没获取用户同意就初始化,因为三方初始化中很多都会获取用户的设备信息)。 3.关于隐私合规一项,每个应用市场都有文档声明,上线之前可以先查看下。 4.像接入三方SDK的时候,比如极光推送,分享,地图等,在SDK接入文档都会有对应上架市场需要处理的隐私合规方法,接入三方SDK时候切记注意这点。 问题记录(声明市场的可以忽略,只是当时遇到的记录,以下处理基本也适用其他市场) 1.(腾讯)按照审核拒绝提示,需要查询ICP备案记录截图,上传至上架时候应用信息基础信息中的版权证明处 如下截图示例 2.(vivo)根据提示,说应用中存在定向推送的功能,如果不存在此功能,那么隐私协议中关于定向之类的描述要删除(不明确隐私协议哪部分,联系应用市场平台客服,他们会告知) 如下截图示例 修改后如下 3.(小米)像下方这种,根据提示查看检测报告,看哪里有问题,像下图示例,他们并没有说明是需要添加隐私协议声明,一般会以为是代码逻辑问题(建议可以先找应用市场人工客服或者提工单确认) 如下截图示例 补充隐私协议声明如下 4.(华为)查看审核拒绝后提示信息,官方提示项目中使用了三方SDK,但是并没有声明,需要在隐私协议中补充声明 如下示例

前端(Vue)sha512加密、后端(Java)sha512加密后加盐实现完整流程

搜索时发现sha512加密(加盐)的内容很少 所以过来添一块砖 文章目录 写在前面一、理解一下SHA512加盐二、前端项目实现SHA512加密1.前端页面中引入js工具类2.调用CryptoJS.SHA512()方法进行加密 三、后端项目实现SHA512加密加盐1.创建加密工具类SHA512Utils.java2.调用工具类方法3.数据入库 写在结尾 写在前面 简单唠一会,别烦嗷! 遇见新的事物我们不妨先来认识一下它。它是什么,能做什么,如何实现,学习起来才能事半功倍。 一、理解一下SHA512加盐 是什么?sha512是密码加密的一种方式,加盐是为了多一层安全保障。密码加盐通俗点来讲就是在密码后面随机加上一个值(这个值随心所欲,可以是固定值、随机数、uuid……)。这个值就是盐(salt),加值的过程就叫加盐。能干什么?加密也好加盐也罢都是为了安全。如何实现?org.apache.commons.codec.digest.DigestUtils这个类里集成了多种加密方法其中也包含了本文的主角——sha512,在自己的项目中封装成工具类简直不要太好用! 二、前端项目实现SHA512加密 实现功能前梳理一下自己的实现思路,个人觉得是极好的!!! 前端对明文密码加密的过程是比较简单的 实现步骤: 前端页面中引入js工具类使用CryptoJS.SHA512() 方法进行加密 1.前端页面中引入js工具类 //npm安装环境 npm install crypto-js Tips:这里既可以终端手动输入命令,也可以鼠标悬浮自动导入的哈 //在需要使用加密方法的页面中引入CryptoJS import CryptoJS from "crypto-js" 2.调用CryptoJS.SHA512()方法进行加密 const Sha512Password = CryptoJS.SHA512(this.password) 这样传给服务端的密码就是sha512加密过的密文啦,具体如何使用还要结合自己的实际项目。 三、后端项目实现SHA512加密加盐 实现步骤: 创建工具类项目中调用加密方法加密数据入库,完毕。 1.创建加密工具类SHA512Utils.java 代码如下(示例): 项目中util包SHA512Utils.java文件下 Tips:代码中有注释可以参考辅读 package com.pay.util; import org.apache.commons.codec.digest.DigestUtils; import java.util.UUID; public class SHA512Utils { //SHA512加密 //创建SHA512对象 public static String SHA512(String code) { byte[] sha512Bytes = DigestUtils.sha512(code); //加密后的数据类型为byte[],这里将它转化为字符串类型 StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < sha512Bytes.

云发布的Docker部署文档

云发布的Docker部署文档 文章目录 云发布的Docker部署文档1、服务器安装 Docker2、修改后端微服务的配置2.1 修改 MySQL 的配置2.2 修改 Redis 的配置2.3 修改 Nacos 的配置 3、生成微服务镜像4、拉取远程镜像5、生成前端镜像5.1 准备文件5.2 构建前端镜像 6、基于镜像生成并运行容器6.1 MySQL6.2 Redis6.3 Nacos6.4 三个后端微服务和网关服务6.5 前端服务 7、最终镜像和容器情况展示7.1 镜像展示7.2 容器展示 8、安全组设置9、访问本系统10、附录 1、服务器安装 Docker 我在华为云服务器上选择的系统是 CentOS 7,因此使用 yum 安装Docker ,并拉取OpenJDK的镜像。使用的是root账户。 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum makecache fast sudo yum -y install docker-ce sudo service docker start docker pull openjdk:8 2、修改后端微服务的配置 2.1 修改 MySQL 的配置 原配置: url: jdbc:mysql://localhost:3306/tp_music?serverTimezone=Asia/Shanghai&useSSL=false 修改后的配置:

Requests-翻页请求实现

翻页请求实现 继https://blog.csdn.net/ssslq/article/details/130747686之后,本篇详述在获取了页面第一页之后,如何获取剩余页的标题内容。 网页:https://books.toscrape.com 找规律 同样还是进行页面的检查,切到网络一栏,找到头部对应的URL。 然后切到第二页,再去观察URL是否变化: 现在发现后面多了路径/catalogue/page-2.html,第二页对应了2.html,那么第一页是否是对应了1.html,试验一下: 发现使用了1.html之后返回到了首页,也就是第一页,现在大概明白了,每一页都可以使用X.html进行访问。这个页面总共有50页可以进行选择,既然第一页的书名已经进行了输出,那如果要访问50页,那就需要使用循环进行输出。 仅第一页代码 from bs4 import BeautifulSoup import requests headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" }#请求头改成自己的 url = "https://books.toscrape.com/catalogue/page-1.html" responce = requests.get(url,headers=headers).text soup = BeautifulSoup(responce,"html.parser") all_title = soup.findAll("h3") for i in all_title: title = i.find("a") print(title.string) 加循环后的代码 from bs4 import BeautifulSoup import requests headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.

CompletableFuture的正常,异常,timeout和cancel

背景 Java 8的CompletableFuture提供了强大的task管理能力,比如通知机制,以及更加简单抽象的task管理。 本文中,将用CompletableFuture的 supplyAsync() 方法来创建一个异步task,task会完成特定的工作,并且返回一个String。 下面的 handleResult() 方法作为task完成时的回调函数(注意:task完成并不意味着task的实际工作一定已经运行结束了,比如timeout和cancel场景)。 public static void handleResult(String result) { System.out.println("==========result: " + result + "==========="); } 一般来说,task的完成,有以下几种原因: 正常结束异常结束timeoutcancel 本文将以代码示例,如何处理task的不同完成状态。 注:本文中使用的有些方法(比如 completeOnTimeout() ),是Java 9提供的。 单独流程 正常流程 使用 thenAccept() 方法来处理task结果,代码如下: CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "hello"); future.thenAccept(e -> handleResult(e)); try { Thread.sleep(10* 1000); } catch (InterruptedException e) { e.printStackTrace(); } 注:在主线程里面sleep一段时间,其目的是确保task在主线程结束前完成工作。 运行结果如下: ==========result: hello=========== Process finished with exit code 0 异常流程 使用 exceptionally() 方法来处理task的异常,代码如下: CompletableFuture<String> future = CompletableFuture.

基于Ant Design Switch开关组件封装的开和关默认值为1和0的开关组件

背景 碰见一个业务需求需要使用开关组件,后端设置的默认值是1和0,但Ant Design官方Switch组件的默认值是布尔类型true或false,所以自己基于antd 的Switch组件封装一个默认值是1和0的开关组件。 下面是组件的代码和使用方法 组件代码 封装一个名为MySwitch的组件 import { useState } from 'react'; import { Switch } from 'antd'; export default function MySwitch({ onChange, ...restProps }) { const [switchValue, setSwitchValue] = useState(false); function handleSwitchChange(value) { const newValue = value setSwitchValue(newValue); if (onChange) { onChange(newValue ? 1 : 0); } } return ( <Switch {...restProps} onChange={(value) => handleSwitchChange(value)}></Switch > ); } 使用方法 下面展示一些 内联代码片。 //从你存放的地方引入MySwitch组件 import MySwitch from '@/components/MySwitch'; //在表单中使用MySwitch组件 <Form.

springboot学习(八十三) springboot中自定义某个对象的JSON序列化反序列化方式

文章目录 前言一、自定义注解二、自定义序列化处理三、自定义反序列化处理四、使用 前言 springboot可自定义JSON序列化和反序列化方式 一、自定义注解 @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using = CustomSerialize.class) @JsonDeserialize(using = CustomDeserialize.class) public @interface CustomStrFormatter { // todo 可以定义格式化方式 String pattern() default ""; } 二、自定义序列化处理 public class CustomSerialize extends JsonSerializer<String> implements ContextualSerializer { @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == null) { gen.writeNull(); } else { TypeReference<List<String>> typeReference = new TypeReference<>() {}; gen.writeObject(JsonUtils.fromJson(value, typeReference)); } } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { //判断beanProperty是不是空 if (property == null){ return prov.