数据结构——排序(2):选择排序+交换排序

目录 一、选择排序 (1)直接选择排序 ①思路 ②过程图示 ③代码实现 ④代码解释 ⑤优化 1.代码实现 2.过程图示 3.代码解释 4.注意 ⑥直接选择排序的复杂度 (2)堆排序 ①注意 ②代码实现 二、交换排序 (1)冒泡排序 ①思路 ②过程图示 ③代码实现 ④代码解释 ⑤复杂度 (2)快速排序 ①思路 ②主要框架 三、写在最后 一、选择排序 思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据排完。 (1)直接选择排序 ①思路 首先在元素集合中(i ~ n-1)选择出最大(或最小)的数据元素。若它不是这组元素中的最后一个(或第一个)元素,则将它与最后一个(或第一个)元素交换。然后在剩余的集合中(i ~ n-2 或 i+1 ~ n-1)重复上述步骤,直到集合中只剩下1个元素。 ②过程图示 我们以数组{2,3,9,6,5}为例: ③代码实现 void SelectSort(int* arr, int n) { for(int i = 0 ; i < n; i ++) { //先假设第一个元素为最小 int min = i; //找最小值 for(int j = i ; j < n; j ++) { if(arr[j] < arr[min]) { min = j; } } } //将最小值与无序区间的第一个元素交换 swap(&arr[i],&arr[min]); } ④代码解释 第一个for循环用来遍历数组所有数据,第二个for循环用来遍历后面的无序区间,找出最小值后将其放在无序区间的第一个位置。然后缩小无序区间之后重复循环。

(el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程

Ⅰ、Element-plus 提供的DatePicker日期选择器组件与想要目标情况的对比: 1、Element-plus 提供DatePicker组件情况: 其一、Element-ui 自提供的DatePicker代码情况为(示例的代码): // Element-plus 提供的组件代码: <template> <el-radio-group v-model="size" aria-label="size control"> <el-radio-button value="large">large</el-radio-button> <el-radio-button value="default">default</el-radio-button> <el-radio-button value="small">small</el-radio-button> </el-radio-group> <div class="demo-date-picker"> <div class="block"> <span class="demonstration">Default</span> <el-date-picker v-model="value1" type="date" placeholder="Pick a day" :size="size" /> </div> <div class="block"> <span class="demonstration">Picker with quick options</span> <el-date-picker v-model="value2" type="date" placeholder="Pick a day" :disabled-date="disabledDate" :shortcuts="shortcuts" :size="size" /> </div> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const size = ref<'default' | 'large' | 'small'>('default') const value1 = ref('') const value2 = ref('') const shortcuts = [ { text: 'Today', value: new Date(), }, { text: 'Yesterday', value: () => { const date = new Date() date.

ElementUI 事件回调函数传参技巧与自定义参数应用

ElementUI 事件回调函数传参技巧与自定义参数应用 在使用elementUI时,事件回调函数传递参数是一个常见的需求。根据搜索结果,我们可以了解到两种主要的方法来传递自定义参数: 使用回调函数:当elementUI组件触发事件时,我们可以通过回调函数传递自定义参数。例如,在el-input组件中,可以使用@change事件,并在回调函数中添加自定义参数。代码示例如下: <el-input v-model="input" placeholder="Please input" @change="(val)=>change(val, 'myId')"/> 在方法中,val是事件传递的默认参数,而'myId'是我们自定义的参数 。 使用$event:另一种方法是使用$event来传递事件对象,然后将其作为参数传递给自定义的方法。例如: <el-input v-model="input" placeholder="Please input" @change="change($event, 'myId')"/> 这里的$event等同于方法1中的val,而'myId'依然是自定义参数 。 对于表单校验,elementUI的自定义校验规则中,必须使用callback函数来返回校验结果。如果校验不通过,需要返回一个新的Error对象,如果通过,则调用callback函数而不带任何参数。每个校验分支都必须调用callback,否则表单校验可能不会按预期工作 。 此外,还有关于在@change等事件中传递多个参数的讨论,说明了可以使用箭头函数来包装回调函数,从而传递额外的参数 。 最后,值得注意的是,在Vue.js中,虽然事件通常用于组件间的通信,但在某些情况下使用回调可能更为合适,尤其是当我们希望确保父组件能够处理某个操作时 。 综上所述,elementUI的事件回调函数可以通过回调函数或$event来传递自定义参数,同时确保在自定义校验规则中正确使用callback函数。

【人工智能】AI时代程序员----是缔造AI程序员,还是AI缔造程序员?

是缔造AI程序员,还是AI缔造程序员? 前言 随着AIGC(如ChatGPT、MidJourney、Claude等)大语言模型的涌现,AI辅助编程工具日益普及,程序员的工作方式正在发生深刻变革。 ​ ChatGPT ​ Midjourney ​ Claude 随着一系列AI产品的兴起,我们也可以看到在各个不同领域AI正在逐渐取代一些职位和工作,而作为离AI最接近的程序员行业,我们应该做些什么来避免被AI所取代呢?我们又可以使用AI来提升自己的哪些能力呢? 以下是针对这个现实问题的一些处理方法。 具体措施 1. 专注于某个领域深耕细作 在AI时代,专注于某个领域深耕细作仍然是保持竞争力的重要途径。尽管AI可以处理大量的代码编写和调试工作,但它在特定领域的深度知识和经验积累方面尚无法与人类匹敌。作为程序员,我们最主要的是提升自己的“排他力”和“排它力”,只要提升自己的不可取代性和在专业领域的重要性,才不会被AI轻易所替代——你做的工作是无可比拟的,是无法被模仿的。 选择一个高需求的领域:如人工智能、数据科学、网络安全等。这些领域不仅技术前沿,而且需求量大。持续学习和更新知识:通过参加行业会议、阅读专业书籍和研究论文,保持对最新技术和趋势的了解。实战经验积累:通过参与实际项目,积累丰富的实战经验,提升问题解决能力。 我们看现在大公司的高级工程师或者是技术总监等职位是无法被AI替代的,也就是因为公司是不能失去他们的,他们发挥着独一无二的作用。 2. 广泛学习以适应快速变化的技术环境 在快速变化的技术环境中,具备广泛的知识面和灵活的适应能力同样重要。AI大模型不断在学习和扩展知识面,你有什么理由不去努力学习新的事物呢?这是一个跟人工智能比知识面的时代,你比它懂得更多,更全面,你就更可能战胜它。程序员可以通过以下方式实现广泛学习: 跨领域学习:除了本职工作相关的技能,还可以学习其他领域的知识,如产品管理、市场营销等,以拓宽视野。掌握多种编程语言和工具:学习不同的编程语言、框架和工具,提高解决不同问题的能力。关注前沿技术:保持对新兴技术的关注,如区块链、量子计算等,提前了解并掌握这些技术。 3. 发展AI无法轻易替代的软技能 虽然AI在编程方面有很大优势,但它难以替代一些软技能。软技能有时指的就是人类社会中某些“潜规则”或者是人际交往的独特性。毕竟人情世故人情世故,机器是冷漠的,人心是鲜活跳动的,提高软技能,创造更多人际关系,也是一个方法。 沟通能力:程序员需要与团队成员、客户和其他利益相关者进行有效沟通,以确保项目的顺利进行。人际关系:处理好与同事、上下司的关系。创造力:AI虽然擅长处理常规任务,但在创新和创造力方面仍然依赖于人类。程序员可以通过培养自己的创造力来设计出更具创新性的解决方案。批判性思维:程序员需要具备批判性思维能力,能够分析和评估AI生成的代码,确保其质量和安全性。 4. 结合AI工具提高工作效率 与其敬畏AI,不如直接同它合作,创造更大的可能性,提高工作效率;程序员可以将AI工具视为提高工作效率的助手,通过合理使用这些工具,提升自己的工作效率和生产力: 利用AI进行代码生成和优化:使用AI辅助编程工具,如GitHub Copilot,快速生成代码和优化现有代码。自动化重复性任务:将一些重复性、低价值的任务交给AI处理,腾出更多时间专注于核心任务。学习和使用AI调试工具:利用AI调试工具快速发现和解决代码中的问题,提高调试效率。 思考 首先,从技术角度来看,AI的快速进步确实给编程行业带来了前所未有的效率提升。AI辅助工具在代码生成、调试、优化等方面展现出了强大的能力,能够帮助程序员快速完成重复性、低复杂度的任务。这意味着程序员不再需要花费大量时间在基础代码编写和问题排查上,而是可以将精力集中在更具创造性和挑战性的任务上。例如,AI可以帮助初级程序员迅速完成基本功能的实现,而高级程序员则可以利用这些工具来进行复杂系统的架构设计和性能优化。 然而,正因为AI的介入,程序员的角色和职责也在发生变化。简单、重复的工作被AI替代的可能性越来越大,因此,程序员需要重新审视自己的职业定位。未来的编程工作将更加偏向于解决复杂问题、开发创新性解决方案,以及进行AI模型的训练和调优。在这一背景下,程序员的学习重点需要从简单的编程语言和工具的掌握,转向更高层次的系统设计、算法优化和跨领域的综合能力。 那么,程序员应该专注于某个领域深耕细作,还是广泛学习以适应快速变化的技术环境呢? 实际上,这两者并非互斥,而是需要动态平衡。程序员应首先在某个领域(如算法、系统架构、数据科学等)建立深厚的专业知识,成为领域内的专家,以应对特定复杂问题的挑战。然而,考虑到技术更新迭代的速度以及跨领域知识融合的趋势,程序员也需要保持开放的心态,不断学习新技术、新工具,扩展自己的知识边界。这样可以在需要时迅速适应新的工作环境和技术需求,避免被快速发展的技术潮流所淘汰。 AI虽然可以处理大量信息并生成代码,但它无法轻易替代人类的创造力、团队协作能力、沟通技巧和项目管理经验。特别是在复杂项目中,如何协调团队、与客户沟通需求、合理分配资源等,都是AI难以替代的领域。因此,未来的程序员不仅要具备深厚的技术能力,还要注重培养这些AI无法替代的软技能,成为更全面的科技人才。 展望 当我们展望未来,随着AI技术的进一步成熟,程序员的工作将更加偏向于与AI协同合作,而不是单纯的技术执行者。这意味着程序员在未来需要具备更高的“AI素养”,理解和利用AI的能力。我们可以期待,一个“人机共创”的时代正在来临,程序员将与AI工具紧密合作,共同推动技术的进步和创新。这种协作模式不仅不会削弱程序员的价值,反而会赋予他们更大的创造力和生产力。 总而言之,程序员在面对AI技术的变革时,应当以开放的心态迎接挑战,并通过不断学习和自我提升,找到自己的独特定位。在深耕技术领域的同时,也要注重软技能的培养,以适应未来复杂多变的技术环境。在人机协作的新时代,程序员将迎来更多的发展机遇,也将承担更多的创新责任。 请记住,我们应该使用AI来缔造新时代的程序员,而不是主要为了缔造新时代的AI程序员。

python-flask-上传多个文件并存储

本地环境:win10 / centos6 , python3 flask入门看这里: ↓ python-flask结合bootstrap实现网页小工具实例-半小时速通版_bootstrap flask-CSDN博客 https://blog.csdn.net/pxy7896/article/details/137854455 动态添加和删除表格中的行,看这里: ↓ javascript-动态增加和删除表格的行-CSDN博客 https://blog.csdn.net/pxy7896/article/details/141030235 问题描述 在前台上传1~N个文件,后台接收并存储。 实现效果 点击“添加峰图”按钮,可以不断加行: 实际的html内容类似: 后台则需要接收这些附件(前一个input也要)。 解决方案 在前台构建一个form,在里面放一个table,然后在列中增加文件上传按钮,如下所示: <form action="run_command_ab1" id="main_form" > <div id="suborderlist" class="row col-md-12"> <table> <!-- 略去一些内容 --> <!-- 这是编号 --> <td name="rowIdx" style="width:10%;"></td> <td style="width:40%;"> <input name="attach" type="file" id="customFile"> </td> </table> </form> 提交按钮的id是submitButton,加上点击操作: $("#submitButton").click(function () { // 构造数据 var formData = new FormData(); var attachList = document.getElementsByName("rowIdx"); for (var x=0; x<attachList.length; x++) { // 接收前面input的细节,略 // 拼接一下文件的id var idx = "

XXXForm组件

效果展示 代码 XXXForm <template> <div class="search-container"> <el-form ref="formRef" class="form_is_hidden" :model="form" v-bind="formAttrs"> <el-row :gutter="20" class="search-row"> <el-col v-for="item in shows.columns" :key="item.inputType + JSON.stringify(item.values)" :span="item.span || 6" > <el-form-item v-bind="item.formItemAttrs || {}"> <FormItem v-if="typeof item.values == 'string'" v-bind="item.inputAttrs || {}" v-model="form[item.values]" :input-type="item.inputType" /> <FormItem v-else v-model:one="form[item.values[0]]" v-model:two="form[item.values[1]]" :input-type="item.inputType" v-bind="item.inputAttrs || {}" /> </el-form-item> </el-col> <el-col :span="shows.btnsSpan" class="search-btn-container"> <el-form-item class="search-btn" label="1" label-width="0"> <el-tooltip v-if="shows.collapsedBtn" :content="collapsed ? '收起' : '展开'" placement="top" trigger="hover" > <el-button class="

【Android Studio】gradle文件、配置、版本下载、国内源(SDK版本、gradle版本以及gradle-plugin(AGP)版本)

文章目录 AS查看gradle-plugin版本及gradle版本(图形)查看gradle-plugin版本及gradle版本(配置文件)配置文件分析解决gradle下载失败、版本错乱等问题。 Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的自动化构建工具,它使用一种基于 Groovy 的特定领域语言(DSL)来声明项目设置,而不是传统的 XML。Gradle 提供了更灵活和强大的方式来构建、测试、打包和部署应用程序,它支持多种编程语言和平台,包括 Java、Kotlin、Groovy、Android、C/C++ 等。 Gradle 的优势 灵活性:Gradle 允许你以编程方式定义构建逻辑,这提供了比传统 XML 配置更高的灵活性。性能:Gradle 使用守护进程和增量构建来加速构建过程。多项目构建:Gradle 支持在一个构建脚本中定义多个项目,并允许你跨项目共享配置和依赖项。强大的依赖管理:Gradle 提供了灵活的依赖管理机制,支持从 Maven 仓库、Ivy 仓库和其他类型的仓库中解析依赖项。社区支持:Gradle 有一个活跃的社区,提供了大量的插件和文档资源。 AS查看gradle-plugin版本及gradle版本(图形) 查看gradle-plugin版本及gradle版本(配置文件) 进入项目级bulid.gradle(不是app级) gradle\wrapper\gradle-wrapper.properties 配置文件分析 gradle-plugin 这里主要解决第一次构建项目时可能出现的问题,不考虑具体项目配置,涉及到的配置文件就上图两个。 项目级build.gradle:项目全局的gradle构建脚本(下面是uniapp 安卓SDK实例) (注意不要找到app文件夹里的那个了) // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { maven {url 'https://maven.aliyun.com/repository/google'} maven {url 'https://maven.aliyun.com/repository/gradle-plugin'} maven {url 'https://maven.aliyun.com/repository/public'} } dependencies { classpath 'com.

【L1.第二章】如何搭建 Appium 环境与配置

Python+Appium+Pytest 自动化测试教程 Appium 所需环境下载与安装JDK 介绍与下载Android SDK 介绍与下载Node.js 介绍与下载Appium 服务端Appium Inspector 介绍与下载Python3 介绍与下载Appium 客户端环境移动设备平台工具 Android Studio 安装 Android SDK 与环境配置Android 配置环境变量Windows 配置 Android 环境MacOS 配置 Android 环境 Android 验证环境是否成功 Node.js 安装与环境配置Window 环境安装 Node.jsMac OS 环境安装 Node.jsNode.js 验证环境是否成功 Appium 服务端安装与配置安装 Appium ServerGUI 版本使用 npm 安装 Appium Server 命令版Appium Server 命令版安装驱动 Appium Inspector 安装与配置GUI 版本配置Web 版本配置 移动设备平台工具下载 Appium 所需环境下载与安装 JDK 介绍与下载 点击官方下载 在 Appium 中,UiAutomator2 通过 Java 编写与 Android 应用程序进行交互,因此需要配置 JDK 环境。可以参考安装教程贴进行安装。

【wiki知识库】08.添加用户登录功能--后端SpringBoot部分

目录 一、今日目标 二、SpringBoot后端实现 2.1 新增UserLoginParam 2.2 修改UserController 2.3 UserServiceImpl代码 2.4 创建用户上下文工具类 2.5 通过token校验用户(重要) 2.6 创建WebMvcConfig 2.7 用户权限校验拦截器 一、今日目标 上篇文章链接:【wiki知识库】08.添加用户登录功能--前端Vue部分修改-CSDN博客 这篇文章主要是实现一下用户登录功能的后端部分,登录功能需要使用redis,不懂redis可以看我之前的一篇文章。 Redis文章链接:【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)_springboot 限流 redis-CSDN博客 那么为什么要用到Redis呢? 这个问题关系到整个系统的用户校验,当我们登录成功的时候,后端会生成一个用于用户校验的token值,然后把这个值传给前端,每次用户请求后端的时候都要带上这个token值,这个token的值当中记录了当前登录的用户是谁,还有过期时间等信息,这样子就可以防止那些没有登陆的用户去直接访问我们的后端调用接口。所以这个token还是需要妥善保管的,一旦token丢失别人就可能用你的token去发送请求,修改你的数据。 二、SpringBoot后端实现 2.1 新增UserLoginParam 这里也做了校验,其实这个事情完全可以放到前端实现,但是也要考虑到有直接调用接口的情况,这时也要给出错误提示。 @Data public class UserLoginParam { @NotEmpty(message = "【用户名】不能为空") private String loginName; @NotEmpty(message = "【密码】不能为空") @Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$", message = "【密码】规则不正确") private String password; } 2.2 修改UserController 直接上代码吧。这里拿到了用户的账号和用户的密码,然后判断加密后的密码和数据库中取出来的用户密码是否相同,如果相同那么就可以登陆。登陆后通过工具类生成一个不会重复的Long类型的值作为该用户的token,然后以token为key,登录用户创建的对象作为值,保存到redis当中,以便于后续用户访问接口时,通过用户token来判断是哪个用户访问接口。 @PostMapping("/login") public CommonResp login(@Valid @RequestBody UserLoginParam req) { req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); System.out.println(req); UserLoginVo userLoginResp = userService.

一篇文章搞懂Cookie, sessionStorage 和 localStorage

#前端实习 主要是最近在实习,想趁着这个机会多记录一下自己没注意,或者是遗漏的知识点。这回主要写的是Cookie,sessionStorage还有localStorage的相关内容,去网上查找了下别的大神写的文章然后还有自己合并总结了一下,主要是自己记录一下这个实习过程,还有方便自己之后的回顾。 具体描述: 在进行网页开发的过程中,我们有时候会需要把一些数据存储在客户端(浏览器)。在存资料到浏览器的方式中,最常用到的就是cookie和localStorrage 和sessionStorage,这三者都可以用来存储数据,但是有着不同的使用情况和限制。 三者概念描述: 一、Cookie 什么是Cookie? Cookie是Web服务器生成并且发送至Web服务器的小型信息文件。Web浏览器在预定义的时间段内或在用户在网站上的会话期间存储收到的Cookie。他们将相关的Cookie附加到用户今后向Web服务器提出的任何请求中 Cookie帮助网站了解用户的情况,使网站能够提供个性化的用户体验。例如,一些电子商务网站使用Cookie来了解用户在其购物车中放了什么东西。然后cookie还可以用于维护安全,比如Cookie身份验证 在互联网上使用的Cookie也称之为”HTTP Cookie”,是通过HTTP协议发送的 Cookie的种类 会话Cookie 会话Cookie帮助网站追踪用户的会话,会话Cookie在用户的会话结束后(退出网站上的账户或退出网站时)被删除,会话Cookie没有到期日期,这向浏览器标明。他们应该在会话结束时立即被删除 持久性Cookie 与会话Cookie不同,持久性Cookie在用户的浏览器最终保持预定的时间长度,可能是一天、一周、几个月、甚至几年。持久性Cookie总是包含一个到期的日期 身份验证Cookie 身份验证Cookie有助于管理用户会话;当前用户通过浏览器登录账户时,就会生成身份验证Cookie。他们通过账户信息与Cookie标识符字符串联系起来,确保敏感信息的被传递给正确的用户会话。 追踪Cookie 追踪Cookie由追踪服务产生,他们用于记录用户的活动,浏览器在下次加载使用该追踪服务的网站时,将该记录发送给相关的追踪服务。 僵尸Cookie 字如其名,僵尸Cookie在被删除后会重新生成。僵尸Cookie在浏览器的典型Cookie存储位置之外还创建自己备份版本,它们使用这写备份在被删除后重新出现的浏览器中。僵尸Cookie有时会被不道德的广告网站利用,甚至被网络攻击者使用。 二、localStorage localStorage是一种Web存储技术,允许用户在浏览器中以键值对的形式存储数据。 特点: 1.永久存储: 只要不删代码,不干什么别的,localStorage的数据是一直存在的,不会因为浏览器关闭等原因会清楚。 2.localStorage会将第一次请求的数据直接存储到本地,这个相当于一个5M大小的前端数据库 3.存储方式:采用key、value的键值对的方式,value的值必须是字符串类型 4.全局的公共对象: 在所有的同源窗口中都是共享的 局限性: 1.因为浏览器的原因,localStorage的存储大小是不同意i的,而且只有IE8版本以上的浏览器才支持这个属性。 2.localStorage在隐私模式下是不可读取的 3.localStorage本质上是对字符串的读取,如果存储内容过多会造成页面卡顿。 4.localStorage无法被爬虫获取 llocalStorage是一个全局对象,提供了一下方法来操作存储的数据: setItem(key , value): 将一个键值对存储到localStorage中。key和value都必须是字符串GetItem(key): 根据key从localStorage中获取存储的值。如果key不存在,则返回null。RemoveItem(key): 根据key从localStoreage中存储的值Clear(): 清楚localStorage存中的所有数据 简单示例: // localStorage 存入数据 // 存储数据 localStorage.setItem('username', 'Alice'); // 获取数据 const username = localStorage.getItem('username'); console.log(username); // 输出:Alice // 删除数据 localStorage.removeItem('username'); // 检查数据是否已被删除 console.log(localStorage.getItem('username')); // 输出:null // 清除所有数据 localStorage.

学生信息管理系统(Python+PySimpleGUI+MySQL)

吐槽一下 经过一段时间学习pymysql的经历,我深刻的体会到了pymysql的不靠谱之处; 就是在使用int型传参,我写的sql语句中格式化%d了之后,我在要传入的数据传递的每一步的去强制转换了,但是他还是会报错,说我的传入参数是string,他要int,我真笑了,最后把%d换成%s结果可以了,,,然后经过我查资料才了解到pymysql他这个库会去自动匹配类型,那也就是说在使用过程中可以对数据类型的关注可以降低一点,让库来给我解决数据类型不匹配的问题。 好了,吐槽就完了,然后就是现在的代码以及内容展示了 可视化展示 不足之处 1.弹窗过多,看多了会烦 2.界面设置大小不够合理 3.图片元素设置不够合理 4.查询的操作可以使用控件Table展示一个表格,懒的做了 登录 在这里会去获取mysql中数据库db1的表user中的数据,然后会进行判断,成立下一步,不成立,会弹出弹窗,进行警告,成立就进入菜单 然后点击左上角的”点击进行操作吧“下面的按钮是假的哈哈哈哈哈哈哈哈哈。 编辑操作 这里删除之后需要关闭系统,可能是因为我这里有缓存的原因 查询操作 在这里去查询所有信息就会返回如图弹窗 按学号查询 按姓名查询 按性别查询 按年龄查询 按专业查询 别问我为什么不在这里去做个选择菜单,那就和性别一样了,懒得再进行加工了 按照班级查询 代码 可提高之处 1.pymysql的使用中游标和数据库的未关闭造成的资源浪费,在进行sql语句的执行时,execute执行之后提交事务,然后关闭游标,关闭数据库的连接 2.json文件的多次读取,造成了性能的浪费。使用类属性,然后使用静态方法判断属性是否为空,空则读取json文件内容,非空则继续读取,之后再进行连接。 3.for循环的不当使用,因为数据库的表中字段并不多,所以我去遍历的行为可以,当字段多了就会对性能造成极大浪费,不过字段毕竟就设置了几个。 main文件 from GUI import GUI if __name__ == '__main__': gui = GUI() gui.get_in() GUI文件 import PySimpleGUI as sg from LoginDatabase import LoginDatabase from Editor import Editor from Find import Find sg.theme('BlueMono') class GUI(object): def __init__(self): self.db_login_conn = LoginDatabase() self.db_login = self.

java 单元测试学习

单测的标准: 语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都要达到100%。 — 《阿里巴巴Java开发手册》 单测覆盖度分级参考 Level1:正常流程可用,即一个函数在输入正确的参数时,会有正确的输出 Level2:异常流程可抛出逻辑异常,即输入参数有误时,不能抛出系统异常,而是用自己定义的逻辑异常通知上层调用代码其错误之处 Level3:极端情况和边界数据可用,对输入参数的边界情况也要单独测试,确保输出是正确有效的 Level4:所有分支、循环的逻辑走通,不能有任何流程是测试不到的 Level5:输出数据的所有字段验证,对有复杂数据结构的输出,确保每个字段都是正确的 60%左右的单测覆盖率可以非常轻松达到,但达到95%以上的覆盖率,需要覆盖各种代码分支和异常情况等,甚至是配置和bean的初始化方法,所投入的时间非常巨大,但边际效应递减。我想测试toString, getter/setter这样的方法也没有意义。多少合适,我认为没有一个固定的标准。高代码覆盖率百分比不表示成功,也不意味着高代码质量。该舍弃测试的部分就大胆的ignore掉。 1、隐藏的测试边界值 2、不要在springboot测试中使用@Transactional以及操作真实数据库 3、单测里时间相关的内容 笔者曾经在工作中遇到过一个极端case,一个CI平时都正常运行,有一次深夜发布, CI跑不过,后来经过第二天check才发现有前人在单测中取了当前时间,在业务逻辑中含有夜间逻辑(夜间消息不发),导致了CI无法通过。那么时间在单测中要如何处理呢? 在使用Mockito时,可以使用mock(Date.class)来模拟日期对象,然后使用when(date.getTime()).thenReturn(time)来设置日期对象的时间。 如果你使用了calendar.getInstance(),如何获取当前时间?Calendar.getInstance()是static方法,无法通过Mockito进行mock。需要引入powerMock,或者升级到mockito 4.x才能支持: final类,static类等的单元测试 如第3点提到的calendar的例子,static类的mock需要mockito4.x的版本。否则就要引入powermock,powermock不兼容mockito3.x版本,不兼容mockito 4.x版本。由于老的应用引入了非常多的mockito3.x的版本,直接使用mockito4.x对final和static类进行mock需要排包。实践中看,JUnit、Mockito、Powermock三者之间的版本号有兼容性问题,可能会出现java.lang.NoSuchMethodError,需要根据实际的情况选择版本进行mock。 但是在新项目立项的时候,要确定好使用的mockito和junit版本,是否引入powermock等框架,确保环境稳定可用。老项目建议不要大规模改动mockito和powermock的版本,容易排包排到怀疑人生。 总结一下什么时候使用容器: // 1. 使用PowerMockRunner @RunWith(PowerMockRunner.class) // 2.使用PandoraBootRunner, 启动pandora,使用tair,metaq等 @RunWith(PandoraBootRunner.class) // 3. springboot启动,加入context上下文,可以直接获取bean @SpringBootTest(classes = {TestApplication.class}) 不要为了覆盖率测没意义的代码 比如toString,比如getter,setter,都是机器生成的代码,单测没意义。如果是为了整体测试覆盖率的提高,那么请在CI中排掉这部分包: 如何测试void方法 如果void方法内部造成了数据库的变更,比如insertPlan(Plan plan),并通过H2操作过数据库,那么可以验证数据库的条数变化等,校验void方法的正确性。 如果void方法调用了函数,可以通过verify验证方法得到调用次数: userService.updateName(1L,“qiushuo”); verify(mockedUserRepository, times(1)).updateName(1L,“qiushuo”); 如果void方法可能会造成抛出异常。 可以通过dothrow来 mock方法抛出的异常: @Test(expected = InvalidParamException.class) public void testUpdateNameThrowExceptionWhenIdNull() { doThrow(new InvalidParamException()) .when(mockedUserRepository).updateName(null,anyString(); userService.updateName(null,“qiushuo”); } 使用 squaretest testme junit5 + Mockito IDEA 安装 squaretest testme 插件

【算法/题目】:递归、搜索训练

✨ 吾与春风皆过客,君携春水揽星河 🌏 📃个人主页:island1314 🔥个人专栏:算法训练 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 目录 1. 找出所有子集的异或总和再求和 2. N皇后 3. 有效的数独 4、解数独 5、单词搜索 6、黄金矿工 7、不同路径III 1. 找出所有子集的异或总和再求和 思路: 假设存在[1,2,3]这个集合,那么开始的时候是空集合,画出其决策树 全局变量:sum和path sum用于求异或和,path用来当进入某一层时,异或该数, 方法dfs : dfs(nums[],pos) 在pos那层 回溯:异或运算:消消乐(相同的数异或为0) AC代码如下: int path, sum; void dfs(vector<int>& nums, int pos) { sum += path; for (int i = pos; i < nums.size(); i++) { path ^= nums[i]; dfs(nums, i + 1); path ^= nums[i]; //恢复现场 } } int subsetXORSum(vector<int>& nums) { dfs(nums, 0); return sum; } 2.

docker上传镜像至阿里云

1、安装wsl2 WSL2安装(详细过程) 2、安装docker Docker在Windows下的安装及使用 3、创建私人阿里云镜像库 如何创建私人阿里云镜像仓库?(保姆级) 4、如何删除容器 (1) 查找正在使用该图像的容器 docker ps -a --filter ancestor=compete:v1 (2) 停止正在运行的容器 docker stop <container-id> (3) 删除容器 docker rm <container-id> (4) 再次尝试删除图像 docker rmi compete:v1

出行365:依托分布式数据库,让出行无忧 | OceanBase案例

*本文首发自“新华社·环球”杂志,作者张海鑫 每年的暑期旅游旺季,都会触发一轮轮的文旅消费的热潮,对于互联网出行服务行业而言,这既是一场盛大的狂欢,也是对其综合实力的严峻考验。 然而,自去年暑假起,出行365的副总裁兼首席技术官,张劲涛先生,心态已经从容了很多。“有了原生分布式数据库——OceanBase 之后,我们对平台的业务支撑能力是越来越有信心了。” 一、翻天覆地的十年 回溯至十数年前,节假日期间最令人困扰的莫过于购票难题,汽车站、代售点随处可见的排队长龙,有人为了买到一张票甚至要排上一个通宵。最绝望的是,好不容易排到了,却发现已经没票了,于是精心计划了很久的行程又不得不临时更改。 这样的场景,曾经是很多国人的共同记忆,不过互联网科技已经为这样的时代烦恼画上了句号。如今,临行前打开出行 365,输入出发地和目的地,选择出行日期,汽车票、城际巴士、火车票等票务信息便一目了然的出现在了手机屏幕上。如今的日常是十几年前的人们很难想象的。 十年前,张劲涛进入出行 365 这个初创企业之时,人们还并没有养成预约出行的习惯,培养市场和人们消费习惯的养成是一个相当漫长的过程,不仅考验着企业的耐力和资金能力,也考验着从业者们的定力。如今,张劲涛已经在互联网出行行业摸爬滚打了十年之久,出行 365 也已经成为在线汽车票务运营服务商排名第一、定制客运网络平台运营商排名第一的品牌。 出行行业比较特殊,不仅平日里需要 24 小时在线服务,每逢节假日才是真正的硬仗。“每到节假日人们集中出行之时,我们都会高度紧张,要为涌入平台的流量做好各种备案,确保大家的出行体验万无一失。”张劲涛说,“尤其是十一黄金周,我们要提前 40 多天就开始编写应急预案,列出一张可能出现的问题清单,针对每种问题还要进行应急演练。” “特别是 2023 年,随着国内旅游市场迅速回暖,从业务量上来看,五一期间就出现了往年十一那种业务量的陡然上升。人们的旅游方式也在不断翻新,我们的定制客运业务量每个月创一个新高,接送服务的增长量也翻了好几倍。”张劲涛说。 十年,张劲涛早已习惯了这样的生活,十年,国人的出行方式也已经发生了翻天覆地的改变。当互联网出行成为一种生活方式,大量的新增数据处理、历史数据的查询、实时的高并发,也给出行 365 带了新的挑战。 二、寻找“互联网皇冠上的明珠” 出行 365 每日交易量最高达到百万笔,而且是读写同时的,用以呈现各种业务的班次量更是达到上亿的规模,而在更新频次上,每秒可能更新上万行。随着出行 365 的业务量增长,给数据库带来了很大压力,Oracle 这种单库数据库的局限性逐渐显露出来。 “如果说航空发动机是‘工业皇冠上的明珠’,那么数据库则可以类比为‘互联网皇冠上的明珠’。因为互联网行业应用层面的很多东西都可以追溯到数据库,可以说数据库的高度就决定了你业务的高度和技术的高度。”张劲涛告诉记者,这么多年来出行 365 技术团队做的很多工作实际上都是为了弥补数据库的局限,但还有很多想实现的服务迟迟无法拓展。 比如清分结算系统,“这是我们用于和供应商、分销商进行结算的系统。由于各个业务系统的数据全部都会集中到这个系统中,不仅数据量很大,还需要按业务进行各种维度的分析,而且常常是跨周期、跨纬度的分析,同时还要求实时的写入和聚合计算。针对一个供应商的一次计算就可能涉及上百万条的聚合数据,一旦数据量大了,聚合运算就变得非常非常慢,计算的压力非常大。所以很多时候,我们都要等业务量不大时才能运行。”张劲涛说。 为了解决这些问题,出行 365 曾设想过用数据仓库、数据库中间件 MyCat 等多种方案,但均效果不佳,选用新的数据库似乎成了不二之选。特别是 2022 年,公司决定对所有部署到用户的系统进行整合,将众多分散的小系统整合为一个大系统,意味着这个数据库需要承载非常大的数据量,并采用集中的 SaaS 模式为用户统一提供服务。不管是从成本的考虑还是数据量的考虑,Oracle 都已经无法满足发展需求。 但数据库迁移并非易事。“首先,它要能在语法上跟 Oracle 能够兼容,否则改动的工作量会很大,其次在性能上要能很好支持海量数据的复杂聚合计算需求,而且在事务支持上不打折扣。”从 2021 年开始,张劲涛很多功夫都花在了数据库的遴选上,但尝试了国内外很多数据库产品后仍未找到合适的。就在张劲涛惆怅不已之时,OceanBase 出现了。 通过测试后他惊讶地发现,一个 OceanBase 数据库就能同时满足上述两个需求。“在出行 365 评估的所有数据库中,OceanBase 是与 Oracle 兼容度最好的。而且在性能比对上,Oracle 和 OceanBase 没有明显差异,在某些场景 OceanBase 可能表现还更好一些。”张劲涛说,“此外,进行迁移测试时 OceanBase 也是最平滑的。而且还有完整的迁移方案,让我们非常容易地完成了数据库迁移,整个迁移过程不到 2 个小时。” 三、站在数据库的肩膀上,轻松“远足” 2022 年下半年,出行 365 完成清分结算、云车站等数套系统的数据库升级之后,2023 年便迎来了旅游市场的一路“狂飙”,让张劲涛很满意的是,尽管面对流量的暴增,系统依然运行非常平稳。

【django升级】django从2.2.6版本升级到3.2.25

一、背景 因为漏洞问题,客户要求把django从2.2.6版本升级到3.2.25版本,在此记录此次升级遇到的问题 二、问题 1.依赖包问题 依赖包变更 Djanog==2.2.6>>>3.2.25 redis==3.2.0>>>4.3.6 django-redis==5.4.0 #新增 whitenoise==3.3.0>>5.3.0 问题1: django.core.cache.backends.base.InvalidCacheBackendError: Could not find backend 'django_redis.cache.RedisCache': cannot import name 'python_2_unicode_compatible' 解决措施: 升级redis4.3.6安装 django-redis5.4.0 2.配置文件 问题1: approval_mgmt.ApprovalDocument: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'. HINT: Configure the DEFAULT_AUTO_FIELD setting or the ApprovalMgmtConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'. 这个警告是 Django 3.2 引入的一个新提示,用于提醒开发者明确设置默认的自动字段类型。你可以通过以下步骤来解决这个问题: 在项目设置中配置 DEFAULT_AUTO_FIELD 在你的 Django 项目的 settings.

【C++深度探索】红黑树实现Set与Map的封装

🔥 个人主页:大耳朵土土垚 🔥 所属专栏:C++从入门至进阶 这里将会不定期更新有关C/C++的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目录 前言1. 修改红黑树2. 迭代器✨const迭代器 3. map的[]访问4. set和map封装✨修改后的红黑树✨map类✨set类 5. 结语 前言 前面我们学习过map、set、multimap、multiset的使用,这四种容器都是使用红黑树作为其底层结构。红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O( l o g 2 N log_2 N log2​N),但是红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对AVL树而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多。 今天我们就可以利用之前实现过的红黑树来对C++STL库中的set和map进行模拟实现。 1. 修改红黑树 我们之前模拟实现过红黑树,插入的节点是键值对pair类型,而如果要使用红黑树来对set和map封装的话,set存储的应该是单个值,而不是键值对,所以我们就需要对红黑树进行修改,使得set和map都能使用: 首先红黑树存储节点的类需要从只能存储键值对改为能够存储任意数据: template<class T> struct RBTreeNode { T _data; //存放数据,不再只能存放键值对:pair<K, V> _kv; RBTreeNode<T>* _left; RBTreeNode<T>* _right; RBTreeNode<T>* _parent; Colour _col; //保存颜色 RBTreeNode(const T& data) :_data(data) , _left(nullptr) , _right(nullptr) , _parent(nullptr) , _col(RED) {} }; 相应的,红黑树的模板参数也需要修改: 修改前: //红黑树类 template<class K, class V> class RBTree { public: typedef RBTreeNode<K, V> Node; Node* Find(const K& key);//查找函数 private: Node* _pHead = nullptr; }; 因为节点类只有一个模板参数了,所以红黑树两个模板参数有点多余,但是如果将红黑树的模板参数也改为一个,如下面代码所示:

程序员如何在人工智能时代保持核心竞争力

目录 1.概述 1.1. 技术深度与广度的平衡 1.2. 软技能的培养 1.3. 持续学习和适应性 1.4. 理解和应用AI 1.5. 伦理和责任意识 2.AI辅助编程对程序员工作的影响 2.1.AI工具对编码实践的积极影响 2.2.AI工具的潜在风险 2.3.如何平衡利与弊 3.程序员应重点发展的核心能力 3.1. 复杂系统设计能力 3.2. 跨学科知识整合能力 3.3. 与AI协作的能力 3.4. 持续学习和适应新技术的能力 3.5. 伦理和社会影响考量能力 4.人机协作模式下的职业发展规划 4.1. 持续学习的重要性 4.2. 如何选择适合自己的专业方向 4.3. 策略 4.4. 使用AI工具的平衡 5.总结 1.概述 随着AI辅助编程工具的普及,程序员确实面临着职业环境和技术需求的快速变化。在这样的背景下,程序员应该如何调整自己的学习和发展策略,以保持和提升自己的核心竞争力成为了一个值得探讨的问题。我们从以下方面来讨论。 1.1. 技术深度与广度的平衡 专注深耕:选择一个领域深入研究,如机器学习、云计算或数据科学,可以让程序员在该领域内成为专家,从而在市场上获得更多的机会。技术多元化:同时,拥抱AI带来的新技术和工具也非常关键。学习如何利用这些工具来优化和简化工作流程,可以使程序员工作更加高效。 1.2. 软技能的培养 AI难以完全替代的领域包括创造力、同理心、领导力、团队合作和复杂决策等软技能。程序员应致力于提高这些技能,以便更好地与团队和客户沟通,管理项目和推动创新。 1.3. 持续学习和适应性 技术行业的变化总是很快,特别是在AI和机器学习的影响下。终身学习不仅仅是一个口号,而是程序员需要践行的必要策略。这意味着定期更新技能库,学习新工具和语言。 1.4. 理解和应用AI 要理解和应用AI,而不仅仅是使用AI工具,更深入地理解AI的工作原理,可以帮助程序员更有效地利用这些工具,甚至参与到AI工具和模型的开发中去。 1.5. 伦理和责任意识 随着AI技术的日益普及,程序员应当增强对AI伦理问题的敏感性,如数据隐私、偏见和安全性等方面的考虑,确保技术的负责任使用。 2.AI辅助编程对程序员工作的影响 AI工具在程序开发上的应用已经显著改变了日常的编码实践,通过自动补全、代码生成等功能有效提高了开发效率和准确性,同时也引起了一系列对过度依赖这些工具可能产生的负面影响的讨论。 2.1.AI工具对编码实践的积极影响 1. 提高编码效率:AI驱动的自动完成工具能够根据上下文和既有编码习惯提供代码建议,显著减少了编码所需时间。 2. 错误检测与削减:一些工具能够在编码时实时检测语法错误或逻辑错误,帮助开发者及时更正。 3. 学习与参考:AI工具可以提供多种编程方式和最佳实践的示例,帮助开发者学习新技巧并增强理解。 4. 支持复杂问题解决:复杂算法或特定领域问题(如数据科学、机器学习模型构建)的编程支持,可以简化代码实现过程。 2.2.AI工具的潜在风险 1. 基本编程技能弱化:依赖AI自动生成代码可能导致开发者忽视基础编程技能的培养,长期可能降低手动编码能力。 2. 创新能力受限:过度依赖工具的建议可能导致开发者在面对独特或新颖问题时缺乏自主创新的能力。

springboot整合springmvc使用外置的Servlet容器

目录 1. 创建2. 配置3. 配置Tomcat4. 心得 1. 创建 2. 配置 首先创建两个文件夹 配置: 3. 配置Tomcat 右上角的按钮 添加 保证这几个不冲突,保证你的tomcat的文件没问题!!! 点击部署 选择第二个war exploded 最终呈现: 访问页面与springboot的书写是一样的,只不过这次不是用springboot自带的tomcat了。 4. 心得 这个很简单,一下子就成了,本身就不难。

如何用sql在1分钟从1T数据中精准定位查询?Hive离线数仓 Spark分析

最近在一个群里,从群友哪里了解到这样一个业务需求:如何在 hdfs 1 T源数据库中,1分钟内从其中抓取自己想要的数据? 我的理解是 : 在hdfs数据库中为拥有 尽1T数据的表创建索引,并对其进行性能优化,以实现1分钟精准查询数据的目的 想要实现其实有点繁杂,可以使用多种工具和技术。如下: 假设使用的是Apache Hive和HDFS存储数据: 有些大数据的朋友可能会疑惑,为什么优先假设hive spark不是更擅长? 因为我是走大数据运维方向的,运维的话数据库sql语句接触的多,离线数仓hive中的语句和sql基本大差不差,作为运维我上手更快一点,学的比较扎实。 如果你也是运维,建议在拓宽技术池的时候优先考虑hive而不是spark;但是,如果你是开发,那么我建议在拓宽技术池的时候优先考虑spark而不是hive,因为spark中定义了一种属于它自己的语言 其实,我spark也会,但是,也只是会,比起各种大牛,只是班门弄斧。不过在最下面三,和四,我会假设spark举例子,并对spark做一下简短介绍。后续的话我会出一期关于大数据所有主流组件搭载在一个集群实验环境的运维配置文档。 注意:在大数据-Hadoop体系中 ,spark批处理和hive离线数仓可以说是对立并行的两个大分支技术栈,,,建议主攻其一,另一个灵活使用就行。他们是2015出现在国内,2017年之后国外各大公司纷纷采用,国内2020采用的,目前属于很前沿,并且很主流,很顶层的技术。(注:19年国内云计算开始起势,大数据的发展与云计算和人工智能等密切相关,更离不开芯片,硬件存储技术等相关支撑,它们之间相辅相成) 一,hive进行数据查询优化,以实现1分钟内精准查询数据的目标。 1. 数据准备:假设使用的是Apache Hive和HDFS存储数据 确保数据已经存储在HDFS中,且数据格式适合索引和查询操作。常见的数据格式包括Parquet和ORC等。 2. 选择合适的工具 在Hadoop生态系统中,有多种工具可以用于索引和优化查询性能,如Apache Hive、Apache HBase、Apache Kudu、Apache Impala等。这里假设使用的是Apache Hive。 其实HBase也能用,它提供了快速的随机读写能力,但对于大规模数据的复杂查询,相较于使用Hive,使用 HBase 可能会面临很多问题如下: 2.1 HBase 中实现类似 SQL 的复杂查询,通常需要额外的设计和开发工作,例如使用二级索引、扫描和过滤器等。 2.3 HBase 可以通过预先分区、压缩和缓存等优化措施提高性能,但是对于 1TB 数据规模的复杂查询, 在一分钟内可能难以完成。 大规模的扫描操作在 HBase 中可能会导致性能瓶颈,会引起大数据集群瞬时宕机,尤其是在没有合适索引的情况下 2.4 HBase 与其他查询优化工具(如 Apache Phoenix)结合可以提供 SQL 查询功能,但整体复杂度较高。 总之,与 Hive 相比,HBase 的查询优化和性能调优复杂度更大。查询小数据 优先hbase 实时性很快反应迅速,但稍微数据量一上来,就要考虑hive了 3. 创建表和索引 3.1 创建表 确保表已经存在并且数据已经加载。 CREATE EXTERNAL TABLE IF NOT EXISTS my_table ( id INT, name STRING, value DOUBLE, timestamp TIMESTAMP ) STORED AS PARQUET LOCATION 'hdfs:///path/to/my_table'; 3.