Linux第63步_为新创建的虚拟机添加必要的目录和安装支持linux系统移植的软件

1、创建必要的目录 输入密码“123456”,登录虚拟机 这个“zgq”,是用户名,也是下面用到的的“zgq”目录。 1)、创建“/home/zgq/linux/”目录 打开终端,进入“/home/zgq/”目录 输入“mkdir linux回车”,创建“/home/zgq/linux/”目录 输入“ls回车”,列举“/home/zgq/”目录的所有文件和文件夹 创建好“/home/zgq/linux/”目录后,目录见下图: 2)、创建“/home/zgq/linux/”的子目录 输入“cd /home/zgq/linux/回车”,切换到“/home/zgq/linux/”目录 输入“mkdir atk-mp1回车”,创建“/home/zgq/linux/busybox/atk-mp1/”目录 输入“mkdir busybox回车”,创建“/home/zgq/linux/busybox/”目录 输入“mkdir buildroot回车”,创建“/home/zgq/linux/buildroot/”目录 输入“mkdir tftpboot回车”,创建“/home/zgq/linux/tftpboot/”目录 输入“chmod 777 tftpboot/回车”,给tftpboot赋可执行权限,非常重要; 输入“mkdir nfs回车”,创建“nfs”目录 输入“mkdir rootfs回车”,创建“/home/zgq/linux/rootfs”目录 输入“mkdir tool回车”,创建“/home/zgq/linux/tool”目录,用于存放各种安装工具 如下: code_1.50.1-1602600906_amd64.deb gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz stm32wrapper4dbg-master.zip 等等 输入“ls回车”,列举“/home/zgq/linux/”的子目录 创建好“/home/zgq/linux/”目录的子目录后,目录见下图: 3)、创建“/home/zgq/linux/atk-mp1/”的子目录 输入“cd /home/zgq/linux/atk-mp1/回车”进入“/home/zgq/linux/atk-mp1/” 输入“mkdir tfa回车”,创建“/home/zgq/linux/atk-mp1/tfa/”目录 输入“mkdir uboot回车”,创建“/home/zgq/linux/atk-mp1/uboot/”目录 输入“mkdir linux回车”,创建“/home/zgq/linux/atk-mp1/linux/”目录 输入“ls回车”,列举“/home/zgq/linux/atk-mp1/”目录的所有文件和文件夹 创建好“/home/zgq/linux/atk-mp1/”目录的子目录后,目录见下图: 4)、创建“/home/zgq/linux/atk-mp1/linux/bootfs/”目录 输入“cd /home/zgq/linux/atk-mp1/linux/回车”, 进入“/home/zgq/linux/atk-mp1/linux/” 输入“mkdir bootfs回车”,创建“/home/zgq/linux/atk-mp1/linux/bootfs”目录,用来存放新生成的“ uImage ” 和“ stm32mp157d-atk.dtb ” 创建好“/home/zgq/linux/atk-mp1/linux/bootfs/”目录后,目录见下图: 5)、创建“/home/zgq/linux/nfs/rootfs/”目录 输入“cd /home/zgq/linux/nfs/回车”,切换到“/home/zgq/linux/nfs/”目录 输入“mkdir rootfs回车”,创建“/home/zgq/linux/nfs/rootfs/”目录用于存放根文件系统 输入“ls回车”,列出“/home/zgq/linux/nfs/”目录下的文件和文件夹 创建好“/home/zgq/linux/nfs/”目录的子目录后,目录见下图: 6)、创建“/usr/local/arm”目录 输入“cd /usr/local/回车” ,切换到“/usr/local/”目录

谷歌发布史上最强开源大模型Gemma,性能超Llama-2,笔记本也能跑

这两天 AI 界真是超级热闹,前有 Open AI 扔出 Sora 炸弹,如今 Google 在没有任何预告的情况下开源了全新大模型 Gemma。 此次发布的 Gemma 相比自家的 Gemini 更加轻量级,模型权重也一并开源。不仅可以在笔记本电脑上运行,而且还免费可商用,支持中文。看来很多创业公司已经开始两眼发光了。 还不知道 Gemma 是啥的,可以跟着我们来了解一下。 Gemma 是一个轻量级、最先进的开源大模型,采用与创建 Gemini 模型相同的研究和技术构建。Gemma 由 Google DeepMind 和 Google 的其他团队开发,灵感来自双子座,拉丁语 gemma,意思是“宝石”。除了模型权重外,谷歌还发布了一些工具,以支持开发人员创新、促进协作并指导负责任地使用 Gemma 模型。 目前 Gemma 在全球范围内可用。以下是有关 Gemma 的一些要点: 两种尺寸的模型权重:Gemma 2B 和 Gemma 7B。每种尺寸都带有预训练和指令微调的版本。 一个生成式人工智能工具包,为使用 Gemma 创建更安全的 AI 应用程序提供了指导和必要工具。 通过原生 Keras 3.0 为所有主要框架(JAX、PyTorch 和 TensorFlow)提供推理和监督微调 (SFT) 的工具链。 准备好现成可用的 Colab 和 Kaggle 笔记本电脑,以及与 Hugging Face、MaxText、NVIDIA NeMo 和 TensorRT-LLM 等流行工具的集成,使 Gemma 入门变得容易。 经过预训练和指令调整的 Gemma 模型可以在笔记本电脑、工作站或 Google Cloud 上运行,并可以轻松部署到 Vertex AI 和 Google Kubernetes Engine (GKE) 上。

【EI会议征稿通知】2024年软件自动化与程序分析国际学术会议(SAPA 2024)

2024年软件自动化与程序分析国际学术会议(SAPA 2024) 2024 International Conference on Software Automation and Program Analysis 在当今科技社会中,软件产业呈快速发展趋势,软件自动化与程序分析技术在提高软件质量、降低开发成本、提升软件安全性等方面发挥着越来越重要的作用。2024年软件自动化与程序分析国际学术会议(SAPA 2024)将于2024年6月14-16日在中国大理举行,旨在聚集创新人才、促进学术繁荣、助力创新驱动、搭建产学研政优势互补的高层次交流平台。会议将涵盖多个主题,包括自动化测试、静态代码分析、动态分析技术、形式化方法等。与会者将有机会深入了解这些领域的最新进展,并与其他专家进行深入交流和合作,本次会议将为与会者提供一个全方位的学术交流平台。我们诚挚邀请来自世界各地的知名专家学者、企业研发人员等,共同分享他们在软件自动化与程序分析领域的最新研究成果、技术突破和实践经验。 重要信息 大会官网:www.icsapa.org(点击参会/投稿/了解会议详情) 大会时间:2024.6.14-16日 大会地点:中国-大理 接受/拒稿通知:投稿后1周内 收录检索:EI Compendex; Scopus 征稿主题 包括但不限于软件架构、OA系统、软件设计方法、软件领域建模、软件教育、自动化软件的设计合成、基于组件的软件工程、软件代理技术、软件测试技术、软件重用和度量、软件开发、流程程序分析、布置与路线分析、闲余能量分析、程序语言、编译优化、体系结构、多线程分析、安全漏洞、软件通信、软件工程决策支持、计算机图形学与人机交互、多媒体技术应用、人工智能和识别、嵌入式软件和应用、自动控制、分布式计算和网格计算、云计算与大数据等。 会议出版 所有的投稿都必须经过2-3位组委会专家审稿,经过严格的审稿之后,所有录用文章在完成注册后被收录至SAPA 2024 会议论文集,由EI目录期刊出版,并被EI Compendex 和 Scopus 检索。 注意事项: 1. 论文需按照会议论文模板排版; 2. 会议只接收英文稿件; 3. 论文应具有学术或实用价值,未在国内外学术期刊或会议发表过。作者可通过CrossCheck, Turnitin或其他查询系统自费查重,否则由文章重复率引起的被拒搞将由作者自行承担责任。涉嫌抄袭的论文将不被出版,且公布在会议主页。 参会方式 作者参会:一篇录用文章允许一名作者免费参会 主讲嘉宾:申请主题演讲,由组委会审核 口头演讲:申请口头报告,时间为15分钟 海报展示:申请海报展示,A1尺寸,彩色打印

一文搞懂match、match_phrase与match_phrase_prefix的检索过程

一、在开始之前,完成数据准备: # 创建映射 PUT /tehero_index { "settings": { "index": { "number_of_shards": 1, "number_of_replicas": 1 } }, "mappings": { "_doc": { "dynamic": false, "properties": { "id": { "type": "integer" }, "content": { "type": "keyword", "fields": { "ik_max_analyzer": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" }, "ik_smart_analyzer": { "type": "text", "analyzer": "ik_smart" } } }, "name":{ "type":"text" }, "createAt": { "type": "date" } } } } } # 导入测试数据 POST _bulk { "

查找日期最相近的数据文件

set target_time "2024-02-22 11:07:32" set earliest_positive_time_diff 9999999999 set earliest_positive_file "" # 文件列表 set file_list { "2024-02-22_11-07-31_lidar.sany" "2024-02-22_11-07-30_lidar.sany" "2024-02-22_11-07-33_lidar.sany" } # 提取文件名中的日期和时间 foreach file $file_list { set filename_parts [split [file rootname $file] "_"] set date_time_parts [split [lindex $filename_parts 0] "-"] set file_year [lindex $date_time_parts 0] set file_month [lindex $date_time_parts 1] set file_day [lindex $date_time_parts 2] set time_parts [split [lindex $filename_parts 1] "-"] set file_hour [lindex $time_parts 0] set file_minute [lindex $time_parts 1] set file_second [lindex [split [lindex $time_parts 2] "

【Simulink】基于快速模型预测控制的三相并网逆变器电流控制(Matlab Function)

之前写过三相并网逆变器FCS-MPC的博客 👉【Simulink】基于FCS-MPC的三相并网逆变器电流控制(Matlab Function) 1. 快速模型预测控制 为什么采用快速模型预测控制? 传统 FCS-MPC的问题: 对于两电平三相逆变器而言,每个控制周期内均需要进行 2 3 = 8 2^3=8 23=8(有两个开关状态对应矢量相同)次矢量寻优才可得到最优矢量,因此计算量大,使得逆变器的实际输出电压电流时刻与理想时刻存在较大延时。 传统 FCS-MPC是将各基本电压矢量代入预测模型,计算相应预测电流矢量后,利用代价函数进行寻优计算,最小的代价函数值所对应的基本电压矢量则为最优矢量。该算法在每个控制周期内需要进行多次预测和寻优计算,因而计算量较大,而预测控制本身希望缩短控制周期从而进一步提升系统控制性能。 快速模型预测控制(Fast Model Predictive Control,F-MPC)的原理: 采用无差拍控制思想,在单个控制周期内只需一次计算即可得到目标电压矢量,再通过相角与幅值即可判断其空间位置,进而可以从8个基本电压矢量中选择出最优的电压矢量。 最优电压矢量计算 FCS-MPC的电流预测公式(详细推导见👉【Simulink】基于FCS-MPC的三相并网逆变器电流控制(Matlab Function)): i α β ( k + 1 ) = T s L [ u α β ( k ) − e α β ( k ) ] + ( 1 − R T s L ) i α β ( k ) i_{\alpha\beta}(k+1)=\frac{T_s}{L}[u_{\alpha\beta}(k)-e_{\alpha\beta}(k)]+(1-\frac{RT_s}{L})i_{\alpha\beta}(k) iαβ​(k+1)=LTs​​[uαβ​(k)−eαβ​(k)]+(1−LRTs​​)iαβ​(k)

Android源码之init.rc文件详解

一、引言 .rc文件是 android系统一个十分重要的文件。 其是资源文件,包括比如对话框、菜单、图标、字符串等资源信息。 使用.rc资源文件的目的是为了对程序中用到的大量的资源进行统一的管理。 本文来了解文件的规则。 二、Android中init.rc文件简单介绍 init.rc脚本是由Android中linux的第一个用户级进程init进行解析的。 init.rc 文件并不是普通的配置文件,而是由一种被称为“Android初始化语言”(Android Init Language,这里简称为AIL)的脚本写成的文件。 init.rc脚本包括了启动脚本文件,主要完成一些初级的初始化,文件系统初始化 主要是: 1)设置一些环境变量 2)创建system、sdcard、data、cache等目录(见案例1) 3)把一些文件系统mount到一些目录去,如,mount tmpfs tmpfs /sqlite_stmt_journals 4)设置一些文件的用户群组、权限 5)设置一些线程参数 6)设置TCP缓存大小 该文件在ROM中是只读的,即使有了root权限,可以修改该文件也没有。因为我们在根目录看到的文件只是内存文件的镜像。也就是说,android启动后,会将init.rc文件装载到内存。而修改init.rc文件的内容实际上只是修改内存中的init.rc文件的内容。一旦重启android,init.rc文件的内容又会恢复到最初的装载。想彻底修改init.rc文件内容的唯一方式是修改Android的ROM中的内核镜像(boot.img)。 如果想要修改启动过程只需要修改init.c(system/core/init)或者init.rc里的内容即可. init.c与init.rc在源码中的位置分别位于如下: 1 init.c : /system/core/init 2 init.rc : /system/core/rootdir 三、文件规则 类型 主要包含了四种类型的语句: 1、Action 2、Services Action和services显式声明了一个语句块 3、Commands 4、Options. commands和options属于最近声明的语句块。 在第一个语句块之前 的commands和options会被忽略. 基本规则 1、在init.rc文件中一条语句通常是占据一行。 2、单词之间是通过空格符来相隔的。 3、如果需要在单词内使用空格,那么得使用转义字符""。 4、末尾的反斜杠,是换行折叠符号,应该和下一行合并成一起来处。 理,与C语言中的含义是一致的。 5、以#号开头的为注释。 关键字 关键字位于语句块的首部,决定了这个语句块的种类 关键字含义Action动作trigger触发器。或者叫做触发条件.commands命令services服务 1、触发器(trigger) 在"动作"(action)里面的,on后面跟着的字符串是触发器(trigger),trigger是一个用于匹配某种事件类型的字符串,它将对应的Action的执行。 触发器(trigger)有几种格式: 1、最简单的一种是一个单纯的字符串。比如“on boot”。这种简单的格式可以使用命令"trigger"来触发。 2、还有一种常见的格式是"on property : <属性>=<值>“。如果属性值在运行时设成了指定的值,则"块”(action)中的命令列表就会执行。 常见的格式: 格式含义on early-init在初始化早期阶段触发on init在初始化阶段触发on late-init在初始化晚期阶段触发on boot/charger当系统启动/充电时触发on property当属性值满足条件时触发 2、动作(Action) 动作表示了一组命令(commands)组成.

基于Redis商品库存扣减方案

前言 电商业务场景下,对于库存的处理是比较重要的,表面上看只是对商品库存数做一个扣减操作,但是要做到不超卖、不少卖,同时还要保证高性能,却是一件非常困难的事。 传统解决方案 库存扣减的传统解决方案是完全基于关系型数据库来做的,以 MySQL 为例,假设有如下sku表: CREATE TABLE `sku` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'skuID', `product_id` BIGINT(20) NOT NULL COMMENT '商品ID', `stock` INT(11) UNSIGNED DEFAULT '0' COMMENT '库存数', PRIMARY KEY (`id`) ) ENGINE = InnoDB COMMENT ='商品sku表'; 用户下单时,先执行如下SQL扣减库存,库存扣减成功才创建订单。任一商品库存不足时,扣减就会失败,此时可以回滚事务,并给用户一个友好的提示。 UPDATE sku SET stock=stock-#{num} WHERE id=#{id} AND stock>=#{num} 这种方案可以保证不超卖,它依赖的是MySQL事务一致性和行锁,上一个请求扣减库存会持有对应sku的行锁直到事务提交,后续请求抢锁失败会阻塞,相当于库存扣减在MySQL层面被串行化了。缺点也很明显,如果系统并发较高,或者遇到大促就会存在热点问题,大量用户购买同一商品,就会导致大量线程都在竞争锁,进而导致MySQL TPS降低,RT线性上升,最终甚至引发系统雪崩。MySQL针对单行update的tps大概也就在500左右,为了避免MySQL成为瓶颈,建议把库存扣减操作转移到上层执行。 基于Redis扣减库存 Redis 高效的读写性能,是所有关系型数据库望尘莫及的,单台实例轻轻松松就能达到10W tps,高出MySQL几个数量级,基于Redis的库存扣减方案可以满足绝大多数企业。 在主流程上,用户可能一次下单多个商品,我们可以通过执行lua脚本的方式来扣减库存,并对脚本执行结果做处理。库存扣减可能有三种结果: 1:库存扣减成功0:库存不足,扣减失败-1:库存不存在,还未load到Redis @Slf4j public class StockService { private final RedisClient redisClient = RedisClient.getClient(); public void reduce(List<SkuDTO> skuDTOList) { // lua脚本扣减库存 int result = doReduce(skuDTOList); if (result == -1) { // 初始化库存 initStock(skuDTOList); result = doReduce(skuDTOList); } if (result == 0) { throw new BizException("

js对象的赋值,浅拷贝,深拷贝区分和使用场景

一、前置知识 js在定义变量的时候,变量会被存储堆和栈中,基本数据类型(String,Number,Null,Undefined,Boolean)存储在栈中,引用数据类型(Object、Array、Function、Data等)存储在堆中,但是在栈中存储了指向堆数据的指针(内存地址)。 二、区分 1.赋值 赋值没有创建新对象,仅仅是拷贝了原对象的指针。所以把obj赋值给obj2,只拷贝了栈中的内存地址,指向同一个堆。 (这里懒得画图就借用其他博主的博客来举例了,复制=赋值) var obj = {name:'ConardLi'}; var obj2 = obj; obj2.name = 'code秘密花园'; console.log(obj.name); // code秘密花园 同理我们赋值一个基本数据类型 var name = 'ConardLi'; var name2 = name; name2 = 'code秘密花园'; console.log(name); // ConardLi; 把name2赋值给name,基础数据类型存放在栈中,所以修改他们两个的数据互不影响。 2.浅拷贝 浅拷贝是创建一个新对象,这个对象仅对原对象的属性进行拷贝,属性值是基本类型时,拷贝的是原数据,属性值是引用类型时,拷贝的是指针。(可以根据上图方便理解)。也可以理解为浅拷贝只拷贝了栈内存中的数据。所以当我们修改基本数据类型时,因为浅拷贝复制了一份栈中的数据,所以两者不会有影响,但是修改引用数据类型时,就会对原数据产生影响。 下面代码举例: let obj = { a: 1, b: { c: 3 } }; // 借助对象的方法assign实现浅拷贝 let obj2 = Object.assign({}, obj) obj.a = 2; obj.b.c = 4; console.log(obj); //{ a: 2, b: { c: 4 } } console.

vue3 +ts 安装并封装axios

目录 1、为什么要封装axios 2、安装 3、封装request 4、使用步骤 步骤1:请求数据 ( 举例下面几个常用的 ) 步骤2:在要请求的组件上使用 5、代理 1、为什么要封装axios axios.get().then() 这样的书写,会有缺陷,在以下缺点 1、请求头能不能统一处理 解决: 创建一个 request/request.js 文件夹, 在里面可以使用axios.create创建实例对象 也可以在里面设置 请求 与 响应 拦截器 2、不便于接口的统一管理 解决:在 request 文件夹加多一个api文件来管理所有接口, (会先导入rerequest.js的实例) 并使用函数,不然每次发请求时都会跑一次api文件 3、容易出现回调地狱 LogoutAPI () 最终的结果是返回proise对象 解决:acync + await await 后面一般放promise对象 注意:但封装axios后还是可以用 .then() 2、安装 npm install axios 3、封装request 先在 src 下创建一个 request 文件夹,并添加一个 request.ts 文件 import axios from 'axios' // 创建axios实例 const request = axios.create({ baseURL: '',// 所有的请求地址前缀部分 timeout: 80000, // 请求超时时间(毫秒) withCredentials: true,// 异步请求携带cookie // headers: { // 设置后端需要的传参类型 // 'Content-Type': 'application/json', // 'token': x-auth-token',//一开始就要token // 'X-Requested-With': 'XMLHttpRequest', // }, }) // request拦截器 request.

下载、编译、安装、使用 vue-devtools

不少人都想下载 vue-devtools插件,但又不会做,今天我做个比较详细的笔记 查看当前的devtools的版本可以去这个网站看右侧的个v几点几的,就是版本号 https://github.com/vuejs/devtools 目录 第一个方法:使用极简插件 第一步:查找极简插件 第二步:搜索vue-devtools 第三步:点击推荐下载 第四步:解压安装​​​​​​​ 第二个方法:在github下载 第一步:下载yarn(未下载yarm的从这开始) 第二步:验证yarn是否安装成功 第三步:再次查看yarn是否正常使用 第四步:从hithub下载devtools(已下yarn可直跳到这步) 第五步:找到evtools文件夹的路径 第六步:初始化 第七步:解包 第八步:安装 第九步:使用 第一个方法:使用极简插件 这个方法比第二个方法简单的多,但不是官网放上去的,只是别把编译好的文件放上来方便我们使用 第一步:查找极简插件 通过下面的链接去极简插件网站 极简插件 第二步:搜索vue-devtools 搜索vue就出来了,搜索vue-devtools(以前可以)反而出不来,网站版本不一样,情况可能不一样 第三步:点击推荐下载 第四步:解压安装 解压下载的文件后按下面的步骤进行, 这也可能会不一样,不过可以统一到设置里找到扩展程序也行 然后把解压好的文件拖动到浏览器扩展程序内就行了,后面就是和第二个方法的使用步骤是一样的。 第九步:使用 第二个方法:在github下载 这个是查看了简书的出处的,本人只是做一个补充,或直观点感受 作者:hemiao3000 链接:编译安装 vue-devtools 来源:简书 本人使用的node是 -- 16.17.1 版本 下载yarn是 -- 1.22.19 版本 下载vue-devtools是 -- 6.4.4 版本 注:后面有对应的图片教程,一步步来就行 第一步:下载yarn(未下载yarm的从这开始) 编译安装 vue-devtools要用到yarn 打开cmd 或 windows PowerShell,建议是打开windows PowerShell(不要说你不会打开) 知道要用这个插件的应该都下载过node了,而node自带npm npm install -g yarn 第二步:验证yarn是否安装成功 安装完毕后,可直接执行 yarn -v 命令查看 yarn 的版本,以验证是否安装成功

Python——multiprocessing报错:TypeError: cannot pickle ‘_thread.lock‘ object

多进程报错 Traceback (most recent call last): File "C:\Users\miaochangbin\PycharmProjects\eduCrawler\main.py", line 138, in <module> p.start() File "D:\Program Files\python\lib\multiprocessing\process.py", line 121, in start self._popen = self._Popen(self) File "D:\Program Files\python\lib\multiprocessing\context.py", line 224, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "D:\Program Files\python\lib\multiprocessing\context.py", line 327, in _Popen return Popen(process_obj) File "D:\Program Files\python\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__ reduction.dump(process_obj, to_child) File "D:\Program Files\python\lib\multiprocessing\reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) TypeError: cannot pickle '_thread.lock' object 原因 在启动子进程时,会将所有输入参数经过信息序列化后传递到子进程中,而报错就是在信息进行序列化时候。而这边信息报错传递子进程的对象信息(属性以及属性的属性)。因此:说明代码中有类或者对象无法被序列化,但是被传入子进程中,去除对应无法实例化的代码,或者将其放在子进程中初始化即可。 参考文章: 多进程 报错 TypeError: cannot pickle ‘_thread.

【Python笔记-设计模式】工厂模式

一、说明 (一) 解决问题 提供了一种方式,在不指定具体类将要创建的情况下,将类的实例化操作延迟到子类中完成。可以实现客户端代码与具体类实现之间的解耦,使得系统更加灵活、可扩展和可维护。 (二) 使用场景 希望复用现有对象来节省系统资源, 而不是每次都重新创建对象时如果无法预知对象确切类别及其依赖关系时希望用户能扩展你软件库或框架的内部组件时 二、结构 产品 (Product) 将会对接口进行声明。 对于所有由创建者及其子类构建的对象, 这些接口都是通用的。具体产品 (Concrete Products) 是产品接口的不同实现。创建者 (Creator) 类声明返回产品对象的工厂方法。 该方法的返回对象类型必须与产品接口相匹配。你可以将工厂方法声明为抽象方法, 强制要求每个子类以不同方式实现该方法。 或者, 你也可以在基础工厂方法中返回默认产品类型。注意, 尽管它的名字是创建者, 但它最主要的职责并不是创建产品。 一般来说, 创建者类包含一些与产品相关的核心业务逻辑。 工厂方法将这些逻辑处理从具体产品类中分离出来。 打个比方, 大型软件开发公司拥有程序员培训部门。 但是, 这些公司的主要工作还是编写代码, 而非生产程序员。具体创建者 (Concrete Creators) 将会重写基础工厂方法, 使其返回不同类型的产品。注意, 并不一定每次调用工厂方法都会创建新的实例。 工厂方法也可以返回缓存、 对象池或其他来源的已有对象。 三、伪代码 #!/usr/bin/env python # -*- coding: UTF-8 -*- __doc__ = """ 工厂模式 将类的实例化操作延迟到子类中完成 例:通过传入不同的操作符,实现对两个数字的加减乘除运算 """ from abc import ABC, abstractmethod class Product(ABC): """ 抽象基类 """ num1 = None num2 = None @abstractmethod def get_result(self): pass class ProductAdd(Product): "

【Python笔记-设计模式】单例模式

一、说明 单例是一种创建型设计模式,能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 (一) 解决问题 维护共享资源(数据库或文件)的访问权限,避免多个实例覆盖同一变量,引发程序崩溃。 (二) 使用场景 数据库连接文件操作所有需要维护对象变量一致性的场景 二、结构 单例 (Singleton) 类声明了一个名为get­Instance获取实例的静态方法来返回其所属类的一个相同实例。单例的构造函数必须对客户端 (Client) 代码隐藏。 调用获取实例方法必须是获取单例对象的唯一方式。 三、伪代码 #!/usr/bin/env python # -*- coding: UTF-8 -*- __doc__ = """ 单例模式 """ import threading class Singleton1: """ 方法1, 实现__new__方法 并在将一个类的实例绑定到类变量_instance上, 如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回 如果cls._instance不为None,直接返回cls._instance """ _instance = None _lock = threading.Lock() def __new__(cls, *args, **kwargs): with cls._lock: if not cls._instance: cls._instance = super().__new__(cls) return cls._instance class Singleton2(type): """ 方法2,实现metaclass,利用metaclass在实例化时已经创建好实例, 从而实现单例模式,注意必须通过metaclass实现 """ _instances = {} _lock = threading.

Python项目打包与部署(四):项目依赖管理

本教程其它章节 Python项目打包与部署(一):模块与包的概念与关系Python项目打包与部署(二): init.py的作用及内容Python项目打包与部署(三):打包与部署的实际操作流程各类Python项目的项目结构及代码组织最佳实践Python项目打包与部署(四):项目依赖管理 Python 项目依赖管理 Python编程效率高,其中1个主要原因是有大量开源库,如常见的 requests, pandas, numpy 等。 通常,python 项目严重依赖各类第3方库。 不同项目对同1个库的版本可能有不同要求,稍不注意,项目就无法运行。因此,依赖管理是Python项目管理的重要内容 1、使用 requirements.txt 管理依赖库 pip + requirements.txt 是管理项目依赖的最常见方式。 这种方式,适合于手工部署、离线部署场景。 1) requirements.txt 格式 Django==3.2.8 djangorestframework==3.1.3 docopt==0.6.2 gnureadline==6.3.3 click 每一行、代表1个依赖库,可以加版本,也可以不加 2) 生成requirements.txt文件 此文件可以手工创建编辑。 如果项目使用单独的虚拟环境开发,可用命令生成 requirements.txt ,自动将当前虚拟环境安装的依赖包写入requirements.txt文件。 pip freeze > ./requirements.txt 3) 根据 requirements.txt 安装依赖 安装项目时,可以根据安装包中的requirements.txt 来安装依赖库: pip install -r requirements.txt -r requirements.txt 指示pip安装requirements.txt 中列出的第3方依赖库。 4) 离线安装依赖 如果安装服务器不能访问internet,按如下步骤安装依赖: (1)开发服务器端 ,导出并打包依赖包 pip download -d require -r requirements.txt 此命令在当前目录下生成 ./require目录,存放了下载的依赖包, (2) 打包 require 目录,并复制到安装服务器安装目录。 (3)本地安装依赖 在项目目录执行命令安装:

Python项目打包与部署(一):模块与包的概念与关系

当前各类Python教程鲜有涉及Python打包与部署技术,或者讲述过于表面化、片面化。 本人尝试从原理开始,结合实例,并给出标准操作步骤建议,为python编程爱好者提供一份较为详实的Python项目打包与部署参考教程。 本教程其它章节 Python项目打包与部署(二): init.py的作用及内容Python项目打包与部署(三):打包与部署的实际操作流程各类Python项目的项目结构及代码组织最佳实践Python项目打包与部署(四):项目依赖管理 虽然 Python 是动态类型编程语言,不需要提前编译。但1个Python项目也是由一组.py文件、数据文件、资源文件等组成,大部分项目还会引用第3方库,也存在依赖管理。因此,python项目管理与其它语言如java,C++是类似的。而构建1个 Python 项目时,模块与包是我们面临的基础概念。 1、模块、包的概念 Python中的模块(Module), 就是一个单独的.py文件,其中包含变量定义,函数定义、类定义、以及其它可执行语句。模块是一个独立的代码单元,可以用解释器直接运行,可以导入到其他模块中。 另一方面,包(Package) 是一个目录中所包含的模块集合。包允许我们将多个相关模块组合在一个公共命名空间下,从而更容易组织和构建我们的代码库。 将代码分解为模块和包可以带来巨大的好处: 可维护性。将代码分解为模块,有助于我们对整个应用程序的独立部分进行更改,而不会影响整个应用程序,因为模块的设计仅用于处理应用程序的一部分。可重复使用性。这是软件开发的关键部分,我们只需编写一次代码,就可以根据需要在应用程序的许多不同部分中多次使用它。这使我们能够编写干净、简洁的代码。方便分工合作。模块化代码,团队的不同开发者可以分别承担同一应用程序的不同部分(模块),而不会相互干扰。可读性。将代码分解为模块和包可以提高代码的可读性。可以很容易地分辨出文件中不同代码的功能。例如,我们可能有一个名为databaseConnection. py的文件:仅从名称上我们就可以知道这个文件处理数据库连接。 2、模块详解 模块包含可执行语句及函数定义。这些语句用于初始化模块,且仅在 import 语句 第一次 遇到模块名时执行。 (文件作为脚本运行时,也会执行这些语句。) 每个模块都有自己的私有命名空间,它会被用作模块中定义的所有函数的全局命名空间。 因此,模块作者可以在模块内使用全局变量而不必担心与用户的全局变量发生意外冲突。 另一方面,如果你知道要怎么做就可以通过与引用模块函数一样的标记法 modname.itemname 来访问一个模块的全局变量。 2.1 创建模块的示例 打开IDE或文本编辑器,创建一个文件,将其命名为sample. py并输入以下代码: # sample.py # create a variable in the module sample_variable = "This is a string variable in the sample.py module" # A function in the module def say_hello(name): return f"Hello, {name} welcome to this simple module.

Java日常开发的21个坑,你踩过几个?

1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空指针问题 Equals方法左边的空指针问题 ConcurrentHashMap 这样的容器不支持 Key 和 Value 为 null。 集合,数组直接获取元素 对象直接获取属性 1.1包装类型的空指针问题 public class NullPointTest { public static void main(String[] args) throws InterruptedException { System.out.println(testInteger(null)); } private static Integer testInteger(Integer i) { return i + 1; //包装类型,传参可能为null,直接计算,则会导致空指针问题 } } 1.2 级联调用的空指针问题 public class NullPointTest { public static void main(String[] args) { //fruitService.getAppleService() 可能为空,会导致空指针问题 fruitService.getAppleService().getWeight().equals("OK"); } } 1.3 Equals方法左边的空指针问题 public class NullPointTest { public static void main(String[] args) { String s = null; if (s.

Vue3组合式API(Composition API)的使用案例

组合式API可以抽离出公共的函数或者抽离出相同功能的代码,使页面更加简洁。 为了更好的组合代码,可以创建统一规范的use函数。 在app.vue(根据自己的情况修改vue页面) <template> <div>{{count}}</div> </temolate> <script setup> // 在vue中引入 import useCount from './useCount.js' let {count, doubleCount} = useCount(1); console.log(count) </script> 在你抽离的函数里面写 import {ref} from 'vue'; function count (num) { let count = ref(num); let dounbleCount = computed(()=>count.value*2); return { count, doubleCount } } export default useCount; 这样就可以根据自己的情况抽离出自己的代码了 参考:组合式 API 常见问答 | Vue.js 代码已经放至github:https://github.com/pan-0909/study/tree/main/CompositionApi,欢迎star⭐⭐!!

linux 系统的目录结构

为什么某些执行程序位于/bin、/sbin、/usr/bin或/usr/sbin目录下?例如,less命令位于/usr/bin目录下。为什么不是/bin、/sbin或/usr/sbin?这些目录之间有什么区别呢? 在这篇文章中,让我们主要讲述一下Linux文件系统结构,并解释各个目录的含义。 1. / 根目录 所有文件和目录都从根目录开始。 只有root用户在该目录下有写权限。 请注意,/root是root用户的主目录,与根目录不同。 2. /bin 用户二进制文件 包含二进制可执行文件。 在单用户模式下需要使用的常见Linux命令位于该目录下。 系统所有用户使用的命令也位于这里。 例如:ps、ls、ping、cp。 3. /sbin 系统二进制文件 与/bin目录类似,/sbin也包含二进制可执行文件。 但是,该目录下的Linux命令通常由系统管理员用于系统维护目的。 例如:iptables、reboot、fdisk、swapon。 4. /etc 配置文件 包含所有程序所需的配置文件。 其中还包括启动和关闭脚本,用于启动/停止各个程序。 例如:/etc/resolv.conf、/etc/init.d/cron 。 5. /dev 设备文件 设备文件。这包括终端设备、USB设备或任何连接到系统上的设备。 例如:/dev/tty1、/dev/stdin。 6. /proc 进程信息 包含有关系统进程的信息。 这是一个伪文件系统,包含有关正在运行的进程的信息。例如:/proc/{pid}目录包含有关具有特定pid的进程的信息。 例如:/proc/uptime包含有关系统资源的文本信息。 7. /var 可变文件 var代表可变文件。 这个目录下可以找到那些预计会增长的文件。 其中包括系统日志文件(/var/log)、软件包和数据库文件(/var/lib)、电子邮件(/var/mail)、打印队列(/var/spool)、锁文件(/var/lock)以及重启后需要的临时文件(/var/tmp)。 8. /tmp 临时文件 包含系统和用户创建的临时文件。 该目录下的文件在系统重新启动时会被删除。 9. /usr 用户程序 包含用户程序的二进制文件、库、文档和源代码的二级程序。 /usr/bin目录包含用户程序的二进制文件。如果在/bin目录下找不到用户二进制文件,可以在/usr/bin目录下查找。例如:at、awk、cc、less、scp。 /usr/sbin目录包含系统管理员的二进制文件。如果在/sbin目录下找不到系统二进制文件,可以在/usr/sbin目录下查找。例如:atd、cron、sshd、useradd、userdel。 /usr/lib目录包含/usr/bin和/usr/sbin的库。 /usr/local目录下包含从源代码安装的用户程序。例如,当从源代码安装apache时,它将安装在/usr/local/apache2目录下。 10. /home 用户目录 用于存储所有用户的个人文件的家目录。 例如:/home/john、/home/rose。 11. /boot 引导加载程序文件 包含与引导加载程序相关的文件。 内核initrd、vmlinux和grub文件位于/boot目录下。 例如:initrd.img-2.6.32-24-generic、vmlinuz-2.6.32-24-generic。

非精线搜索步长规则Armijo规则&Goldstein规则&Wolfe规则

文章目录 非精确线搜索步长规则Armijo规则Goldstein规则Wolfe规则C++示例代码参考链接 非精确线搜索步长规则 在数值优化中,线搜索是一种寻找合适步长的策略,以确保在目标函数上获得足够的下降。如最速下降法,拟牛顿法这些常用的优化算法等,其中的线搜索步骤通常使用Armijo规则、Goldstein规则或Wolfe规则等。 设无约束优化问题: min ⁡ f ( x ) , x ∈ R n \min f(x),{\kern 1pt} \,x \in {R^n} minf(x),x∈Rn 参数迭代过程: x k + 1 ← x k + α k d k x_{k+1}\leftarrow x_k + \alpha_k d_k xk+1​←xk​+αk​dk​ α k = arg ⁡ min ⁡ f ( x k + 1 ) = arg ⁡ min ⁡ α k > 0 f ( x k + α k ⋅ d k ) = arg ⁡ min ⁡ α k > 0 ϕ ( α k ) \alpha _{k}=\arg\min f\left(x_{k+1}\right) =\arg\min_{\alpha_k>0}f\left(x_{k}+\alpha_k\cdot d_{k}\right) \\ =\arg\min_{\alpha_k>0}\phi\left(\alpha_k\right) αk​=argminf(xk+1​)=argαk​>0min​f(xk​+αk​⋅dk​)=argαk​>0min​ϕ(αk​)