文章目录 前言一、选择排序二、快速排序三、二分查找四、广度优先搜索五、贪婪算法总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍 四、Python工具包+项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料 六、Python兼职渠道 前言 这篇文章主要介绍了如何用Python实现几种常见算法,文中代码简单易懂非常适合零基础刚刚入门的小伙伴,方便大家更好的学习,感兴趣的朋友可以了解下~
一、选择排序 选择排序是一种简单直观的排序算法。它的原理是这样:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的后面,以此类推,直到所有元素均排序完毕。算法实现如下:
#找到最小的元素def FindSmall(list): min=list[0] for i in range(len(list)): if list[i]<min: min=list[i] return min #选择排序def Select_Sort(list): newArr=[] for i in range(len(list)): minValue=FindSmall(list) newArr.append(minValue) list.remove(minValue) return newArr testArr=[11,22,33,21,123]print(Select_Sort(testArr)) 二、快速排序 快速排序的运行速度快于选择排序,
它的工作原理是这样:
设要排序的数组是N,首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
可以使用python用递归式的方法来解决这个问题:
def Quick_Sort(list): if len(list)<2: return list else: temp=list[0] less=[i for i in list[1:] if i<=temp] more=[i for i in list[1:] if i>temp] return Quick_Sort(less)+[temp]+Quick_Sort(more) testArr= [13,44,53,24,876,2]print(Quick_Sort(testArr)) 三、二分查找 二分查找的输入是一个有序的列表,如果要查找的元素包含在一个有序列表中,二分查找可以返回其位置。
打个比方来说明二分查找的原理:比如我随便想了个范围在1~100以内的整数,由你来猜,以最少的次数来猜出这个数字,你每次猜完给出个数字,我会回复大了或小了,第一种方法是你从1开始依次往后猜,那如果我想的数字是100,那么你就要猜100次;第二种方法是从50开始,如果我说小了,那你就猜75,就这样依次排除掉一半的剩余数字,这就是二分查找法。
可以看出二分查找法更加快速。
对于包含n个元素的有序列表,用简单查找最多需要n步,而二分查找法则最多只需lon2 n步。
Matlab+Webots联合仿真错误和问题记录 Matlab版本 2023b (需要下载支持包,matlab附加功能中MinGW-w64 C/C++)
Webots版本 2023b 后续回退版本到2023a
win10
1.Webots资源加载不出来 由于网络原因导致不能顺利打开Webots资源。故下载github中对应版本的assets资源包。参考官方文档,解压到下述目录中(修改电脑对应用户名,如下"he"):
C:\Users\“he”\AppData\Local\Cyberbotics\Webots\cache\assets
2.联合仿真时Matlab界面不能启动并调试 Webots2023b启动Matlab控制器由之前的nodesktop方式,变为了banch方式,导致Matlab的桌面不能正常启动,Github中已有该问题且提出了一种解决方案,期待后续版本中可以修正:
Cannot open Matlab desktop when using “batch” option #6362
https://github.com/cyberbotics/webots/issues/6362#issuecomment-1695794195
根据回答需采用extern外部控制的方式,启动matlab控制器并解决Matlab代码调试的问题,参考如下:
https://www.cyberbotics.com/doc/guide/running-extern-robot-controllers?version=master#running-a-matlab-extern-robot-controller
https://www.cyberbotics.com/doc/guide/matlab?version=master&tab-os=windows
https://github.com/cyberbotics/webots/pull/6366
详细步骤如下,供参考:
Cmd 窗口下切换到webots安装目录下(此时需要更新webots2023rev1,2024a未尝试),例:cd /d D:\soft\Webots\msys64\mingw64\bin运行webots-controller.exe并设置一些参数(需要指定matlab.exe路径),启动"yourname".m(绝对路径)文件,例:webots-controller.exe --interactive --matlab-path=D:\soft\MATLAB\R2023b\bin\win64\MATLAB.exe D:\bots_test\controllers\mpc_controller\mpc_controller.mm文件中添加代码desktop;keyboard;,此时就可以在matlab界面中进行单步调试。 后续:此方法打开Matlab后仍会闪退,此类BUG还是等更新大版本后看官方文档解决吧。本人回退2023a版本。
另外,运用uiopen函数,可将simulink当做ui界面打开,皆可以无缝仿真,中间不用过于卡顿。uiopen函数前面使用的地址是控制器文件夹中的simulink模型的地址(未在2023b版本尝试此方法打开simulink):
zhuanlan.zhihu.com/p/513545274?utm_id=0
uiopen(‘Full_model’,1);
3.Matlab/Simulink + Webots时间同步 修改Simulink设置为定步长,步长时间与webots时间步一致,如0.032s。
4.Matlab/Simulink + Webots API函数报错 使用联合仿真时,需要对每个API函数加入相应的调用代码,有那个函数就添加哪行,例:
coder.extrinsic(‘calllib’);
coder.extrinsic(‘setdatatype’);
其它参考链接 webots与Matlab联合仿真中的错误记录(1)
https://miracle.blog.csdn.net/article/details/104686998?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-1.nonecase
我matlab退出调试_开发经验分享(3) - Webots + Matlab/Simulink联合仿真方法
https://blog.csdn.net/weixin_39842237/article/details/109914823?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.no_search_link
从Java开发转向AI大模型开发,需要系统地学习和掌握一系列新的技术和算法。以下是一条推荐的学习路线:
数学与统计学基础:
线性代数:矩阵运算、特征值与特征向量等。概率论与统计学:概率分布、假设检验、最大似然估计、贝叶斯推断等。微积分:梯度求解和优化理论。 机器学习入门:
学习监督学习、无监督学习和强化学习的基本原理、模型及其应用场景。掌握经典机器学习算法,如线性回归、逻辑回归、决策树、随机森林、支持向量机(SVM)、K近邻(KNN)等。 深度学习基础:
学习神经网络的基本结构,包括全连接网络、卷积神经网络(CNN)、循环神经网络(RNN)、长短时记忆网络(LSTM)、变分自编码器(VAE)和生成对抗网络(GAN)等。学习深度学习框架,例如TensorFlow、PyTorch或Keras,并通过实践项目熟悉它们的API和工作流程。 大模型技术栈:
了解并研究大规模预训练模型,如BERT、GPT、Transformer家族和其他前沿的大规模语言模型。学习如何利用大规模数据集进行模型训练、微调以及推理部署。学习分布式训练、模型并行化和计算优化的相关技术。 自然语言处理(NLP):
学习文本处理的基本技术,包括词嵌入、序列标注、语义分析等。理解和应用现代NLP任务中常见的预处理方法、评估指标和最佳实践。 实践项目:
完成一些基于Java或者Python(鉴于AI领域的主流是Python)的机器学习和深度学习实战项目,以加深对理论知识的理解,并积累实践经验。参与开源项目,或者参加Kaggle比赛,锻炼实际问题解决能力。 持续跟进最新进展:
关注AI领域最新的研究成果和技术动态,如阅读论文、参加研讨会或在线课程。 软技能提升:
提高数据分析能力,理解业务场景并将AI技术应用于实际问题。学习云计算平台上的服务,如阿里云、AWS或Google Cloud的AI/ML服务,以便将模型部署到生产环境。 在转行过程中,除了技术层面的准备,还需要逐渐建立起AI产品思维,思考如何将模型转化为可行的产品和服务,这可能涉及与产品经理、数据工程师、运维工程师等多个角色协同工作。同时,保持对行业标准和法规的关注也是必不可少的。
想处理属性表中的字段,用字段计算器,发现只要用到python的字符串split方法,就会报错,原因未知。期待有朝一日能得到合理解答。
comfyui+krita所有相关资源整合包(无需下载后面链接)百度网盘:https://pan.baidu.com/s/1iwNRpdTaD26YbzSDm6WLDA?pwd=bur8
–来自百度网盘超级会员V4的分享
krita绘画软件官网地址 https://krita.org/en/download/krita-desktop/
krita-ai-diffusion 插件:https://github.com/Acly/krita-ai-diffusion
英文文字教程:https://weirdwonderfulai.art/tutorial/generative-ai-for-krita/
B站视频教程: 实时AI绘画工作流 Krita+ComfyUI+LCM 完全开源免费本地部署 手残也能轻松愉快涂鸦了
文章目录 准备一、krita+AI绘画插件安装导入 krita_ai_diffusion-1.7.1.zip (无需解压)启动插件 二、开始使用运行前先配置参数原始生成模式(generate)全画布大小生成 附录:制作整合包需要的资源(如果找不到模型,请参考路径反复核对):需要安装的自定义节点(需要访问github)需要的模型SharedSD 1.5SD XL Checkpoints The following checkpoints are used by the default styles: 链接本地的comfyui缺少 CLIPVision model pytorch_model.bin缺少 IPAdapter model ip-adapter_sd15.safetensors LCM相关(运行实时生成流) 准备 下载整合包 (comfyui+krita+插件) :https://pan.baidu.com/s/1iwNRpdTaD26YbzSDm6WLDA?pwd=bur8
一、krita+AI绘画插件安装 krita是开源的类似photoshop的多图层绘图软件
新建图像后出现下面界面
导入 krita_ai_diffusion-1.7.1.zip (无需解压) 工具 》 脚本 》》 从文件导入Python插件
导入成功
启动插件 显示AI图像生成面板
启用后界面
配置 链接启动的comfyu
https://127.0.0.1:8188
二、开始使用 3个模式:生成(generate) 超分 (upscale ) Live (实时绘画)
运行前先配置参数 选择模型,lora , 采样次数等
目录 1.数组方法
1.增删改: unshift、push、splice、shift、pop、splice、slice
1.unshift:在数组的头部添加内容
2.push:在数组的尾部添加内容
3.splice 在数组的中部添加、删除内容
4.设置数组的长度
5. shift 删除数组的头部元素
6. pop:尾部删除元素
7.splice:增加、删除、修改
8.slice:截取数组的元素 ;
2.回调函数类: map、filter、reduce、find、findIndex 、some、every、sort
1.map:映射
2.filter:过滤
3.reduce:累计
4.find finIndex -查找
5.some every -检测
6.sort:排序
3.其他方法:join、split、reverse、concat、includes [ indexOf ] 、
1.join:拼接符
2.split:拆分符
3.reverse:翻转
4.concat:拼接
5.includes:判断
2.字符串常用方法
1.split、substr、substring、slice、toUpperCase、toLowerCase、 replace、indexOf
1.split:根据某个字符 把字符串切割成数组 split(字符)
2.substr:截取字符串1 : substr (多) 字符串.substr(开始截取的索引,截取的数量(不给就到结尾))
3.substring:字符串.substring(开始截取的索引位置,结束截取的索引位置); 包前不包后
4.slice:截取字符串
5.toUpperCase:把字符串里的英文变大写
6.toLowerCase:把字符串里的英文转小写
7.replace:替换字符串 replace("要替换的值","替换的新值");
8.indexOf:查找某个字符的索引
3.对象新增方法
1.is、assign、Object.hasOwn、hasOwnProperty、keys、values、seal
1.is:判断对象是否相同
2.assign:合并2个或者多个对象
3.1 hasOwnProperty:ES5判断某个属性是否 是对象的自身属性
3.2.Object.hasOwn:ES6判断某个属性是否 是对象的自身属性
4.Object.keys(); 获取对象的所有键名
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家, 跳转到网站 概念 基本概念解读 当谈到 "栈" 时,它是一种遵循后进先出(Last In, First Out,LIFO)原则 的有序集合。这意味着最后入栈的元素首先被弹出,而最早入栈的元素最后被弹 出。 在栈中,只能对最上面的元素进行操作,其他元素都不可见,需要将上面的元素 先出栈才能访问到其他元素。 基本操作分析 栈的基本操作包括入栈(push)和出栈(pop)。入栈指的是向栈中添加一个元 素,使其成为新的栈顶;而出栈指的是移除栈顶的元素,使得下一个元素成为新 的栈顶。此外,还可以通过栈顶元素的读取(top)来查看当前栈顶的值,以及 判断栈是否为空(empty)。 基本操作总结 入栈(Push):将一个元素放入栈的顶部。 出栈(Pop):从栈的顶部移除一个元素,并将其返回。 获取栈顶元素(Top):返回栈的顶部元素,但不对栈进行修改。 判空(isEmpty):检查栈是否为空。 获取栈的大小(getSize):返回栈中元素的个数。 应用分析 实际应用分析 栈的应用相当广泛,例如函数的调用栈、浏览器的前进后退功能和计算器的后缀 表达式求值等等。在算法设计中,栈也常用于解决问题,如深度优先搜索和括号 匹配等。 实际应用场景 表达式求值:栈可用于将中缀表达式转换为后缀表达式,并对其进行求值。运算 符和操作数依次入栈,直到遇到更高优先级的运算符。这时,先前的运算符必须 先出栈。 递归算法:递归算法通常使用栈来实现,因为递归函数的调用过程本质上也是一 个栈结构,每次递归调用都会将当前函数的局部变量和返回地址保存在栈上。 浏览器历史记录:浏览器使用栈来跟踪用户访问不同网页的历史记录。每当用户 访问一个新页面时,该页面被推入栈中。通过后退操作,最近访问的页面会从栈 中弹出。 函数调用:函数调用通常使用栈来管理函数的调用顺序和返回地址。每当一个函 数被调用时,其相关信息(参数、局部变量等)会被压入栈,函数执行完成后将 被弹出。 撤销操作:编辑器、文本处理软件等应用中,栈可以用于实现撤销操作。每次对 文本进行修改时,相关的操作记录会被压入栈中,在用户需要撤销操作时,可以 从栈中弹出最近的修改记录,实现撤销功能。 浏览器的浏览历史:浏览器通过使用栈来记录用户的浏览历史。每当用户访问一 个新的网页时,该网页的 URL 被推入栈中,当用户点击“后退”按钮时,最近访 问的网页 URL 被弹出栈。 括号匹配:栈可以用于检查表达式中的括号是否匹配。遍历表达式,将左括号压 入栈中,当遇到右括号时,检查栈顶的左括号是否与之匹配,若匹配则继续。 需要注意的是,在使用栈时要避免两个常见的问题:栈上溢(stack overflow)和栈下溢(stack underflow)。栈上溢发生在尝试向已满的栈中插入元素时,而栈下溢发生在尝试从空栈中弹出元素时。
注意事项 基本注意事项 栈的初始化:在使用栈之前,需要对栈进行初始化,即为栈分配一定大小的内存 空间,并将栈的指针指向栈底。如果栈的大小事先不确定,可以动态调整栈的大 小。 入栈操作:在进行入栈操作时,需要注意判断栈是否已满。如果栈已满,则需要 进行相应的处理,如扩充栈的空间或者报错。入栈时要确保栈的指针指向栈顶, 并将要入栈的数据放入栈顶位置,同时栈顶指针要更新。 出栈操作:在进行出栈操作时,需要判断栈是否为空。如果栈为空,则需要进行 相应的处理,如报错或者返回特定的值。出栈时要确保栈的指针指向栈顶元素, 取出栈顶元素后,栈顶指针要更新。 栈的访问:栈是一种后进先出的数据结构,因此只能访问栈顶元素,无法直接访 问栈中的其他元素。如果需要访问栈中的其他元素,需要先将栈顶元素出栈,然 后再入栈其他元素,或者使用辅助栈进行操作。 栈的容量控制:由于栈的大小是有限的,对于大量数据的处理,需要合理控制栈 的容量,避免过多的数据存储在栈中,以免造成栈溢出或者浪费内存的问题。可 以根据具体需求,设定一个合适的栈的容量上限,并在入栈操作时判断栈是否超 过容量上限。 异常处理:在使用栈的过程中,可能会出现一些异常情况,如栈溢出、空栈出栈 等。需要进行异常处理,如使用try-catch语句来捕获异常并进行相应的处理。 避免程序崩溃或者逻辑错误。 内存管理:在使用栈的过程中,需要合理地管理栈的内存。当不再需要使用栈时, 需要及时释放栈所占用的内存空间,以避免内存泄漏问题。 栈的大小限制:栈的大小是有限的,具体取决于操作系统和计算机硬件的限制。 在使用栈的过程中,需要确保栈不会溢出。当递归层数过深或者栈中的数据量 过大时,可能会导致栈溢出的问题。 入栈和出栈的顺序:栈是一种遵循"
本文章会对Java线性表的相关知识进行讲解,也会以Java代码示例来进行解释 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家, 跳转到网站 对线性表的讲解分析 定义 线性表是一种数据结构,它是由一系列具有相同类型的元素组成的有序集合。线性表中的元素按照线性的顺序 排列,每个元素只有一个前驱元素和一个后继元素,除了第一个元素没有前驱元素,最后一个元素没有后继 元素。 可以表示为 表中的元素序列{x1,x2,...,xn},其中xi是表中的元素,它们具有相同的数据类型,n表示表中元素的个数。 线性表满足以下特性: 元素的有序性:线性表中的元素按照线性的顺序排列,每个元素都有一个确定的位置。 有限性:线性表中的元素个数是有限的。 相同数据类型:线性表中的元素具有相同的数据类型,即它们具有相同的属性和操作。 线性表可以用多种方式来表示和实现,常见的实现方式包括顺序表和链表两种。 顺序表 是一种基于数组的实现方式,元素在内存中连续存储,通过下标访问元素,插入和删除操作需要移动其他元素。 链表 是一种通过节点之间的指针来连接的实现方式,节点包含元素和指向下一个节点的指针,可以实现高效的插入 和删除操作,但访问元素的效率相对较低。 注意 线性表作为数据结构中的基本概念,广泛应用于各个领域的算法和程序设计中。掌握线性表的定义和实现方式, 能够帮助我们更好地理解和应用其他数据结构和算法。 线性表是一种常见的数据结构,它由一系列元素组成,这些元素之间存在着一对一的前后关系。线性表中的元 素可以是任何类型的数据,如整数、字符或对象等。 线性表中的元素排列有序,每个元素都有一个直接前驱元素和一个直接后继元素,除了第一个元素没有前驱元 素,最后一个元素没有后继元素。 线性表的访问方式可以根据元素在表中的位置进行操作,如按索引访问、插入、删除等。其中,按索引访问是 通过元素在表中的位置(索引)来获取对应的元素值。插入和删除可以在指定的位置上插入新的元素或者移除 现有的元素。 线性表有很多种实现方式,常见的包括数组和链表。数组作为一种静态数据结构,需要提前声明一个固定大小 的空间来存储元素,操作灵活性较差。链表则以节点的形式存储元素,每个节点包含了数据及指向下一个节点 的指针,操作相对灵活,但涉及到频繁的内存分配和释放。 线性表常用的算法包括遍历、查找和排序等。遍历操作用于依次访问线性表中的所有元素。查找操作可以根据 某个条件查找满足要求的元素,常见的方法有线性查找和二分查找。排序操作可以将线性表中的元素按照一定 的规则进行排列,常见的排序算法有冒泡排序、插入排序和快速排序等。 总之,线性表是一种简单、常用的数据结构,能够有效地组织和处理大量的数据,广泛应用于各个领域的算法 与程序设计中。 代码实现 在Java中,我们可以使用数组或链表来实现线性表。 使用数组实现线性表: public class ArrayList { private int size; private Object[] array; public ArrayList() { this.size = 0; this.array = new Object[10]; // 初始化数组大小为10 } public void add(Object item) { if (size == array.
1.1 概念 1) 线程是什么 一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行 着多份代码. 还是回到我们之前
2)进程和线程的区别 进程是包含线程的. 每个进程至少有一个线程存在,即主线程。 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间.
进程是系统分配资源的最小单位,线程是系统调度的最小单位。
3)Java 的线程 和 操作系统线程 的关系 线程是操作系统中的概念. 操作系统内核实现了线程这样的机制, 并且对用户层提供了一些 API 供用户使 用(例如 Linux 的 pthread 库). Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装.
1.2 创建线程 方法1 继承 Thread 类 1) 继承 Thread 来创建一个线程类.
class MyThread extends Thread { @Override public void run() { System.out.println("这里是线程运行的代码"); } } 2) 创建 MyThread 类的实例
3) 调用 start 方法启动线程
有这么一个需求,就是听某个系列的讲课,每个课程前都有101秒的前奏介绍,每一次听的时候都要忍受这101秒的时间,既然学了python ,就把它解决掉。话不多说,上代码干货!
from pydub import AudioSegment import os from multiprocessing import Pool def worker(filename): try: # print(filename) path = r'F:\\55后\\57-114\\test\\' # print(path) path_out = path + '转换后\\' print(path_out) if not os.path.exists(path_out): os.mkdir(path_out) used_name = path + filename print(used_name) ## 因为文件名里面包含了文件的后缀,所以重命名的时候要加上 new_name = path_out + filename input_music = AudioSegment.from_mp3(used_name) # 截取音频前101000毫秒(101秒) output_music = input_music[101000:] # 保存音频 前面为保存的路径wenj ,后面为保存的格式 output_music.export(new_name, bitrate="64k") print(new_name+'完成!') except: ## 跳过一些系统隐藏文档 pass # os.rename(used_name, new_name) if __name__ == '__main__': path = r'F:\\55后\\57-114\\test\\' converted_count = 0 convertlist = [] for filename in os.
numpy 多维函数的声明,属性(shape, size, len)和使用 1. numpy 的 size, shape 和 内建函数len的使用对比 python-numpy 中 的 size shape 和 len 是跑一趟红中的三个内置函数,常用来查询数组的大小属性,以及作为循环控制条件,其发挥着巨大的作用,然而在使用的过程中,大部分人总是容易记混乱,此处给出三者的区别并附带简单的代码复制理解和记忆。
##区别和联系:
1.size ():返回数组中元素总个数;
2.shape():返回数组各个维度对应长度;
3.len ():返回数组第一维度的长度。
##代码举例:
import numpy as np a = np.zeros(shape=(3,4,5)) #返回a数组的元素总数:60(=3 * 4 *5)
print(a.size) print(np.size(a)) #返回a数组的各个维度的大小:(3,4,5)
print(a.shape) print(np.shape(a)) #返回a数组的第一维大小:3
print(len(a)) 2. numpy 中多维矩阵 声明 和使用(索引输出任意行和列) 定义一个多(零)维矩阵
arr = np.array([[1,2,3], [4,5,6], [7,8,9]]) array = np.zeros(shape = (3,4,5)) 取出第一行
arr[0,:] 取出第一列
arr[:,0]
前言:听说有本很牛的关于Java设计模式的书——重学Java设计模式,然后买了(*^▽^*)
开始跟着小傅哥学Java设计模式吧,本文主要记录笔者的学习笔记和心得。
打卡!打卡!
六大设计原则 单一职责原则、开闭原则、里氏替换原则、迪米特法则、接口隔离原则、依赖倒置原则。
(引读:这里的节奏是,先说一下概念定义,然后是模拟场景,最后是反例、正例。)
一、单一职责原则 1、定义 单一职责原则,它规定一个类应该只有一个发生变化的原因。
为什么?
因为如果开发的一个功能不是一次性的,当一个Class类负责超过两个及以上职责时,当需求不断迭代、实现类持续扩张,就会出现难以维护、不好扩展、测试难度大和上线风险高等问题。
2、模式场景 一个视频网站用户分类的例子:
访问用户,只能看480P的高清视频,有广告普通会员,可以看720P的超清视频,有广告VIP会员,付费的大哥,可以看1080P的蓝光视频,无广告 3、违背原则方案(反例) 根据上面的需求,直接编码,实现一个最简单的基本功能:根据不同的用户类型,判断用户可以观看的视频类型。
public class VideoUserService { public void serveGrade(String userType){ if ("VIP用户".equals(userType)){ System.out.println("VIP用户,视频1080P蓝光"); } else if ("普通用户".equals(userType)){ System.out.println("普通用户,视频720P超清"); } else if ("访客用户".equals(userType)){ System.out.println("访客用户,视频480P高清"); } } } 如上,这一个类包含着多个不同的行为,多种用户职责,如果在这样的类上继续扩展功能就会显得很臃肿。比如再加一个“超级VIP会员”,可以超前点播,按上面的实现方式,只能继续ifelse。这样的代码结构每次迭代,新需求的实现都可能会影响到其他逻辑。
4、单一职责原则改善代码(正例) 视频播放是视频网站的核心功能,当完成核心功能的开发后,就需要不断地完善用户权限,才能更好运营网站。其实就是不断建设用户权益,根据不同的用户类型提供差异化服务。
为了满足不断迭代的需求,就不能向上面一样把所有职责行为混为一谈,而是应该提供一个上层的接口类,对不同的差异化用户给出单独的实现类,拆分各自的职责。
(1)定义接口
public interface IVideoUserService { // 视频清晰级别;480P、720P、1080P void definition(); // 广告播放方式;无广告、有广告 void advertisement(); } 定义出上层接口IVideoUserService,统一定义需要实现的功能,包括视频清晰级别接口definition()、广告播放方式接口advertisement()。然后三种不同类型的用户就可以分别实现自己的服务类,做到职责统一。
(2)实现类
1)访问用户,只能看480P的高清视频,有广告
public class GuestVideoUserService implements IVideoUserService { public void definition() { System.
uniapp安卓本地打包成apk 环境准备 1.HBuilderX最新版
2.与HBuilderX版本对应版本的“Android 离线SDK - 正式版”, 下载见:https://nativesupport.dcloud.net.cn/AppDocs/download/android.html
3.Android Studio,官方下载地址:https://developer.android.google.cn/studio?hl=zh-cn
4.java1.8环境
证书(keystore)准备 输入生成证书的命令,格式为:
keytool -genkey -alias 证书别名 -keyalg RSA -keysize 2048 -validity 证书的有效期(单位为天) -keystore 证书文件名.keystore
例如:
keytool -genkey -alias test -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore 之后查看证书,使用命令
keytool -list -v -keystore 证书文件名.keystore
例如:
keytool -list -v -keystore test.keystore 显示的信息如下,重点注意证书指纹信息:SHA1,SHA256,之后要用到
注册登录开发者中心(dcloud) 注册登录开发者中心,网址:https://dev.dcloud.net.cn
创建项目 使用HBuilderX创建uniapp项目
项目创建好后可以在“开发者中心-我的应用”中查看到该应用和Appid
Android平台信息配置与离线打包key获取 点击应用名称进入管理页面
点击各平台信息
点击新增
平台选择Android App,版本选择正式版,输入包名(自定义即可),和证书指纹信息中的SHA1,SHA256值,然后点击提交
提交后点击创建离线打包key
创建好之后然后点击查看
打码部分就是我们需要的离线打包key,之后需要用到
App配置 配置需要支持的CPU类型,我这里全勾了,关于该配置的说明见官网:https://ask.dcloud.net.cn/article/36195
生成本地打包App资源 生成的资源所在路径如下:(我这里_UNI_F60B5A5就是生成的资源)
作者:小小明
https://xxmdmst.blog.csdn.net/article/details/134938026
阅读本文档的前置说明:
本文档用于讲解Python的moviepy库的自带函数的用法,主要目的是讲一下每个函数的每个参数的含义,无需一开始就全部掌握,粗略看一下就行,可以在后面自己开发过程,遇到不会用的函数再回过头来看看本文档,我将在后续的文章中,通过几下实际的案例来理解视频特效的开发流程。
moviepy简介及基本概念 moviepy概述 MoviePy 是一个用于视频编辑的 Python 库,使用户能够处理、编辑和操作视频文件。这个库允许你剪辑视频、添加文本、合并视频剪辑,以及应用各种效果和转换。它建立在 NumPy、imageio 和 Decorator 等库的基础上,使得在处理视频时能够更加高效。
下面是一些 MoviePy 的主要功能和特点:
剪辑和合并视频: MoviePy 允许你从现有视频中选择特定的片段,然后将它们合并成一个新的视频文件。
添加文本和图形: 你可以在视频中添加文本、图形和其他元素,以创建字幕、水印或其他视觉效果。
视频效果: MoviePy 提供了一系列内置的视频效果,如模糊、旋转、缩放等,使用户能够轻松地对视频进行编辑和改进。
音频处理: 除了视频,MoviePy 还支持音频处理,你可以添加音轨、调整音量等。
格式转换: 通过 MoviePy,你可以将视频文件转换为不同的格式,以适应不同的设备和平台。
自定义效果: 如果内置效果不够,你还可以使用 MoviePy 提供的 API 来创建自定义的视频效果。
可以通过 pip 来安装 MoviePy,命令如下:
pip install moviepy 视频剪辑中的mask mask可以译为遮罩、遮片、蒙版,后面本文都称为遮罩。
mask遮罩是一种特殊的视频剪辑,每像素只有一个0-1之间的值(1表示完全可见的像素,0表示透明的像素)mask遮罩可以决定对应视频剪辑对应帧哪些像素可见、哪些不可见。
带mask遮罩的剪辑在导出为GIF或PNG图像时,用于定义图像的透明度。
标准剪辑输出的帧每像素包含RGB的3个0-255之间的值,而遮罩剪辑每像素只有一个0-1之间的值。
RGB、灰度、RGBA、ARGB和PARGB RGB:RGB代表红色(Red)、绿色(Green)、蓝色(Blue),这是最基本的颜色模式。
灰度:共256中颜色,可以理解为RGB数值相等的某个颜色。灰度也可通过百分比表示,范围从0%到100%,表示从纯白到纯黑过度。灰度往往作为判断通道饱和度或透明度的标准。
RGBA和ARGB是RGB加上了透明度(Alpha)通道,它决定了图像中的每个像素的透明度。ARGB的Alpha通道值放在前面,RGBA的Alpha通道值放在后面。
PARGB是预乘Alpha RGB的缩写,其中颜色值已经乘以透明度值。
当一个带alpha通道的透明图像和一个不带alpha通道的不透明图像进行合成时,可以实现一种半透明效果,它们的处理过程称为阿尔法混色。两张图像合成时,带alpha通道的图像一般称为源图像(前景),不带alpha通道的图像为背景图像。RGB值计算公式如下:
合成图像的像素显示颜色=源图像像素颜色 X alpha + 背景图像像素颜色 X (1- alpha)
HSL 和HSV 一般的像素颜色表示使用RGB颜色空间,但美术人员更多的是使用HSV(HSL),因为可以方便的调整饱和度和亮度。
HSL即色相、饱和度、亮度(Hue, Saturation, Lightness),HSV即色相、饱和度、明度(Hue, Saturation, Value),又称HSB,其中B表示Brightness。
背景 还是为了完善高大上的在线文档系统,虽然比着葫芦画瓢的修改了一些所谓的代码,慢慢的才发现,原来这就是传说中的React,所以有比较又要囫囵吞枣一下React。
基本原理 参照《React技术揭秘》 网上有电子版 ,应该是个高手,点赞
概述 前端框架主要的作用是将数据的变化映射为UI的变化: UI=fn(state)
fn就是计算数据的变动导致UI是如何变化的,不同的框架中,fn的描述方式不同
主流的描述方式分为:
jsx:使UI和逻辑更紧密,它是ES语法糖.(从逻辑出发,扩展逻辑,描述UI)模板语法:使用HTML描述UI,它是HTML语法扩展。(从UI出发,扩展UI,描述逻辑) jsx是动态的,即使代码没有变,每次更新,都会重新编译,
模板语法是静态的,可以用来分析,哪些节点是动态的,哪些节点是静态的。有很大的优化空间。
不管是jsx还是模板语法,它们都是组织逻辑和UI的关系
根据UI变化方式(更新细粒度)不同,将框架可以分为三类:
应用级:数据变化时,重新渲染整个应用,React组件级:数据变化时,重新渲染数据有变化的组件Vue元素级:数据变化时,只渲染数据变化的DOM节点,Svelte 按下性能问题暂且不表,先想想,为啥会有这种差别呢?这是因为不同的框架,架构不同导致的。
我们的代码并不是立即执行的,而是先进行编译(语法转换、将ts转为js、压缩、polyfill等),将我们的代码转为宿主环境可以识别的代码。
React React经过编译之后返回的是createElement函数,所以每次数据变化,React都会从应用根节点重新加载整个应用。因此React无需知道是哪个变量发生变化导致的更新。
export const App = () => { const [count, setCount] = useState(0); return /*#__PURE__*/React.createElement("div", { onClick: () => setCount(conut++) }, count); }; 所以这种框被架称为应用级框架
Vue3 Vue3经过编译之后返回的是组件的render函数,Vue3会为每个组件建立watchEffect事件,这个大致如下:
在页面首次进入或者watchEffect的依赖项发生变化时,都会调用组件的render函数。
render函数的返回值是本次更新的VNode,Vue会根据本次更新的VNode与上次更新做比较(patch),找到最优的更新路径,并且进行更新。 所以这种框架被称为组件级框架
function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createElementBlock("h1", { onClick: _cache[0] || (_cache[0] = $event => (_ctx.count++)) }, _toDisplayString(_ctx.
什么是进程/任务(Process/Task)
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程; 同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。
进程控制块抽象(PCB Process Control Block)
class PCB { // 进程的唯一标识 —— pid;
}
每一个 PCB 对象,就代表着一个实实在在运行着的程序,也就是进程。
CPU 分配 —— 进程调度(Process Scheduling)
操作系统对CPU资源的分配,采用的是时间模式 —— 不同的进程在不同的时间段去使用 CPU 资源。
内存分配 —— 内存管理(Memory Manage)
操作系统对内存资源的分配,采用的是空间模式 —— 不同进程使用内存中的不同区域,互相之间不会干 扰。
进程调度的基本过程
进程到达:一个新进程到达系统并被添加到就绪队列中。进程选择:调度器从就绪队列中选择一个进程在CPU上运行。选择算法可以基于优先级、最短作业优先、循环等标准。上下文切换:当CPU从一个进程切换到另一个进程时,需要保存第一个进程的当前状态,并加载保存第二个进程的状态。进程执行:选定的进程在CPU上执行一定的时间,称为时间片。在此期间,进程可以执行其操作并使用系统资源。进程终止:一个进程完成执行后,从系统中删除。进程抢占:如果高优先级的进程进入就绪队列,而低优先级的进程正在执行,高优先级的进程可以抢占低优先级的进程,从而控制CPU。重复:对系统中的每个进程重复上述步骤,直到所有进程完成。 此外,进程调度中涉及的要素还包括:
进程状态:包括运行、就绪和阻塞三种状态。进程的优先级:优先级高的进程理论上会被更多更快的调度到CPU上执行。上下文信息:记录了进程当前执行到哪里,包括CPU内部的寄存器值等。记账信息:记录了每个进程在CPU上执行了多久,可以作为调度的参考依据。 冯诺依曼体系(Von Neumann Architecture) 冯诺依曼体系结构是由数学家冯诺依曼提出的计算机制造的三个基本原则和计算机的五个组成部分构成的。其中三个基本原则是:采用二进制逻辑、程序存储执行以及计算机由五个部分组成(运算器、控制器、存储器、输入设备、输出设备)。
五个组成部分包括:输入设备、输出设备、存储器、运算器和控制器。
作者:小小明
地址:https://xxmdmst.blog.csdn.net/article/details/134938026
CSDN - 小小明
本文用于讲解Python的moviepy库的自带函数的用法,主要目的是讲一下每个函数的每个参数的含义,无需一开始就全部掌握,粗略看一下就行,可以在后面自己开发过程,遇到不会用的函数再回过头来看看本文档。
moviepy简介及基本概念 moviepy概述 MoviePy 是一个用于视频编辑的 Python 库,使用户能够处理、编辑和操作视频文件。这个库允许你剪辑视频、添加文本、合并视频剪辑,以及应用各种效果和转换。它建立在 NumPy、imageio 和 Decorator 等库的基础上,使得在处理视频时能够更加高效。
下面是一些 MoviePy 的主要功能和特点:
剪辑和合并视频: MoviePy 允许你从现有视频中选择特定的片段,然后将它们合并成一个新的视频文件。
添加文本和图形: 你可以在视频中添加文本、图形和其他元素,以创建字幕、水印或其他视觉效果。
视频效果: MoviePy 提供了一系列内置的视频效果,如模糊、旋转、缩放等,使用户能够轻松地对视频进行编辑和改进。
音频处理: 除了视频,MoviePy 还支持音频处理,你可以添加音轨、调整音量等。
格式转换: 通过 MoviePy,你可以将视频文件转换为不同的格式,以适应不同的设备和平台。
自定义效果: 如果内置效果不够,你还可以使用 MoviePy 提供的 API 来创建自定义的视频效果。
可以通过 pip 来安装 MoviePy,命令如下:
pip install moviepy 视频剪辑中的mask mask可以译为遮罩、遮片、蒙版,后面本文都称为遮罩。
mask遮罩是一种特殊的视频剪辑,每像素只有一个0-1之间的值(1表示完全可见的像素,0表示透明的像素)mask遮罩可以决定对应视频剪辑对应帧哪些像素可见、哪些不可见。
带mask遮罩的剪辑在导出为GIF或PNG图像时,用于定义图像的透明度。
标准剪辑输出的帧每像素包含RGB的3个0-255之间的值,而遮罩剪辑每像素只有一个0-1之间的值。
RGB、灰度、RGBA、ARGB和PARGB RGB:RGB代表红色(Red)、绿色(Green)、蓝色(Blue),这是最基本的颜色模式。
灰度:共256中颜色,可以理解为RGB数值相等的某个颜色。灰度也可通过百分比表示,范围从0%到100%,表示从纯白到纯黑过度。灰度往往作为判断通道饱和度或透明度的标准。
RGBA和ARGB是RGB加上了透明度(Alpha)通道,它决定了图像中的每个像素的透明度。ARGB的Alpha通道值放在前面,RGBA的Alpha通道值放在后面。
PARGB是预乘Alpha RGB的缩写,其中颜色值已经乘以透明度值。
当一个带alpha通道的透明图像和一个不带alpha通道的不透明图像进行合成时,可以实现一种半透明效果,它们的处理过程称为阿尔法混色。两张图像合成时,带alpha通道的图像一般称为源图像(前景),不带alpha通道的图像为背景图像。RGB值计算公式如下:
合成图像的像素显示颜色=源图像像素颜色 X alpha + 背景图像像素颜色 X (1- alpha)
HSL 和HSV 一般的像素颜色表示使用RGB颜色空间,但美术人员更多的是使用HSV(HSL),因为可以方便的调整饱和度和亮度。
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 在 Golang 领域,并发发送 HTTP 请求是优化 Web 应用程序的一项重要技能。本文探讨了实现此目的的各种方法,从基本的 goroutine 到涉及通道和sync.WaitGroup 的高级技术。我们将深入研究并发环境中性能和错误处理的最佳实践,为你提供提高 Go 应用程序速度和可靠性的策略。让我们深入探讨 Golang 中并发 HTTP 请求的世界!
使用 Goroutines 的基本方法 当谈到在 Golang 中实现并发时,最直接的方法是使用 goroutine。这些是 Go 中并发的构建块,提供了一种简单而强大的并发执行函数的方法。
Goroutine 入门 要启动一个 goroutine,只需在函数调用前加上go关键字即可。这会将函数作为 goroutine 启动,从而允许主程序继续独立运行。这就像开始一项任务并继续前进而不等待它完成。
例如,考虑发送 HTTP 请求的场景。通常,你会调用类似 的函数sendRequest(),并且你的程序将等待该函数完成。使用 goroutine,你可以同时执行此操作:
go sendRequest("http://example.com") 处理多个请求 假设你有一个 URL 列表,并且需要向每个 URL 发送一个 HTTP 请求。如果没有 goroutine,你的程序将一个接一个地发送这些请求,这非常耗时。使用 goroutine,你几乎可以同时发送它们:
urls := []string{"http://example.com", "http://another.com", ...} for _, url := range urls { go sendRequest(url) } 这个循环为每个 URL 启动一个新的 goroutine,大大减少了程序发送所有请求所需的时间。
项目场景: gcc版本过低导致redis安装失败: 问题描述 错误:没有*成员等,具体上图看: 原因分析: gcc版本过低,图上为4.8.5:
命令如下:
gcc --version 解决方案: 升级gcc:
命令如下:
yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash 再次查看gcc版本:
前言 Linux环境--redis安装:
一、下载redis redis官网地址:http://www.redis.io/
下载地址:http://download.redis.io/releases/
redis中文文档地址:http://www.redis.cn/documentation.html
注意:示例版本为6.2.4,且gcc的版本过低,会导致redis安装不成功,如果遇到gcc版本过低导致redis安装失败,参考https://blog.csdn.net/qq_42390993/article/details/135598607?spm=1001.2014.3001.5502
二、使用步骤 1.解压包 注意:进入到服务器接收文件路径上
命令如下:
cd /data/softwore ll tar -zxvf redis-6.2.4.tar.gz cd redis-6.2.4 2.安装 命令如下:
mkdir /usr/local/redis mkdir /usr/local/redis/conf make make install PREFIX=/usr/local/redis cp redis.conf /usr/local/redis/conf/ 3.修改配置文件 命令如下:
vi /usr/local/redis/conf/redis.conf 找到下面的参数进行修改,然后保存
requirepass 密码
daemonize yes
找到bind 127.0.0.1,把它进行注释
注意:笔记本中i为输入,修改完,Esc后,输入:wq!,强制保存,退出
4.启动 命令如下:
cd /usr/local/redis/bin ./redis-server ../conf/redis.conf 5.验证 命令如下:
ps -ef|grep redis 5.防火墙开放端口 命令如下:
增加需开放的端口 firewall-cmd --add-port=6379/tcp --permanent 防火墙重新加载配置 firewall-cmd --reload 查看所有开放的端口 firewall-cmd --zone=public --list-ports