颜色矩(Color Moments)是一种常用的图像特征描述方法,用于表示图像中颜色的分布和统计特征。它是基于图像的颜色直方图而计算得到的。
颜色矩通常包括三个维度:平均值、方差和偏度。具体来说:
平均值(Mean):表示图像中颜色分布的平均值,可以分别计算每个颜色通道(如红、绿、蓝)的平均值。
方差(Variance):表示图像中颜色分布的离散程度,用于反映颜色的变化范围。方差越大,表示颜色分布越分散。
偏度(Skewness):描述颜色分布的偏斜程度,用于判断颜色分布的对称性。正偏斜表示颜色分布向右偏移,负偏斜表示颜色分布向左偏移。
通过计算这些颜色矩特征,我们可以获得关于图像颜色分布的统计信息。这些特征可以应用于图像检索、图像分类、目标识别等领域。在图像检索中,我们可以根据颜色矩特征的相似度进行图像的匹配和检索。
需要注意的是,颜色矩是一种简化的颜色特征表示方法,它忽略了颜色之间的空间关系。因此,在某些情况下,可能需要结合其他特征描述方法来获得更全面的图像特征表示。
总结起来,颜色矩是一种基于颜色直方图的图像特征描述方法,用于表示图像中颜色的分布和统计特征。它在图像处理和相关应用中具有广泛的应用价值。
写在前面的话:很久没有使用C/C++进行编程了,这次在MAC电脑的vscode中对C/C++代码进行调试时,发现运行到scanf、cin等输入语句时无法输入,参考了网上一些教程,发现有些繁琐或是难以解决我的问题。因此以本文记录最终的解决方案,一来为了记录以便下次遇到时进行解决,二来希望同大家交流探讨。
一、问题描述 这里用一个简单的输入输出示例说明我遇到的问题。当我进行调试时,发现程序的输出是在调试控制台,并且在这里我无法进行输入。(也就是对应scanf的那条语句开始无法继续向下推进)。
因此,我需要寻求方法,解决调试过程中无法进行输入的问题。
二、解决方法 (有多种解决方法,这里选择我认为最易于进行的方法)
Step1:下载相关插件(这一步简单带过)
安装CodeLLDB的扩展插件。
Step2:生成可执行文件
这里既可以直接在终端中输入g++命令,也可以直接点击vscode右上角的运行按钮。
经过这一步,我们会发现当前目录下生成了可执行文件。此时,我们就可以进行调试了。
Step3:调试(修改launch.json文件)
按fn+F5(建议这种方法不要选择右上角的调试按钮),然后选择LLDB调试器。
可以看到在当前目录下多了.vscode文件夹,并且自动创建了launch.json文件。(这个时候直接进行调试会报错/仍然无法处理输入问题)
这里我们需要修改两个地方:
1、使用集成终端来运行和调试程序:增加 “terminal”: “integrated”,
2、运行当前文件所在目录下的同名可执行文件:修改program属性为:“${workspaceFolder}/${fileBasenameNoExtension}”
如下图所示,为了方便复制,把这段configurations粘贴在这里:
"configurations": [ { "type": "lldb", "request": "launch", "name": "Debug", "terminal": "integrated", "program": "${workspaceFolder}/${fileBasenameNoExtension}", "args": [], "cwd": "${workspaceFolder}" } ] 至此,修改完成。此时我们再按fn+F5,发现调试可以处理我们的输入语句了。
三、解决每次都需要修改配置文件的方法 在上面的步骤中,已经能解决在当前项目下debug无法处理输入的问题了。但是如果换一个项目,依然要重新经历一次上面的配置修改,较为麻烦。因此考虑解决每次都需要重新修改配置文件的问题。(一种比较简便的方法是将配置文件保存成模板,新建项目后拷贝进去)这里介绍一种更方便的方法:在VSCode的全局用户设置中配置一个默认的launch.json文件。
使用快捷键command+,打开设置。点击settings.json,这个文件是用来存储VS Code的全局用户设置的。
找到名为"launch"的属性,它的值是一个对象,对象中包含了我们想要配置的launch.json文件的内容。
根据我们这次的内容修改为如下所示:
此后,我们即使新建一个项目,不需要重新配置调试也可以处理输入了。
个人记录:python是解释类型的语言,与之处理方式不同。经过一些处理,在本电脑下调试时直接按右上角的调试按钮选择python调试进行调试即可。
下载go SDK All releases - The Go Programming Language
此处建议选择与本机windows一样的版本,便于调试,若不涉及本地windows,则忽略此提示
上传到linux
解压go SDK 执行下述命令进行解压
tar -xvf go1.19.linux-amd64.tar.gz 此处选择的原地解压,也可以解压到指定的其他目录
配置环境变量 将解压后的go/bin添加到环境变量
export PATH=$PATH:/root/goDebug/go/bin 检查版本 若能够成功执行go version,并且输出的结果是预期安装的版本,则说明go sdk 已经安装成功
🌈个人主页:聆风吟
🔥系列专栏:数据结构、网络奇遇记
🔖少年有梦不应止于心动,更要付诸行动。
文章目录 📋前言一. 什么是AIGC?二. AIGC的主要特征2.1 文本生成2.2 图像生成2.3 语音生成2.4 视频生成 三. AIGC如何运作?3.1 步骤一:收集数据3.2 步骤二:模型训练3.3 步骤三:内容生成3.4 步骤四:反馈和改进 四. AIGC关键技术能力五. 应用领域六. AIGC的优势和挑战6.1 优势6.2 挑战 📝结语 📋前言 随着人工智能技术的不断发展,我们进入了一个信息爆炸的时代,信息量庞大,但也难免产生了信息过载的问题。为了解决这一问题,人工智能生成内容技术(AIGC)应运而生。
生成式人工智能AIGC(Artificial Intelligence Generated Content)是人工智能1.0时代进入2.0时代的重要标志。
一. 什么是AIGC? AIGC是一种新的人工智能技术,它的全称是Artificial Intelligence Generative Content,即人工智能生成内容。
它是一种基于机器学习和自然语言处理的技术,能够自动产生文本、图像、音频等多种类型的内容。这些内容可以是新闻文章、小说、图片、音乐,甚至可以是软件代码。AIGC系统通过分析大量的数据和文本,学会了模仿人类的创造力,生成高质量的内容。
二. AIGC的主要特征 现阶段国内AIGC多以单模型应用的形式出现,主要分为文本生成、图像生成、视频生成、音频生成,其中文本生成成为其他内容生成的基础。
2.1 文本生成 文本生成(AI Text Generation),人工智能文本生成是使用人工智能(AI)算法和模型来生成模仿人类书写内容的文本。它涉及在现有文本的大型数据集上训练机器学习模型,以生成在风格、语气和内容上与输入数据相似的新文本。
2.2 图像生成 图像生成(AI Image Generation),人工智能(AI)可用于生成非人类艺术家作品的图像。这种类型的图像被称为“人工智能生成的图像”。人工智能图像可以是现实的或抽象的,也可以传达特定的主题或信息。
2.3 语音生成 语音生成(AI Audio Generation),AIGC的音频生成技术可以分为两类,分别是文本到语音合成和语音克隆。文本到语音合成需要输入文本并输出特定说话者的语音,主要用于机器人和语音播报任务。到目前为止,文本转语音任务已经相对成熟,语音质量已达到自然标准,未来将向更具情感的语音合成和小样本语音学习方向发展;语音克隆以给定的目标语音作为输入,然后将输入语音或文本转换为目标说话人的语音。此类任务用于智能配音等类似场景,合成特定说话人的语音。
2.4 视频生成 视频生成(AI Video Generation),AIGC已被用于视频剪辑处理以生成预告片和宣传视频。工作流程类似于图像生成,视频的每一帧都在帧级别进行处理,然后利用 AI 算法检测视频片段。AIGC生成引人入胜且高效的宣传视频的能力是通过结合不同的AI算法实现的。凭借其先进的功能和日益普及,AIGC可能会继续革新视频内容的创建和营销方式。
三. AIGC如何运作? 通过单个大规模数据的学习训练,令AI具备了多个不同领域的知识,只需要对模型进行适当的调整修正,就能完成真实场景的任务。AIGC的工作原理可以分为以下几个步骤:
3.1 步骤一:收集数据 AIGC 需要大量的数据来学习和理解人类创作的内容。这些数据可以包括书籍、文章、图片、音频和视频等各种形式的媒体。
24 双非硕的秋招总结
结果:运气捡漏去了腾讯想想自己整个研究生学习过程,还是挺坎坷的,记录一下,也给未来的同学提供一些参考。研一我是研一上开始学前端的,应该是21年10月份左右,我们
华为现在还没面试,笔试154,是不是G了
华为11.13号投的,笔试分数154,HR说11.29面试的,后来一问说12月的第一个星期面试,现在还没给我发邮件,是不是G了,面试机会都没有😨
题解 | #整数与IP地址间的转换#
#include <iostream>#include <string>#include <vector>#include 题解 | #删除链表的倒数第n个节点#
import java.util.*;/* * public class ListNode { * int val; * ListNode next =
题解 | #链表内指定区间反转#
import java.util.*;/* * public class ListNode { * int val; * ListNode next =
题解 | #二叉树的前序遍历#
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *r
请问什么时候会有题解?
rt
家境真的重要吗?
如题头一次感到好无力,好累啊天津高考去我本科学校同专业比我低50分,那我高中起早摸黑这么奋战的意义是什么?
from PIL import Image import os def png_to_jpg(png_path, jpg_path): image = Image.open(png_path) rgb_image = image.convert('RGB') rgb_image.save(jpg_path, 'JPEG') # 文件夹路径 folder_path = "path/try" # 获取文件夹中的所有文件 file_list = os.listdir(folder_path) # 循环处理每个文件 for png_filename in file_list: # 检查文件扩展名是否为 .png if png_filename.lower().endswith('.png'): jpg_filename = png_filename[:-4] + '.jpg' # 替换扩展名为 .jpg png_path = os.path.join(folder_path, png_filename) jpg_path = os.path.join(folder_path, jpg_filename) png_to_jpg(png_path, jpg_path) print(f"Converted {png_filename} to {jpg_filename}")
1、背景 springboot的pagehelper插件能够实现对mybatis查询的分页管理,而且在使用时只需要提前声明即可,不需要修改已有的查询语句。使用如下:
之前对这个功能一直很感兴趣,但是一直没完整看过,今天准备详细梳理下。按照个人的习惯,我喜欢带着问题去看源码,这次浏览源码我希望可以了解以下两个问题:
1)分页插件什么时候被加载的
2)分页插件什么时候生效的,如何生效的
2、技巧(可跳过) mybatis自身的功能原理这里我们不深入探讨,网上文章很多,我之前也写过类似的文章,这里为了防止文章杂乱,我们只关注感兴趣的点,即mybatis pagehelper分页原理,其它的一笔带过。另外因为mybatis查询生效都是用的代理对象。如果对源码不是很熟悉,很难第一时间找到打断点的位置。不过通过查看page的源码可以知道,最后的分页参数都放到了threadlocal对象里,如下:
而最后使用该threadlocal时是一定会调用它的获取和移除方法,因此我们在它的这两个方法中加断点。等进入断点后再通过方法栈追踪其全流程。如下:
3、源码追踪流程 有了上述方法栈的查看,我们知道了查询的入口和大体流程,现在重新执行查询跟随源码脚步来详细看下分页的实现逻辑。首先是在代码中我们主动进行分页查询,如下:
前三行代码很简单,主要是从httpservletrequest中获取分页参数,并设置到当前线程的threadlocal变量中。第四行则是调用接口方法进行查询。在mybatis中,接口方法最终功能的实现主要是依靠MapperProxy代理类实现(代理类中包含接口和xml配置相关信息),所以接下来我们直接到MapperProxy中打断点追踪(至于mybatis如何关联接口和mapper.xml文件,MapperProxy如何生成等问题不是本文讨论重点,感兴趣的可以单独去查阅或者浏览我以前的相关文章)。
MapperProxy是代理对象,主要调用方法是invoke方法,所以在该方法中加断点,或者依靠第二步中的技巧查看整个查询的方法栈,随后再在MapperProxy对应的行中加断点。具体断点信息如下:
因为method不是Object类型,所以执行else里面的代码:
可以看到最后会执行PlainMethodInvoker对象里的invoke方法,所以我们接着到该方法中打断点并继续追踪查看:
可以看到调用SqlSessionTemplate对象的selectList方法,我们接着向下看:
再接着到DefaultSqlSession中继续查看:
可以看到,最后会调用CachingExecutor的query方法,但是这里要留意一点,那就是CachingExecutor是一个代理对象,执行代理对象方法首先要进入代理,并执行invoke方法。我们这里通过断点调试的步入查看执行哪个类的invoke方法:
可以看到最终是通过Plugin代理实现CachingExecutor对象query方法的调用。我们再接着向下看:
因为要执行的方法是查询方法,其是分页拦截器指定要拦截的方法类型,所以会进入拦截方法中。这里我标记了两个框,第一个是拦截,第二个是不进行拦截直接执行查询方法,因此可以推测分页逻辑是再拦截器中进行的。拦截器中会进行sql的改写,所以这里进入拦截器中进一步查看。拦截器对象为PageInterceptor,到这终于和本文的主题关联上了,接下来我们到分页拦截器中看一下:
可以看到源码中都加好注释了,看起来就更简单了,这里我们看下进入分页的条件:
可以看到最后获取的page对象实际上就是我们一开在代码中传入分页参数创建的page对象。因为page对象不为空,所以会返回false,进而不跳过分页逻辑。(另外这里要提醒下各位小伙伴,page对象继承了ArrayList,所以断点查看时看不得page里面的内容,只能看到其size为0。)
我们接着回到主流程向下看,随后会判断是否需要计算总数,默认创建page时需要计算总数,这里我们就不进入before方法查看了,里面逻辑比较简单。下面我们简单看下计算总数的逻辑:
可以看到其计算总数的sql比较精简,主要是根据查询的对象和条件直接计算总数。这里sql的解析和生成主要是依赖jsqlparser工具类实现(jsqlparser的使用可以参考我以前的文章),sql解析比较复杂,感兴趣的可以自行查看。接着我们再回到主流程,看下何时添加的分页查询参数:
可以看到最后再sql末尾加了limit分页参数,而这个sql的改写过程与计算count类似,都是通过jsqlparser工具实现的。
通过上面的流程,我们已经知道了分页插件如何生效的了。但是还有一个问题是分页插件如何被加载的。这个流程比较简单,我也是通过第二步的技巧逆推的全流程。下面我按照正常项目的加载顺利简单介绍下:
当我们在pom中引入pageHelper插件依赖并且在yml中配置分页相关的信息时,项目启动后就会主动的进行插件的初始化并注入到插件拦截器链里面。大体逻辑如下:
可以看到分页插件有个配置类,其在项目初始化的时候会创建分页拦截器,并调用Configuration进行添加,接着我们看下最后会将拦截器添加到哪里:
可以看到最终会添加到拦截器链对象的私有集合里。但是我们最终使用拦截器是在Plugin对象里用的,而不是在拦截器链里面,那Plugin如何使用到该拦截器的呢?
在拦截器链里有个pluginAll方法,它会封装拦截器成一个“链式”动态代理对象,代理类是Plugin,该方法会在创建Executor时执行(还记得前面源码里介绍这块的提醒吧,Executor是一个被动态代理的对象),通过pluginAll方法,将拦截器封装成链并将Executor放在链路最后一层。
可以看到通过pluginAll方法将拦截器封装成了一个链,下面再看一下Executor的创建就完全清晰了:
至此,我们两个问题都再浏览源码的过程中清晰了。
4、总结 1)该文章主要是探究sringboot分页插件实现的原理,所以对于mapper.xml与接口方法的整合和mybatis代理对象如何实现查看没有细讲,但是这部分也是查询过程中核心的代码。
2)由PageInterceptor分页拦截器拦截指定的查询请求,然后在拦截方法中调用PageHelper中的方法对sql进行改写,最后再进行提交。
2)无论计算总数还是重写分页sql,都是通过jsqlparser工具实现的(为了使得文章主题清晰,这里没有介绍sql的改写过程,jsqlparser的使用可以浏览我以前的文章)
3)Plugin是一个链式动态代理对象,最后一个节点是Executor被代理对象,前面的节点是Interceptor被代理对象。
4)再Plugin.wrap方法中会提取出拦截器里的signature标签,并保存在每个Plugin链式代理对象中。在被代理对象执行对应方法时,如果plugin代理对象包含对应的signature集合则说明当前被代理对象是拦截器,如果不包含signature或者signature标签没有拦截当前方法,则直接执行当前方法。
参考文章: 5分钟!彻底搞懂MyBatis插件+PageHelper原理 - 知乎
文章目录 1、数组splice方法2、数组排序sort方法3、数组操作(数组的增删改查)`.unshift(参数)` 数组最前方增加`.push(参数)` 数组末尾增加`.shift()` 删除数组第一个元素`.pop()` 删除数组末尾元素 4、数组其它方法`concat()` 连接俩个数组`includes()`查找数组里是否包含一个值`indexOf ()`正向查找数组元素返回索引`lastIndexOf ()` 反向查找数组元素返回索引`join()`指定分隔符连接数组元素`forEach()``map()``forEach()`和`map()` 的区别`find()`返回满足条件的第一个元素`findIndex()`查找满足条件的第一个元素的索引`some()`一些`every()`每个`reverse()` 翻转`filter()` 过滤`reduce()`减少`flat()`数组扁平化`Array.from()`ES6`Array.isArray ()`ES6 1、数组splice方法 数组名.splice(起时索引,删除元素个数,要添加的元素,要添加的元素,…)返回值:被删除的元素组成的数组 const arr = ['a', 'b'] //(增加)在a和b之间增加俩个元素c和d const res = arr.splice(1, 0, 'c', 'd') console.log(res) // ['a', 'c', 'd', 'b'] //(删除)删除序号为1的元素 const res2 = arr.splice(1, 1) console.log(arr) // ['a', 'c', 'd', 'b'] console.log(res2) // ['a'] //(替换) 把b->e const res3 = arr.splice(1, 1, 'e') console.log(res3) //['a', 'b'] console.log(res3) //['a', 'e'] 2、数组排序sort方法 sort()方法是数组对象的一个方法,用于对数组的元素进行排序。这个方法会改变原数组的顺序。默认情况下,sort()方法按照字符串Unicode码点顺序进行排序。也就是说,它把每个元素都转换成字符串,然后按照每个字符串的Unicode编码顺序进行排序。如果你想按照自定义的规则进行排序,你可以提供一个比较函数作为sort()方法的参数。这个比较函数应该接收两个参数,如果第一个参数应该排在第二个参数前面,那么比较函数应该返回一个负数。如果两个参数相等,那么比较函数应该返回0。如果第一个参数应该排在第二个参数后面,那么比较函数应该返回一个正数。 const arr = [10, 2, 5, 1, 9,3 ] // sort排序 默认按照字符串排序 // arr.
文章目录 正则表达式(Regular Expression)使用场景:定义语法:判断是否符合规则的语法:元字符下面是一些示例: 正则表达式(Regular Expression) 正则表达式(Regular Expression,通常简写为regex)是一种在计算机科学中常用的语法规则,用于匹配字符串模式。它是由一系列的字符、符号和规则组成,可以用来搜索、替换、拆分等操作字符串。
使用场景: 一般使用在账号、密码、身份证、验证码、电话号码等一些验证中
定义语法: 在JavaScript中,正则表达式被定义为一个对象,可以通过正则表达式的字面量或者使用RegExp构造函数来创建
// 字面量方式创建正则表达式 let regex = /abc/; // 使用RegExp构造函数创建正则表达式 let regex = new RegExp('abc'); 判断是否符合规则的语法: regObj.test(被检测的字符串)
如果正则表达式与指定的字符串匹配,返回true,否则返回false
// lg // 要检测的字符串 const str = '人之初,性本善' // 定义正则表达式检测规则 const reg = /本善/ // 检测方法 console.log(reg.test(str)) // true regObj.exec(被检测的字符串)
如果有匹配的的字符串返回一个数组,没有返回null
// lg // 要检测的字符串 const str = '人之初,性本善' // 定义正则表达式检测规则 const reg = /本善/ // 检测方法 console.log(reg.exec(str)) // 返回一个数组 // ['本善',index:5,input:'人之初,性本善'] 元字符 边界符^匹配输入字符串的开始位置$匹配输入字符串的结束位置.
时间复杂度习题演练 导言分析方法与步骤单层循环嵌套循环 单项选择题题目1题目解析 题目2题目解析 题目3题目解析 题目4题目解析 题目5题目解析 题目6题目解析 题目7题目解析 题目8题目解析 题目9题目解析 题目10题目解析 结语【数据结构】第一章——绪论 导言 本篇章题目出自:王道考研系列丛书——《2024年数据结构考研复习指导》课后习题。
题目主要考察的是对时间复杂度的分析,在前面的篇章中我们知道时间复杂度是与问题规模n和输入的值k有关的,但是我们在分析时间复杂度时都是以最坏时间复杂度进行分析,这样能确保算法的运行时间不会比它更长。
分析方法与步骤 对于时间复杂度的分析,我自己的经验是通过递进语句与条件判断语句来找出程序运行时间与问题规模之间的关系。
因为我们在分析时间复杂度是都是分析的最坏时间复杂度,所以此时是忽略输入值带来的影响,默认初始值为最小值,之后我们只需要确认最小值是如何通过递进条件来逼近问题规模就行了。
这里我通过下面两个列子来说明:
单层循环 void Func(int n) { for (int i = 0; i < n; i++) { printf("hello world\n"); } } 在这个函数中,我们想要分析它的时间复杂度,可以按照以下步骤一步一步来分析:
第一步:找到问题规模
我们从条件语句i < n;可以很容易的得到这个问题的问题规模为n,当i = n 成立时循环结束; 第二步:找到递进方式
通过对象语句int i = 0;和递进语句i++; 我们能够知道,此时的对象需要每执行一次递进都会在原先的基础上增加1; 第三步:找到执行次数与问题规模之间的关系
当变量 i 执行 1 次递进语句时,i 就会从0变成1;当变量 i 执行 t 次递进语句时,i 就会从0变成 t;当t = n 时,i 就会从0变成 n;
项目场景: 在stm32项目中为了调试将某些参数打出来,重定向printf
问题描述 printf打印不出东西
缓冲区满了才打印出来
原因分析: 使用printf函数必须等到缓冲区满或程序结束时,才进行写入到屏幕
解决方案: 解决方法一:加 \n 回车
解决方法二: 加 fflush(stdout); 刷新输出流将缓冲区中的数据立即写入到文件(或显示设备)中,而不是等到缓冲区满或程序结束时才进行写入。
解决方法三: 在初始化中加入 setvbuf(stdout, NULL, _IONBF, 0); 将缓冲区置为0
#搬运过来的,看不懂请看原出处
原作者:
熊荣川
六盘水师范学院生物信息学实验室
xiongrongchuan@126.com
http://blog.sciencenet.cn/u/Bearjazz
通常在R语言中矩阵(表格)数据的填充默认顺序为先列后行,从左到右。如果需要先行后列的填充数据的话,可是使用byrow=TRUE这个参数实现,具体过程请参考下面的两个例子。
a=matrix(1:30, 5,6)
建立矩阵a,三个参数分别表示数据源,5行、6列
a
查看a
[,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 6 11 16 21 26
[2,] 2 7 12 17 22 27
[3,] 3 8 13 18 23 28
[4,] 4 9 14 19 24 29
[5,] 5 10 15 20 25 30
[,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 2 3 4 5 6
[2,] 7 8 9 10 11 12
需求背景 需要在如图所示的列表中播放视频,并且播放视频在对应的卡片上,滚动结束的时候, 完整露出封面图的第一个视频自动播放
分析 根据需求,是滚动的时候获取符合条件的cell,并且
在cell的封面图上播放视频,从上往下,第一个完全展示的
cell播放视频
这就要求,我们的播放器应该是页面级别的,而不应该是cell 级别的,并且ZFPlayer框架支持这种自动播放的需求,
但是和我们的有些不同,我们这个列表是多种cell同时存在的,但是只有一种cell支持自动播放,所以要求我们进行
定制化开发
获取当前适合条件的cell 其实zfplayer是有获取当前符合条件的cell的方法的,但是
和我们的判断条件不一样,并且滚动回调是在这里设置的
如图,这里要我们ZFPlayer必须存在,但是我们页面消失之后,回
销毁ZFplayer,如果再回到这个页面,再滚动页面的时候,就没有这个
回调了,所以,我们直接在页面的scrollview代理方法中调用
如下代码
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [super scrollViewDidEndDecelerating:scrollView]; [self findCorrectCell]; } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { [super scrollViewDidEndDragging:scrollView willDecelerate:decelerate]; if (!decelerate) { [self findCorrectCell]; } } - (void)findCorrectCell { if (self.channelBannerTool.playerView.currentPlayerManager.isPlaying) { //如果正在播放广告, 不自动播放 return; } NSArray *cells = self.tableView.visibleCells; CGFloat scrollViewMidY = CGRectGetHeight(self.tableView.frame)/2; /// The final playing indexPath. __block NSIndexPath *finalIndexPath = nil; @weakify(self) [cells enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL * _Nonnull stop) { @strongify(self) if (!
数据结构的基本概念 导言一、基本概念和术语1.数据定义记忆定义理解定义 2.数据元素定义记忆定义理解定义 3.数据对象定义记忆定义理解定义 4.数据结构定义记忆定义理解定义数据结构与数据对象 5.数据类型定义记忆定义 分类原子类型结构类型抽象数据类型(Abstract Data Type, ADT)理解定义原子类型结构体类型抽象数据类型 总结 二、数据结构的三要素1.数据的逻辑结构定义分类集合线性结构树图 2.数据的存储结构定义分类顺序存储定义优缺点 链式存储定义优缺点 索引存储定义优缺点 散列存储定义优缺点 3.数据的运算 结语【数据结构】第一章——绪论博客同步声明 导言 大家好,今天开始,我将开始从原先的专心学习C语言调整到边学习C语言,边学习数据结构的相关内容。
当然,在学习的过程中我也会将各个知识点通过博客记录下来并将自己对知识点的理解分享给大家。
本章内容是数据结构的概述,我们可以通过对本章内容的学习,初步了解数据结构的基本内容和基本方法。
一、基本概念和术语 1.数据 定义 数据是信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。
记忆定义 我对该定义的记忆方式是先抓主干,后补充细节。
主干:数据是一个载体,它也是一个集合,它更是一种原料。
细节:数据作为信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合,是计算机程序加工的原料。
理解定义 我们可以简单的理解为,描述客观事物属性的相关信息是通过承载在数据上然后再被计算机程序加工,最后呈现在我们面前。
就比如这篇博客,呈现在我们面前的就是一些图文,这些图文呈现的步骤就是:
先通过我输入相应的字符,然后计算机在识别这些字符后通过一系列的处理,最终将这些信息呈现出来。
在C语言中我们学到了计算机能够识别的内容就是二进制序列,计算机能处理的内容也是二进制数列。下面我们通过流程图来理解这个过程:
从图中我们应该能更好的理解数据以及它在计算机中的一个运行流程,这里我再进行一次文字解释:
我们在计算机上开始操作后,
首先是先将我们需要输入的信息通过字符、数字、符号等形式输入进计算机,此时我们输入的信息承载在数据上;然后这些数据会将信息运送给计算机,计算机开始加工这些数据,加工的过程是先识别这些信息的二进制序列,再将这些二进制序列处理成我们想要的内容;最后我们想要的这些内容作为需要输出的信息,将会再一次承载在数据上,通过数据,输送到我们的屏幕上进行输出。 ☆☆☆我们输入和计算机输出的内容就是数据。
2.数据元素 定义 数据元素是数据的基本单位,通常作为一个整体进行考虑和处理。
一个数据元素可由若干个数据项组成,数据项是构成数据元素的不可分割的最小单位。
记忆定义 主干:数据元素是基本单位,通常作为一个整体进行考虑和处理。
细节:数据元素是数据的基本单位。这个整体可由若干个数据项组成,数据项是构成数据元素的不可分割的最小单位。
理解定义 下面我们通过画图来进一步理解数据、数据元素和数据项之间的关系:
从图中可以看到,若干个数据项组成了一个整体,这个整体就是数据元素,然后由若干个数据元素组成了一个完整的数据。
这里我们举一个例子来加深一下对这个知识点的理解:
学校马上要开运动会了,现在班上要学生报名,并要求登记报名的项目、身高、体重。
总共有10人报名,张三报名了400m,李四报名了跳远、王五报名了铅球……
在这个例子中总人数就是班上运动会报名的数据,张三、李四、王五……这些学生就是一个个数据元素,他们报名的项目、身高、体重就是数据项。
数据描述的是一个集合,这个集合是由报名的学生组成的;数据元素描述的是一个个体,这些个体就是张三、李四、王五……他们这些学生;数据项指的是组成数据元素的不可分割的最小单位,这些数据项就是项目、身高、体重这3项内容; 如果一个数据项中的内容由多个属性组成,比如2020-10-19这个内容我们可以把它拆分为年月日,那这种情况下,这个数据项我们就把它称为组合项。
☆☆☆不可分割的数据项组成一个数据元素,所有数据元素的集合就是数据。
3.数据对象 定义 数据对象是具有相同性质的数据元素的集合,是数据的一个子集。
记忆定义 主干:数据对象是一个集合,是一个子集。
细节:数据对象是具有相同性质的数据元素的集合,是数据的一个子集。
理解定义 我们还是通过画图来理解:
图中我们可以看到,这一整个集合组成了数据,两个数据元素组成了一个数据对象,n个数据项组成了一个数据元素。
要注意的是组成数据对象的两个数据元素要是相同性质的。
比如现在学校组织运动会,班级里要统计运动员、新闻稿、后勤员等工作的名单。
所有的运动员的学生名单组成的集合就是一个数据对象;所有写新闻稿的学生名单组成的集合就是第二个数据对象;所有的后勤员的学生名单组成的集合就是第三个数据对象。 ☆☆☆数据项的集合是一个数据元素,相同性质的数据元素的集合是一个数据对象,所有数据对象的集合是数据。
算法和算法评价 前言算法的基本概念定义理解定义 算法的5个特性有穷性定义理解 确定性定义理解 可行性定义理解 输入定义理解 输出定义理解 什么是好的算法正确性定义理解 可读性定义理解 健壮性定义理解 高效率和低存储量需求定义理解 结语【数据结构】第一章——绪论 前言 大家好,很高兴又和大家见面啦!!!今天我们将继续介绍数据结构第一章的相关内容。
在上一篇中,我们介绍了数据结构的基本概率,简单说明了一下数据结构的三要素——数据的逻辑结构、数据的存储结构以及数据的运算。我个人是感觉这些定义有点不好理解,不过没关系,这些内容会随着我们学习的深入而不断提升对它们的理解。下面我们就来看一下第一章的第二部分内容——算法和算法评价。
算法的基本概念 定义 算法(Algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。
理解定义 对于这个定义我是这样理解的——在C语言中,我们有介绍过函数,在我们用函数编写一个功能时,函数的返回类型、函数名和函数的参数都是在对这个函数进行声明,函数的具体实现是在函数体内完成的,这个实现的过程,我们就可以简单的理解为是算法。下面我举一个最简单的算法:
//实现打印hello int main() { printf("hello\n"); return 0; } 现在我为了实现打印hello这个功能,我在主函数体内通过调用库函数printf完成了这个功能,那我现在就可以称这个实现这个功能的过程就是实现这个功能的算法。
在这个算法中,它有2个指令——printf和return;
对于这两条指令,它都只有一个操作——打印和返回0;
算法的5个特性 那我们现在对算法有了一个初步的了解之后,我们现在来看一下算法又有哪些特性;
有穷性 定义 一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。
理解 对于有穷性的理解,我的理解就是像死循环这种无法结束的代码就称不上是算法,如下图所示:
对于这个循环来说,判断条件为1,结果恒为真,代码进入死循环,不断的打印hello,像这种打印的实现就称不上是算法,但是如果我们将它简单修改一下,如下图所示:
可以看到,我们不管是修改了判断条件也好,还是增加了介绍标志也好,都是在告诉计算机,你现在需要在什么时候停止,等计算机运行到那个停止点时,它就停止不再运行了。也就是说有穷性就是程序能够正常的终止。
确定性 定义 算法中每条指令必须有确切的含义,对于相同的输入只能得到相同的输出。
理解 确定性的话我们可以理解为就像数学中的函数一样,自变量与因变量的关系可以是一对一也可以是多对一,但绝不能是一对多这种情况。下面我们来通过计算机语言来描述:
在这个代码中我们通过判断变量i的值是否为-1来决定是否要继续循环;
在循环中则进行了三个功能的实现——输出i的值、输出hello以及输出数组元素,对于个功能的实现如下:
当i的值不为1且i的值也不为2时,我们执行的是一对一的输出,可以看到结果展示每一个输入的值都能得到一个输出,并且同一个输入能得到同一个输出;当i的值为2时,我们执行的是多对一的输出,这时需要输入第二个变量j,从结果中可以看到当满足i==2这个条件时,不管j的值为多少,我们都能得到hello的打印结果;当i的值为1时,我们执行的是一对多的输出,我们通过rand函数与srand函数生成随机数使数组的下标随机,在这种情况下同一个i值得到的结果却是截然不同的; 我们现在从算法确定性的角度来分析,那么对于输出数组元素这个内容的实现显然就不满足算法的确定性;
为了实现输出数组元素的功能,我们可以如下进行代码编写:
像这样编写代码后我们可以看到,对于变量i的每一次输入,我们都能得到一个输出,并且同样的输入对应的是同样的输出,不同的输入对应的是不同的输出,此时输入与输出满足一对一的关系;
对于上述这种输入和输出满足一对一关系或者多对一关系的代码,我们就称这样的算法是具有确定性的;
可行性 定义 算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
理解 对于可行性我的理解是——我们在算法中的操作过程,都是能够通过计算机语言进行实现的。
如我想打印内容,我可以通过库函数printf、putchar等等这样的输出函数进行打印;
我想输入数据我可以通过scanf、gets等这样的输入函数进行数据的输入;
我想进行加减乘除的运算我可以通过+-*/这些算术操作符实现;
除了上述这些内容外,只要是我们想实现的功能,都是能够通过相应的计算机语言进行实现的,这就是可行性;
输入 定义 一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合。
理解 对于一个算法而言,我们可以没有输入,如通过printf在屏幕上输出hello world:
我们也可以只有一个输入,如通过输入给变量a赋值,并在屏幕上以a=%d的形式输出a的值:
我们还可以有多个输入,如编写一个简单的进行两个数的四则运算的程序:
算法和算法评价 前言算法效率的度量时间复杂度定义理解时间复杂度的计算加法规则:乘法规则:常见的渐近时间复杂度 习题巩固 结语【数据结构】第一章——绪论 前言 大家好,很高兴又和大家见面啦!!!在上一篇中我们介绍了算法以及算法的五个特性和五个目标,今天我们将开始重点介绍算法的高效率和低存储量需求。
算法效率的度量 算法效率的度量是通过时间复杂度和空间复杂度来描述的。
时间复杂度对应的就是高效率;空间复杂度对应的就是低存储量需求。
那时间复杂度和空间复杂度又是什么呢?下面我们就来分别介绍一下;
时间复杂度 定义 一个语句的频度是指该语句在算法中被重复执行的次数。算法中所有语句的频度之和记为 T ( n ) T(n) T(n)。它是该算法问题规模 n n n的函数,时间复杂度主要分析 T ( n ) T(n) T(n)的数量级。
理解 大家看到这个定义时可能一脸懵,又是问题规模、又是数量级的,这些都是什么呀?
我刚开始看到这两个内容时也是一头雾水,经过后面的学习,我对这两个内容也有了一个初步的理解:
问题规模指的是一个程序执行的次数。
//问题规模 int main() { printf("hello world\n");//执行次数为一次,问题规模为1 for (int i = 0; i < 20; i++) { printf("你好\n");//执行次数为20次,问题规模为20 } for (int i = 0; i < 3000; i++) { printf("I Love You\n");//执行次数3000次,问题规模为3000 } return 0; } 从这个代码中我们可以看到,每一句代码执行的次数都不相同,它们的执行次数也就代表着这句代码的问题规模;
数量级指的就是执行次数的单位。
基本情况 这是一个前端实习岗位,在boss上进行投递,本篇博客记载天天拍车的一面。大概面了快一个小时,面试题目不难,面试官非常友善,且通过此次面试我也颇有收获。
因为题目也不难,可以搜到答案,所以这里只记录题目是什么,我回答的怎么样,对于标准答案,不作详述。
由于有几天了,有事情耽搁没详细记录,所以只把能想起来的给记下来,希望能帮助到读者朋友。
询问情况 面试官比较在意在校期间的学习情况,我针对前端,比赛等进行了展开讲解;
面试官还注重我的实习情况,做了什么,学到什么,由于我的简历上有两份实习经历,所以依次说了我担任的角色以及我做的事情。
这些基本问题了解后,就进入了基础考察环节。
面试问题 1.介绍原型和原型链的区别
这个问题我已经理解并熟练了,在很久之前写过一篇博客,记录的非常详细:
构造函数与原型对象
这里还问到了Vue中的内容,比如Vue对原型的应用。(事件车)
2.js事件循环
说实话当时有点懵逼,在想是不是对一个事件进行循环。下来搜之后,秒懂了。
实际上就是同步跟异步。同步任务进入主进程,异步任务在特定时刻执行。但异步任务的执行也有讲究,我们可以把异步任务分为宏任务和微任务,宏任务就比如定时器,微任务是我们的promise。微任务优先宏任务执行。
3.正则表达式的考察
这块之前面滴滴的时候就有考,这次又考了,遗憾的是,又不能回答出完整正确的过程。我一定要把正则给好好过一遍,然后在这里附上我的打卡博客。
4.ES6新增内容
ES6新增每一个都可以详细说的。这里我记录下我回答上来的:
新增let、const,这里我详述了下这两点。这一点在我这家公司面试的时候也详细考过,印象深刻;
class类的出现;
promise的应用(这里我有详细回答);
箭头函数;
set、map的使用,这两点面试官有问,但我觉得我后面还需要再使用,让自己更加了解;
proxy代理。
5.原型上遍历数组的方法
这里我提到了forEach、map、filter(面试官详细问了)、面试官为我提到了IndexOf、还有find等。这个后面还需要多了解。
我还提到了非原型遍历数组,用for,for of的方法。
6.跨域问题的解决
前端方面的jsonp、script标签、proxy代理;
后端Nginx的反向代理、请求头设置(没答上来详细的请求头)。
res.setHeader(‘Access-Control-Allow-Origin’, ‘*’)
7.前端如何向后端传递JSON数据
这个我不太清楚,硬着头皮说把对象转化成JSON格式传过去,面试官提醒我这个也需要在后端进行设置,类似于解决跨域的请求头;
后面我问了我的后端,现在java的框架好像已经可以自动设置了,无需配置,用框架工具即可。
8.get、post的区别,以及还知道什么请求
这个我之前面试也出现过,具体是什么就不详述了。还知道什么请求,我回答的是delete;
面试官提示我的options请求,也是一种请求类型,是全能的。可以在methods中设置get、set等。
9.new的作用
反问环节 反问环节我问了实习介绍上面的“微前端”标签,得到的答案是跟部署有关的相关操作,面试官还主动为我介绍了公司实习生的学习与职责,以及后面的转正留用相关情况。
总结 一面过了,二面是技术总监的面试,也相当于技术面,二面加油!
冲冲冲!
前言 鼎捷一共两面,一面针对技术,这篇博客记录下我认为有价值的问题。
有价值的提问 js类的继承的方式 es5,涉及到原型、原型链的继承;
es6,类与对象,extends,super;
还问到Vue方向的一些原理。但是是让我谈我知道的原理,我聊到了响应式、事件车、diff比对算法、el的渲染(render函数)等。
自己写一个render函数会怎样思考 render是用来渲染的,本质上是一个函数。内部传参为一个createElement函数,这个函数内部有三个参数,第一个必须要有,是需要渲染的标签;第二个第三个跟渲染元素的特性、虚拟节点有关系,非必选。
知道了原理,那么思路好说。我的回答涉及到了原生js中的innerHTML,innerText。我们也可以写一个render1,内部的参数为一个函数,函数的第一个参数是html结构,或者是字符串。
当内部的这个函数拿到了这个字符串之后,可以把传的参数解析渲染到页面上,实现一个基本的渲染功能。
在当今互联网时代,数据已经成为了一种非常重要的资源,而爬虫技术则是一种常用的数据获取方式。但是,爬虫抓取数据是否合法,一直是一个备受争议的话题。本文将从多个角度分析,以探讨这个问题的答案。
首先,从法律角度来看,爬虫抓取数据是否违法取决于其是否侵犯了他人的知识产权。例如,如果爬虫抓取了某个网站的内容,而该网站对其内容享有版权,那么这个行为就是不合法的。此外,如果爬虫抓取了包含他人隐私的内容,那么它也是不合法的。因此,爬虫抓取数据是否违法,完全取决于其是否侵犯了他人的权益。
其次,从伦理道德角度来看,爬虫抓取数据是否违法也存在争议。一些人认为,如果使用爬虫技术仅限于获取公共数据,那么这个行为是合法的,因为这些数据并不受版权保护。然而,另一些人则认为,即使是公共数据,也应该受到一定的保护,因为它们可能包含个人信息和隐私。因此,爬虫抓取数据是否违法,也取决于其是否存在道德问题。
再次,从技术角度来看,爬虫抓取数据是否违法也存在一些问题。一些网站会使用反爬虫技术来防止爬虫抓取其数据,如果爬虫继续进行抓取,那么它可能会被认为是一种恶意攻击。此外,如果爬虫抓取的数据过多,会占用网站的带宽资源,导致其运行缓慢或崩溃。因此,爬虫抓取数据是否违法,也取决于其是否会对网站产生负面影响。
最后,从实际应用角度来看,爬虫抓取数据是否违法也存在一些限制。例如,一些网站会通过用户协议或隐私政策来限制外部程序对其数据的访问。如果爬虫违反了这些规定,那么它就是不合法的。此外,如果爬虫抓取的数据用于商业目的,那么它可能会侵犯其他公司的商业利益,从而引起法律纠纷。因此,爬虫抓取数据是否违法,也取决于其是否符合相关规定和道德标准。
综上所述,爬虫抓取数据是否违法,取决于多个因素,包括法律、道德、技术和实际应用。如果使用爬虫技术合法、道德、技术安全,并符合相关规定和道德标准,那么它就是一种合法的数据获取方式。
关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
最后祝大家天天进步!!
上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。
IBL - Image Based Lighting - 也就是基于图像的照明,是一组照亮物体的技术,不是像上一章那样通过直接分析光,而是将周围环境视为一个大光源。 这通常是通过操作立方体贴图环境贴图(取自现实世界或从 3D 场景生成)来完成的,这样我们就可以直接在我们的光照方程中使用它:将每个立方体贴图纹理元素视为光发射器。 通过这种方式,我们可以有效地捕捉环境的全局照明和总体感觉,使物体在其环境中具有更好的归属感。
NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎
1、辐照图贴图及其计算方法 由于基于图像的照明算法捕获某些(全局)环境的照明,因此其输入被认为是环境照明的更精确形式,甚至是全局照明的粗略近似。 这使得 IBL 对于 PBR 来说很有趣,因为当我们考虑环境照明时,物体看起来在物理上更加准确。
为了开始将 IBL 引入我们的 PBR 系统,让我们再次快速浏览一下反射率方程:
如前所述,我们的主要目标是求解半球Ω上所有入射光方向的积分wi。 求解上一章中的积分很容易,因为我们事先知道确切的几个光线方向wi有助于积分。 然而这一次,每个来自周围环境的入射光方向wi都可能会产生一些辐射,从而使求解积分变得不那么简单。 这给我们求解积分提出了两个主要要求:
我们需要某种方法来检索给定任何方向向量 wi 的场景的辐射亮度。求解积分需要快速且实时。 现在,第一个要求相对简单。 我们已经暗示过,但表示环境或场景的辐照度的一种方法是采用(已处理的)环境立方体贴图的形式。 给定这样一个立方体贴图,我们可以将立方体贴图的每个纹理像素可视化为一个发射光源。 通过使用任意方向向量 wi 对该立方体贴图进行采样,我们从该方向检索场景的辐射。
那么给定任意方向向量 wi 获取场景的辐射亮度就很简单:
vec3 radiance = texture(_cubemapEnvironment, w_i).rgb; 尽管如此,求解积分要求我们不仅从一个方向采样环境贴图,而且从半球上Ω所有可能的方向wi采样,这对于每个片段着色器调用来说都太昂贵了。 为了以更有效的方式求解积分,我们需要预处理或预计算大部分计算。 为此,我们必须更深入地研究反射率方程:
仔细研究反射率方程,我们发现BRDF 的漫反射 kd和镜面 ks项彼此独立,我们可以将积分一分为二:
通过将积分分成两部分,我们可以分别关注漫反射和镜面反射项; 本章的重点是漫反射积分。
仔细观察漫反射积分,我们发现漫反射朗伯项是一个常数项(颜色 c、 折射率 kd
一、EDKII windows 环境搭建 1. 下载UEFI开源代码 cmd进入C盘根目录,git clone https://github.com/tianocore/edk2.git edkii && cd edkii && git submodule update --init (太慢的话,使用gitee, git clone https://gitee.com/xiaopangzi313/edk2.git)
2. 安装ASL编译器 下载 iasl-win-20190405.zip,然后解压至C:\asl。
3. 安装NASM编译器 下载 nasm-2.14.02-win64.zip,解压nasm-2.14.02-win64.zip到C:\nasm
4. 安装VS2013或者VS2015(过程略) 5. 修改启动脚本edksetup.bat 进入edk2目录,在edksetup.bat最后一行添加
build -a X64 -p OvmfPkg\OvmfPkgX64.dsc -D DEBUG_ON_SERIAL_PORT
6. 编译 OVMF.FD 固件文件 在edk2目录执行edksetup.bat,
运行结果如下,
为了运行方便,可以将edksetup.bat放入右键菜单,编写以下文本保存为EDK2_Build.reg 并双击运行,
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\shell\EDK2_Build] @="EDK2_Build" "Icon"="cmd.exe" [HKEY_CLASSES_ROOT\Directory\shell\EDK2_Build\command] @="cmd.exe /s /k pushd \"%V\" && edksetup.bat" [HKEY_CLASSES_ROOT\Directory\Background\shell\EDK2_Build] @="EDK2_Build" "Icon"="cmd.exe" [HKEY_CLASSES_ROOT\Directory\Background\shell\EDK2_Build\command] @="
什么是Huffman编码? 当我们传输数据的时候,有一种传输方式叫做二进制传输,也就是把需要传输的数据转化为二进制数传输给对方。
比如我们有一段文字内容“BADCADFEED”要通过网络传输给别人,把这段内容编码为一段二进制数,将编码后的二进制数传输给对方,对方再根据得到的二进制解码为原内容,实现二进制传输。
如果要实现这一过程,我们可以采用这种方法,文字内容中每一个字符都有一个二进制数与之对应,且每一个字符对应的二进制数的长度是一样的。例如,我可以规定: “A”:000,“B”:001,“C”:010,“D”:011,“E”:100,“F”:101。这样我们就可以把文字内容转化为一段二进制数了,转化后的二进制数是“001000011010000011101100100011”,对方接收到这段二进制数后,每一次读取三个二进制数,根据编码表就可以解码为对应的字符,这个过程就实现了。
但是如果一篇文章内容很长,所包含的字符数量非常大,这种方式编码的二进制数会非常庞大。如果规定等长的二进制数长度为5,他能表示的字符数为2^5=32,ASCII码一共有256个字符,2^8=256,也就是每一个字符需要长度为8的二进制数对应,这样带来的内存消耗是非常大的,那有没有别的编码方式可以减少这种消耗呢?
Huffman提出一种新的编码方式,不再规定二进制数长度的统一,而是设计长短不等的编码,这种编码其实是很容易混淆的,给你一段很长的二进制数,你不知道要在那些地方划分解码,所以这种方式必须满足一个前提,任一字符的编码都不是另一个字符的编码前缀,这种编码方式称为前缀编码,也称为Huffman编码。
Huffman树 关于Huffman编码我们先来介绍一下Huffman树。
如果我们所需要传输的文本内容不再是“BADCADFEED”,而是由这六个字符组成的某段文字,这六个字符出现的频率分别为A27,B8,C15,D15,E30,F5。
Huffman树 如图所示:
根据Huffman树,我们可以知道,“D”:00,“A”:01,“E”:11,“C”:101,“B”:1001,“F”:1000,从而实现了Huffman编码,设计长短不等的编码,但是就算是长短不一,似乎也不能减少内存的消耗,我们设计等长的二进制数长度是3,Huffman编码所展示的“B”,“F”二进制长度都超过3变为了4,这种编码方式真的可以达到减少消耗的作用吗?可以根据数学计算,计算出此编码方式得到的二进制数总长度与等长度为3的编码方式得到的二进制总长度节省的空间大小,计算公式:二进制数长度减少的个数乘以出现频率减去二进制数长度增加的个数乘以出现频率。
根据公式可以得知,如果可以控制增加长度减少的字符出现频率,减少长度增加的字符出现频率,就可以尽量使得节省空间大小的值更大。根据这个思路,我们把出现频率高的字符安放在离根近的叶子位置,而出现频率低的字符安放在离根远的叶子位置。这就是Huffman编码方式节省空间的原理。
Huffman编码定义 Huffman编码是一种常用的数据压缩算法,通过使用不等长的编码来表示不同的符号,以实现对数据的高效压缩。该算法由David A. Huffman于1952年提出,并且在信息论和压缩领域广泛应用。
Huffman编码的基本思想是,出现频率高的符号使用较短的编码,而出现频率低的符号使用较长的编码。这样可以确保整体的编码长度较短,从而实现数据的高效压缩。
以下是Huffman编码的基本步骤:
统计符号的频率:遍历待压缩的数据,统计每个符号(通常是字符)的出现频率。
构建Huffman树:将每个符号及其频率作为一个节点,构建一个最小堆(Min Heap)或优先队列。不断合并两个具有最小频率的节点,直到只剩下一个节点,即树的根节点。这个树就是Huffman树。
分配编码:从根节点开始,向左走为0,向右走为1,从而得到每个符号的Huffman编码。编码的长度取决于符号在Huffman树中的深度。
构建Huffman编码表:将每个符号及其对应的Huffman编码存储在一个表中,以便进行编码和解码。
数据编码:用Huffman编码表将原始数据中的每个符号替换为相应的Huffman编码,得到压缩后的数据。
Huffman编码的解码过程是编码过程的逆过程:
读取Huffman编码表。从根节点开始,根据编码的每一位向左或向右遍历Huffman树。当到达叶子节点时,输出对应的符号,并回到根节点,继续解码下一个编码。 Huffman编码在图像、音频、文本等数据的压缩中得到了广泛应用,因为它能够根据数据的统计特性实现高效的压缩。
怎么样构建Huffman树? 前面我们提到了,Huffman树构建思路需要把出现频率高的字符安放在离根结点近的叶子位置,而出现频率低的字符安放在离根结点远的叶子位置。以下是Huffman树构建步骤:
如果我们所需要传输的文本内容不再是“BADCADFEED”,而是由这六个字符组成的某段文字,这六个字符出现的频率分别为A27,B8,C15,D15,E30,F5。
先把这些叶子结点按照从小到大的顺序排列成一个有序序列,即F5,B8,C15,D15,A27,E30。取头两个出现次数最小的结点作为一个新结点N1的两个子节点,新结点的出现次数算作两个结点出现次数之和。用N1结点替换F与B,插入有序序列中,保持从小到大排序。即N1 13,C15,D15,A27,E30。重复步骤2。将N1与C作为一个新结点N2的两个子结点。将N2替换N1与B,插入有序序列中,保持从小到大排序,即N2 28,D15,A27,E30。重复步骤2。将N2与D作为一个新结点N3的两个子结点。将N3替换N2与D,插入有序序列中,保持从小到大排序,即N3 43,A27,E30。重复步骤2。将N3与A作为一个新结点N4的两个子结点。将N4替换N3与A,插入有序序列中,保持从小到大排序,即N4 70,E30。重复步骤2。将N4与E作为一个新结点N5的两个子结点。将N5替换N4与E,插入有序序列中,保持从小到大排序,即N5100。 最后得到的Huffman树就如图所示:
代码的具体实现 编写结构体 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Node { char data; int frequency; struct Node* left; struct Node* right; } Node; 首先我们编写好头文件和Huffman树结点的结构体,结构体中需要存储表示的字符和这个字符的出现频率,以及左孩子和右孩子。
编写创建Huffman结点的函数 #include <stdio.h> #include <stdlib.h> #include <string.
re:Invent 2023前沿资讯快速入口➡️:2023亚马逊云科技reinvent大会,与开发者一起构建未来!
文章目录 一、2023 亚马逊云科技 re:Invent 精彩内容速递🎨二、Amazon Q 震撼来袭2.1 什么是`Amazon Q`?2.2 Amazon Q功能介绍 三、Amazon Q测评体验3.1 使用 Amazon Q 排查控制台错误3.2 与 AWS 支持人员聊天 四、🥚彩蛋:大会精彩花絮🎉五、🎨精彩栏目纷呈,即可锁定🔐1️⃣ PartyRock2️⃣re:Invent 2023 传音信箱3️⃣世界开发者说:听见全球开发者的声音4️⃣「构」向云端,构建者征文大赛5️⃣亚马逊云科技培训与认证6️⃣re:Invent 2023 开发者活动 六、参考链接🔗 一、2023 亚马逊云科技 re:Invent 精彩内容速递🎨 ① 2023 亚马逊云科技 re:Invent ,十二年间精彩纷呈不断.... 自2012年以来,亚马逊云科技re:Invent全球大会,已成为全球云计算领域创新年度发布的关键节点
十二年来,哪些高光瞬间让你记忆犹新,快邀请TA一同见证吧!
②17 年磨一剑,程序员编程利器 Amazon Q 面世! Amazon Q 问世,全场尖叫!这是一种以安全和隐私为重点构建的新型生成式人工智能助手,旨在帮助企业级开发者们释放生成式 AI 技术的全部潜力!
③黄教主亲身支持,官宣英伟达重磅合作 在主题演讲中,亚马逊云科技 CEO Adam Selipsky 邀请上老朋友英伟达 CEO 黄仁勋,黄教主的出现也让现场进入了一个小高潮。
④两大“王炸”芯片来袭,数周内训练出 3000 亿个参数的 LLM 亚马逊云科技发布 S3 Express One Zone、Amazon Graviton 4以及 R8g Instances for EC2 实例、Trainium2 芯片等!全面助力客户降本增效!
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、银行应用程序的特征
1)多层功能,支持数千个并发用户会话
2)大规模集成,通常是银行应用程序与许多其他应用程序集成,例如账单支付实用程序,交易账户,在线定期存款等。
3)复杂的业务工作流
4)实时和批处理
5)每秒事务率高
6)安全事务
7)强大的报告部分,可跟踪日常交易
8)强大的审计功能可解决客户问题
9)海量存储系统
10)灾害管理
上面列出的十点是银行应用程序最重要的特征。
银行应用程序在执行操作时涉及多个层。
例如,典型的银行应用程序可能具有:
1个 Web 服务器,用于通过 Web 浏览器与最终用户交互;
用于验证 Web 服务器的输入和输出的中间层;
用于存储数据和过程的数据库;
事务处理器,可以是大容量大型机或任何其他遗留系统,每秒执行数万亿个事务。
如果我们谈论测试银行应用程序,它需要一个端到端的测试方法,涉及多种软件测试技术,以确保:
全面覆盖所有银行工作流程和业务需求
应用程序的功能方面
应用程序的安全性方面
数据完整性
并发
用户体验
2、测试银行应用程序典型阶段
收集
需求审查
业务场景准备
功能测试
数据库测试
安全测试
用户接受
1)需求收集
需求收集阶段涉及将需求记录为功能
规范或用例。根据客户需求收集需求,并由银行专家或业务分析师记录。要编写要求,涉及多个主题专家,因为银行本身具有多个子域,并且一个成熟的银行应用程序将是所有子域的集成。
例如,银行应用程序可能具有用于汇款,信用卡,报告,贷款帐户,账单支付,电子交易等的单独模块。
2)需求审查
需求收集的可交付成果由所有利益相关者(如QA工程师,开发主管和同行业务分析师)进行审查。他们交叉检查现有业务工作流和新工作流是否都未违反。
3)业务场景准备
在此阶段,QA 工程师从需求文档(功能规范或用例)派生业务方案。业务方案的派生方式是涵盖所有业务需求。
业务方案是高级方案,没有任何详细步骤。此外,这些业务场景由业务分析师审查,以确保满足所有业务需求,并且BA审查高级场景比审查低级详细测试用例更容易。
4)功能测试
在此阶段,将执行功能测试并执行通常的软件测试活动。
例如:
测试用例准备:在此阶段,测试用例派生自业务方案,其中一个
业务场景导致几个正面和负面的测试用例。通常,在此阶段使用的工具是微软Excel,测试总监或质量中心。
测试用例评审:由同行 QA 工程师进行评审。
测试用例执行:测试用例执行可以是手动的,也可以是自动的,涉及QC,QTP,硒或任何其他工具。
5)数据库测试
银行应用程序涉及在Ul级别和数据库级别执行的复杂事务,因此数据库测试与功能测试一样重要。
数据库本身是一个完全独立的层,因此它通常由数据库专家执行,并使用相同的技术进行测试。
例如:
数据加载
数据库迁移
测试数据库架构和数据类型
规则测试
推荐链接:
总结——》【Java】
总结——》【Mysql】
总结——》【Redis】
总结——》【Kafka】
总结——》【Spring】
总结——》【SpringBoot】
总结——》【MyBatis、MyBatis-Plus】
总结——》【Linux】
总结——》【MongoDB】
总结——》【Elasticsearch】
Java——》JSONObjet 数据顺序 一、源码二、JSONObjet按顺序显示 一、源码 JSONObject 内部是用 Map* 来存储的:
HashMap 元素是无序的LinkedHashMap 元素是有序的 二、JSONObjet按顺序显示 通过下面两种方法实现固定排序:
JSONObject jsonObj = new JSONObject(new LinkedHashMap<String, Object>());JSONObject jsonObj = new JSONObject(true); import com.alibaba.fastjson.JSONObject; import java.util.LinkedHashMap; public class Test { public static void main(String[] args) { // JSONObject内部是用HashMap来存储的,HashMap 元素是无序的,LinkedHashMap 元素是有序的 JSONObject jsonObject = new JSONObject(); jsonObject.put("3","c"); jsonObject.put("2","b"); jsonObject.put("1","a"); System.out.println(jsonObject); // 固定排序(保持put时的顺序):方法1 jsonObject = new JSONObject(true); jsonObject.put("3","c"); jsonObject.
【快速见刊|投稿优惠】2024年文化传播与社会管理国际会议(ICCCSM 2024) 2024文化传播与社会管理国际会议(ICCCSM 2024)
2024 International Conference on Cultural Communication and Social Management (ICCCSM 2024)
▶会议简介 2024年文化传播与社会管理国际会议(ICCCSM 2024)将围绕“文化传播,社会管理”的新兴研究领域,为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供一个分享专业经验,扩大专业网络,面对面交流新思想以及展示研究成果的国际平台,探讨本领域发展所面临的关键性挑战问题和研究方向,以期推动该领域理论、技术在高校和企业的发展和应用,也为参会者建立业务或研究上的联系以及寻找未来事业上的全球合作伙伴。 ▶重要信息 投稿邮箱:s19113133262@163.com
【投稿请备注icccsm+苏老师推荐+投稿人姓名,精准备注更快审稿】
最终截稿时间:请查看官网
接受/拒稿:投稿后2-3日内通知
(见刊快,检索稳定)
▶征稿主题(其他符合文化传播和社会管理相关主题皆可投稿) 文化传播:
新闻与传播
传播行为
符号传播
跨文化交际
文化研究
文化比较
文化形态
文化保育
文化传承
文化创新文化变迁与转型
文化的价值塑造
社会管理:
心理学
文化
法律
政治
历史
新闻
科技发展
交流、社区和电子社会
地理与地质科学
卫生事务及服务
商务、金融、旅游管理
人类和社会进化的复杂性
基于心理和社会概念的人类发展
创新、科技与社会
国际关系与合作
认知、心理和行为科学
人文社科类相关主题
▶论文提交 将您的文章或摘要投到我们的会议邮箱,我们收到后会第一时间回复您。 投稿邮箱:s19113133262@163.com
【投稿备注icccsm+苏老师推荐,精准备注更快审稿+享投稿优惠】
审稿流程:作者投稿→稿件收到确认(1个工作日)→初审(1-3工作日) →告知结果(接受/拒稿)。
(为了您能在第一时间得到回复,添加时请备注“icccsm 2024”)
目录 前言一,插槽的基本使用1.1 引出插槽1.2 插槽的基本使用1.3 默认插槽1.4 插槽样式 二,具名插槽2.1 引出具名插槽2.2 具名插槽的使用 三,template标签3.1 引出template标签3.2 template标签的使用 四,作用域插槽4.1 引出作用域插槽4.2 作用域插槽后记 前言 插槽是vue中一个很有用的工具。本篇文章将讲解vue插槽的基本用法,并详细讲解作用域插槽。
希望能对读者有所帮助!
一,插槽的基本使用 1.1 引出插槽 我们对组件进行复用的时候,虽可以通过父子传值改变组件的数据,但页面的结构还是取决于组件本身。
那么,如何不改变组件本身的结构,且能够在组件本身结构的基础上再添加想加的内容呢?使用插槽可以办到。
插槽概念:
插槽就是子组件中的提供给父组件使用的一个占位符,用slot标签 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的slot标签。简单理解就是子组件中留下个“坑”,父组件可以使用指定内容来补“坑”。
1.2 插槽的基本使用 如下所示,一个父组件里面复用了子组件:
<template> <div class="container"> <Student></Student> <Student></Student> <Student></Student> </div> </template> student的结构也非常简单:
<template> <div class="student"> <h3>巧克力小猫猿</h3></div> </template> 最后的效果:
现在,我想在不改变student组件的前提下,给‘巧克力小猫猿’的上面添加一个‘加油’,于是我们可以使用插槽。
插槽其实很简单,结合定义不难理解。我们可以在子组件中给父组件挖一个坑,父组件把内容放入子组件的坑中:
子组件中用slot标签挖坑
<template> <div class="student"> <slot></slot> <h3>巧克力小猫猿</h3> </div> </template> 在父组件中填坑:
<template> <div class="container"> <Student>加油</Student> <Student></Student> <Student></Student> </div> </template> 于是可以看到效果:
同样如果我们想给’巧克力小猫猿’的下面添加一个加油,我们可以把坑挖在此结构的下面:
<template> <div class="student"> <!
引入cesium npm install cesium --save 安装完成后在node_modules 依赖包里面找到cesium目录下的Build文件夹,将里面的Cesium 文件夹复制到public文件夹下
在index.html文件里引入
<script type="text/javascript" src="./Cesium/Cesium.js"></script> <link rel="stylesheet" href="./Cesium/Widgets/widgets.css"> 因为我看天地图的官网demo需要引入cesiumTdt.js,所以我也下载了cesiumTdt.js放在public文件夹下的Cesium 文件夹里并引入
<script type="text/javascript" src="./Cesium/cesiumTdt.js" ></script> 使用Cesium
先去cesium申请token <template> <div id="my-map"> </div> </template> export default { name: "TianMap", data() { return { viewer: null, scene: null, pointList: [], poinEntity: {}, pointsMsg: {} } }, mounted() { this.init() }, methods: { init() { Cesium.Ion.defaultAccessToken = '你的Cesium token' this.viewer = new Cesium.Viewer('my-map', { homeButton: false, sceneModePicker: false, baseLayerPicker: false, // 影像切换 animation: false, // 是否显示动画控件 infoBox: false, // 是否显示点击要素之后显示的信息 selectionIndicator: false, // 要素选中框 geocoder: false, // 是否显示地名查找控件 timeline: false, // 是否显示时间线控件 fullscreenButton: false, shouldAnimate: false, navigationHelpButton: false, // 是否显示帮助信息控件 }); this.
某java进程CPU耗用率非常高 下面启动一个java进程,模拟如何排查java进程cpu使用率非常高的情况。
top 查看CPU耗用率最高的java进程ID,得到进程ID,如:31876 #使用进程ID查看该进程的线程 top -H -p 31876 #找到最高的线程ID,如线程ID是31876,需要将线程ID转换为16进制 printf '0x%x\n' 31876 0x7c94 #使用jstack命令排查,jstack在java-1.8.0-openjdk-devel包中,没有这个命令需要先安装 yum install java-1.8.0-openjdk-devel -y #使用jstack命令排查, jstack 进程ID | grep -C 20 '16进制的线程ID' jstack 31876 | grep -C 20 '0x7c94'
日常生活中,当遇到需要将某个PDF文件转换为Word格式文件时,一般是通过一些在线格式转换的网站,或者软件来完成,但我们也可以使用python来完成这个需求(当然,这种方法仅能够满足大部分的格式)。
前提: 使用pdf2docx库,在保持原来内容格式不变的情况下将PDF转换为Word,它专门用于在不丢失格式的情况下将PDF文件转换为Word文件。此库的安装可能需要一些依赖项,例如pandas 和 tqdm,可以使用以下命令安装:
pip install pdf2docx pandas tqdm 由于需要调用文件路径,所以需要使用OS库。
场景一:单文件转换。 需要修改代码中的pdf_file_path地址替换为所需要转换的pdf文件地址。(地址中的转义字符“\”替换成“\\”或者用//)
import os from pdf2docx import Converter def pdf_to_docx(pdf_path): # 获取PDF文件所在的目录 pdf_directory = os.path.dirname(pdf_path) # 生成Word文件的路径 pdf_filename = os.path.splitext(os.path.basename(pdf_path))[0] docx_filename = pdf_filename + "_converted.docx" docx_path = os.path.join(pdf_directory, docx_filename) # 使用pdf2docx库将PDF转换为Word cv = Converter(pdf_path) cv.convert(docx_path, start=0, end=None) cv.close() return docx_path if __name__ == "__main__": # 用法示例 pdf_file_path = "C://Users//Desktop//test.pdf" # 调用pdf_to_docx函数进行转换 generated_docx_path = pdf_to_docx(pdf_file_path) print(f"Word文件已生成:{generated_docx_path}") 场景二:某个文件夹内所有的pdf文件转换, 需要将input_pdf_folder替换成所要转换的pdf文件夹,其次将output_docx_folder设置为输出的文件夹。
import os from pdf2docx import Converter def convert_pdfs_to_docx(input_folder, output_folder): # 确保输出目录存在,如果不存在则创建 os.
【火热征稿|投稿优惠】2024年通信网络与光电信息国际学术会议(ICCNOI 2024)
2024 International Conference Communication Network and Optoelectronic Information(ICCNOI 2024)
一、【会议简介】
这个会议的主题可谓是紧跟时代步伐,紧密围绕通信网络与光电信息两大核心领域。在这里,专家学者们将共聚一堂,交流最新的研究成果,探讨最前沿的科学问题。会议的议题范围广泛,包括但不限于通信网络技术、光电信息处理、光电子器件等领域。
二、【征稿主题】主题包括但不限于以下
传播理论
传播建模理论与实践
通信信号处理
人机交互
绿色通信系统
网络和无线通信
光通信和光网络
5G通信和网络
遥感和卫星通信
有线传感器和通信网络
通信渠道和移动设备
网络与信息安全技术
卫星通信技术
现代光纤通信技术
汇编语言编程
光电子学和技术
光电信息工程
光电信号获取
光通信
光电信息处理
光纤通信与系统
光存储与光显示
光电测控与光电传感
光电探测技术与器件
光电信息应用
光电成像技术
光电检测技术
光电仪器设计
光电器件
光通信和信息系统
微机电系统
数字图像处理
数字电子技术
通信与数据传输
光通信器件
三、【重要信息】
投稿邮箱:s19113133262@163.com
投稿时请邮箱正文备注:论文投稿+苏老师推荐+投稿人姓名
最终截稿时间:请查看官网
接受/拒稿:投稿后2-3日内通知
四、【论文提交】
1. 文章需全英文,重复率低于30%。
2. 文章必须要有题目、作者、单位、邮箱、关键词、摘要、必要的图表、结论、参考文献等。
3. 投稿流程:投稿→审稿→录用→注册→开具增值税普票(专票)→电子版→纸质版→检索。
4. 请勿一稿多投,所有稿件将接受两三名专家进行评审
五、【联系我们】
邮箱:s19113133262@163.com
备注:你的名字+苏老师推荐,享投稿优惠+优先审稿
【学生特惠|权威主办】2024年工业设计与建筑土木国际学术会议(ICIDBCE 2024)
2024 International Conference Industrial Design and Building Civil Engineering(ICIDBCE 2024)
一、【会议简介】
在这次会议上,来自全球各地的学者们纷纷展示他们的研究成果。有的团队研发了一种新型材料,具有轻质、高强度、环保等优点;有的团队设计了一种智能建筑,能够根据环境变化自动调节温度和湿度;还有的研究团队发现了一种新的建筑结构,能够提高建筑的抗震性能。这些研究成果不仅展示了工业设计和建筑土木领域的最新进展,也为未来的发展提供了新的思路和方向。
二、【征稿主题】主题包括但不限于以下
环境设计
环境设计理念
产品开发
产品设计
交互设计
环境设计
创新设计
计算机辅助设计
数字媒体艺术
多媒体艺术设计
分析与优化设计
环境与公共艺术设计
土木工程技术
土木勘测
土木工程机械
土木工程抗震
新型建筑技术
工程结构与抗震
工程监测检测技术
高层建筑工程技术
建筑改造技术
结构修复、改造和加固技术
混凝土结构、钢结构及技术
钢结构、金属结构技术
通风与空调工程技术
装饰装修、防水、基础技术
模板机具技术
建筑构件生产技术
建筑水暖电气
建筑电力系统
建筑设备安装技术
建筑施工技术
建筑节能技术
三、【重要信息】
投稿邮箱:s19113133262@163.com
投稿时请邮箱正文备注:论文投稿+苏老师推荐+投稿人姓名
最终截稿时间:请查看官网
接受/拒稿:投稿后2-3日内通知
四、【论文提交】
1. 文章需全英文,重复率低于30%。
2. 文章必须要有题目、作者、单位、邮箱、关键词、摘要、必要的图表、结论、参考文献等。
3. 投稿流程:投稿→审稿→录用→注册→开具增值税普票(专票)→电子版→纸质版→检索。
4. 请勿一稿多投,所有稿件将接受两三名专家进行评审
邮箱:ts19113133262@163.com
备注:你的名字+苏老师推荐,享投稿优惠+优先审稿
二进制数:是计算技术中经常采用的一种数制。二进制数据是由0和1两个基本数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。 十进制数:是组成以10为进位单位基础的数字系统,是以0,1,2,3, 4, 5, 6, 7, 8, 9十个基本数字组成。十进制计数是由印度教教徒在1500年前发明的,由阿拉伯人传承至11世纪。 十六进制(简写为hex或下标16)是一种基数为16的计数系统,是一种逢16进1的进位制。通常用数字0、1、2、3、4、5、6、7、8、9和字母A、B、C、D、E、F(a、b、c、d、e、f)表示,其中:A~F表示10~15,这些称作十六进制数字。 一般的数字是几进制:十进制 在线转换工具:https://c.runoob.com/unit-conversion/7994/
高德地图 webjs api 2.0官网教程
AMap.Driving使用说明 <div class="mmp"> <div id="map" ref="mapcontainer"></div> </div> <script lang="ts"> //安全密钥 window._AMapSecurityConfig={ securityJsCode: "高德地图key密钥", } import { Component, Emit, Vue } from "vue-property-decorator"; import AMapLoader from "@amap/amap-jsapi-loader"; @Component export default class HomeView extends Vue { AMap: any = undefined; map: any = undefined; start: any = []; end: any = []; zoom: number = 10; getInMap() { AMapLoader.load({ key: "高德地图key值", version: "2.0", plugins: ["AMap.Scale"], }) .then((AMap: any) => { this.
MySQL数据库简介 MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。
由于MySQL是开放源代码的,因此任何人都可以在General Public License的许可下下载并根据个性化的需要对其进行修改。MySQL因为其速度、可靠性和适应性而备受关注。大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。
服务器准备 1,安装
[root@db01 ~]# yum install mariadb* -y 2,启动
[root@db01 ~]# systemctl start mariadb 3,测试链接
[root@db01 ~]# mysql 或者 [root@db01 ~]# mysql -uroot 4,创建远程链接用户
MariaDB [(none)]> grant all privileges on *.* to root@'%' identified by '123456'; 5,创建本地链接用户
MariaDB [(none)]> grant all privileges on *.* to 'root'@'localhost' identified by '123456'; 6,刷新权限
MariaDB [(none)]> FLUSH PRIVILEGES; 7,退出并重新连接
MariaDB [(none)]> exit [root@db01 ~]# mysql -uroot -p123456 8、创建一个数据库并查看此数据库
在 MySQL 中,你可以使用多种方法来比较日期的大小。以下是一些常用的方式:
使用比较运算符:
SELECT * FROM your_table WHERE your_date_column > '2023-01-01';
这将选择日期列值大于 '2023-01-01' 的所有记录。
使用比较运算符和 NOW() 函数:
SELECT * FROM your_table WHERE your_date_column > NOW();
这将选择日期列值大于当前日期和时间的所有记录。
使用DATEDIFF函数:
SELECT * FROM your_table WHERE DATEDIFF(your_date_column, '2023-01-01') > 0;
这将选择日期列值在 '2023-01-01' 之后的所有记录。DATEDIFF 函数返回两个日期之间的天数差异。
使用DATE函数进行比较:
SELECT * FROM your_table WHERE DATE(your_date_column) > '2023-01-01';
这将选择日期列值在 '2023-01-01' 之后的所有记录。DATE 函数用于提取日期部分。
确保在比较日期时,你使用的日期格式和比较值的格式是一致的,以避免错误。日期比较时,MySQL 会将字符串转换为日期类型进行比较。
CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注!
以下信息仅供参考,以比赛官网为准
目录
2023-12-02(周六) #4场比赛2023-12-03(周日) #7场比赛2023-12-04(周一) #无比赛2023-12-05(周二) #1场比赛2023-12-06(周三) #2场比赛2023-12-07(周四) #无比赛2023-12-08(周五) #1场比赛 2023-12-02(周六) #4场比赛 DEGwer's Doctoral Dissertation Cheering Contest🖥 AtCoder · ⚖️ ACM赛制🥳 12:00开始 · ⏳ 时长5hhttps://atcoder.jp/contests/DEGwer2023 2023年广东工业大学腾讯杯新生程序设计竞赛🖥 牛客(Nowcoder) · ⚖️ ACM赛制🥳 13:30开始 · ⏳ 时长4h#高校校赛https://ac.nowcoder.com/acm/contest/71512 第 132 场周赛🖥 AcWing · ⚖️ ACM赛制🥳 19:00开始 · ⏳ 时长1h 15minhttps://www.acwing.com/activity/content/3648/ Daiwa Securities Co. Ltd. Programming Contest 2023(AtCoder Beginner Contest 331)🖥 AtCoder · ⚖️ ACM赛制🥳 20:00开始 · ⏳ 时长1h 40minhttps://atcoder.jp/contests/abc331 2023-12-03(周日) #7场比赛 第 374 场周赛🖥 Leetcode · ⚖️ ACM赛制🥳 10:30开始 · ⏳ 时长1h 30minhttps://leetcode.
文章目录 1 问题背景2 前言3 什么是消息推送4 短轮询5 长轮询5.1 demo代码 6 iframe流6.1 demo代码 7 SSE7.1 demo代码7.2 生产环境的应用 (重要) 8 MQTT 1 问题背景 扩宽自己的知识广度,研究一下web实时消息推送
2 前言 文章参考自Web 实时消息推送的 7 种实现方案针对一些比较重要的方式,我都会尽量敲出一份完整的demo代码,享受其中的编程乐趣。在SSE方式中,笔者延申思考,将他应用于电商支付的场景中,给出了比较合理的解决方案,但并未在生产环境中验证,仍待考证。 3 什么是消息推送 消息推送是指服务端将消息推送给客户端。常见的场景有:有人关注公众号,公众号推送消息给关注者;站内消息通知;未读邮件数量;监控告警数量等等。
4 短轮询 常见的http请求即是短轮询,由客户端发起请求,服务端接收请求并同步实时处理,最后返回数据给客户端。
5 长轮询 短轮询的异步方式即是长轮询,异步在哪里?客户端发起请求,web容器(比如tomcat)安排子线程去处理这些请求,将这些请求交给服务端后,无需阻塞等待结果,tomcat会立即安排该子线程理其他请求 ,tomcat以此接收更多的请求提升系统的吞吐量。服务端处理完请求再返回数据给客户端。
5.1 demo代码 因为一个ID可能会被多个长轮询请求监听,所以采用了guava包提供的Multimap结构存放长轮询,一个key可以对应多个value。一旦监听到key发生变化,对应的所有长轮询都会响应。
引入guava依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.1-jre</version> </dependency> 处理请求的接口:
package com.ganzalang.gmall.sse.controller; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.async.DeferredResult; import java.time.LocalDateTime; import java.
数组理论基础,704. 二分查找,27. 移除元素 704. 二分查找:时间复杂度O(log n) 核心:注意使用二分法的区间!第一种[left,right]属于左闭右闭 left=0 right=x-1 while left==<=======right left=mid+1 right=mid-1 !
class Solution: def search(self, nums: List[int], target: int) -> int: left=0 right=len(nums)-1 while left<=right: mid=left+(right-left)//2 # 是防止整数过大导致int溢出 if nums[mid]==target: return mid elif nums[mid]>target: right=mid-1 else: left=mid+1 return -1 第二种[left,right)属于左闭右开 left=0 right=x while left==<==right left=mid+1 right=mid
class Solution: def search(self, nums: List[int], target: int) -> int: left=0 right=len(nums) while left<right: mid=left+(right-left)//2 # 是防止整数过大导致int溢出 习惯使用/是真除法 if nums[mid]==target: return mid elif nums[mid]>target: right=mid else : left=mid+1 return -1 需要注意的是:python中//才是整除,别与其他语言混乱了!
参考文档:
https://developer.android.com/guide/topics/data/autobackup?hl=zh-cn
https://developer.android.com/about/versions/12/backup-restore#xml-changes
https://stackoverflow.com/questions/70365809/how-to-specify-to-not-allow-any-data-backup-with-androiddataextractionrules
问题描述:
最近包括1年前,也都发现了,某一些手机(特别是,有google框架服务的)在卸载后,安装回来,会加载到类似/data/data下面的cache内容,比如database,sharedPref,mmkv等。
问题的根源在于,从android6.0开始就支持一个自动备份。并且在android11,android12,均有更改。
进行影响你配置androidManifest.xml的三个点。
android:allowBackup="false" android:fullBackupContent="false" android:dataExtractionRules="@xml/data_extraction_rules" data_extraction_rules.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Sample data extraction rules file; uncomment and customize as necessary. See https://developer.android.com/about/versions/12/backup-restore#xml-changes for details. --> <data-extraction-rules> <cloud-backup> <exclude domain="root" /> <exclude domain="file" /> <exclude domain="database" /> <exclude domain="sharedpref" /> <exclude domain="external" /> </cloud-backup> <device-transfer> <exclude domain="file" /> <exclude domain="database" /> <exclude domain="sharedpref" /> <exclude domain="external" /> <exclude domain="root" /> </device-transfer> </data-extraction-rules> 其中allowBackup,是老版本android必备。
其中fullBackupContent,是配置android11以下。
pycharm中随便打开一个文件,在special variables中能看到一个__name__的变量
在很多python脚本中,也经常能看到if name == "main"这样一行
所以_name_到底是个啥?
首先,我们可以确定这是一个str字符变量
“在 Python 中,name 是一个特殊的内置变量,它用于表示一个模块的名称。具体来说,它表示当前模块的名称或正在执行的脚本的名称。”
上面这句话是个官方解释,有可能有点云里雾里,看懂了又好像不懂。那是因为我们对模块和脚本这些概念不是十分清晰。
先来解释一下脚本(script):脚本通常指一段可以直接执行的代码,以 .py 扩展名结尾。也就是平常自己写的py文件就是一个脚本。
模块(module):模块也是py文件,只不过这个py文件有概念上的规范和限制,不是所有py文件都可以叫模块,必须是用来封装代码、使代码可以被重复使用、可以在不同的脚本中被导入和调用的py文件才称得上是module。
所以可以简单的理解:脚本就是广义的py文件(py文件也就是Python文件),模块是狭义的py文件,它们都是py文件。
ok,讲完了脚本和模块,说回正题。
当一个 Python 脚本被直接运行时,它的 name 会被设置为 “main”,表示该脚本正在作为主程序执行。而当一个模块被导入到其他脚本中时,它的 name 会被设置为模块的名称。这样一来,当你希望某个模块在被直接运行时执行一些特定的操作,但在被其他模块导入时不执行这些操作。通过将这些可执行的代码放在 if name == “main”: 条件判断内部,这些代码只有在模块作为主程序运行时才会被执行。这样,当你直接运行模块时,这些代码会被执行,但如果你将模块导入到其他地方,这些代码就不会执行。通过这种机制,你可以将模块中的功能区分为两种类型的代码,使代码更具模块化和可重用性。这也能确保在导入模块时不会执行无关的操作,只有在需要的时候才会执行。
举个例子就能很好明白了:
# 模块示例 def some_function(): print("This function can be reused in other modules.") if __name__ == "__main__": # 这里的代码只有在该脚本直接运行时才会执行 print("This script is run directly.") # 可以在这里放置一些在直接运行时需要执行的操作 some_function() 当这个py文件作为主程序运行时,两个print都会输出,因为这时候的__name__是等于main的。如果这个py文件被做为module,导入道其他py文件去,在其他py文件中运行时,这个modele的__name__会被设置为他的模块名,这时候第二个print就不会执行了,也不会有任何输出。
现在,你明白了吗
MAMP Pro是一款专为Mac用户设计的全功能本地服务器软件,可以将电脑变成一个完整的Web开发环境。无论个人开发者、网站管理员还是团队协作,MAMP Pro都提供了强大的工具和便捷的管理方式,能够更加高效地构建和测试网站。
MAMP Pro的基本功能包括集成AMP环境,即Apache、MySQL和PHP环境,这些是构建和运行现代网站所必需的核心组件。软件将这些组件集成在一起,通过直观的控制面板,使得安装和配置变得异常简单。只需几步操作,就能搭建起一个完整的本地服务器环境,省去了繁琐的手动配置过程。
除了基本的AMP环境,MAMP Pro还提供了一系列增强功能。例如,它内置了一个强大的虚拟主机管理器,可以轻松地创建和管理多个虚拟主机。每个虚拟主机都可以拥有独立的域名和配置,仿佛拥有了多个独立的服务器。这对于同时开发多个项目或为客户提供独立的测试环境非常有用。另外,MAMP Pro还集成了phpMyAdmin,一个功能强大的MySQL数据库管理工具,可以轻松地创建、编辑和管理数据库。
MAMP Pro v6.8.1(PHP/MySQL开发环境)
目录 前言docker的工作原理是什么,讲一下docker的组成包含哪几大部分docker与传统虚拟机的区别什么?docker技术的三大核心概念是什么?centos镜像几个G,但是docker centos镜像才几百兆,这是为什么?讲一下镜像的分层结构以及为什么要使用镜像的分层结构?讲一下容器的copy-on-write特性,修改容器里面的内容会修改镜像吗?简单描述一下Dockerfile的整个构建镜像过程Dockerfile构建镜像出现异常,如何排查?Dockerfile的基本指令有哪些?如何进入容器?使用哪个命令什么是k8s?说出你的理解k8s的组件有哪些,作用分别是什么?kubelet的功能、作用是什么?(重点,经常会问)kube-api-server的端口是多少?各个pod是如何访问kube-api-server的?k8s中命名空间的作用是什么?k8s提供了大量的REST接口,其中有一个是Kubernetes Proxy API接口,简述一下这个Proxy接口的作用,已经怎么使用。pod是什么?pod的原理是什么?pod有什么特点?pause容器作用是什么?pod的重启策略有哪些?pod的镜像拉取策略有哪几种?pod的存活探针有哪几种?(必须记住3种探测方式,重点,经常问)存活探针的属性参数有哪几个?pod的就绪探针有哪几种?(必须记住3种探测方式,重点,经常问)就绪探针的属性参数有哪些就绪探针与存活探针区别是什么?简单讲一下 pod创建过程简单描述一下pod的终止过程pod的生命周期有哪几种?pod状态一般有哪些?pod一致处于pending状态一般有哪些情况,怎么排查?(重点,持续更新)pod的钩子函数有哪几种,作用是什么?pod的初始化容器是干什么的?pod的资源请求、限制如何定义?pod的定义中有个command和args参数,这两个参数不会和docker镜像的entrypointc冲突吗?标签及标签选择器是什么,如何使用?service是如何与pod关联的?service的域名解析格式、pod的域名解析格式service的类型有哪几种一个应用pod是如何发现service的,或者说,pod里面的容器用于是如何连接service的?如何创建一个service代理外部的服务,或者换句话来说,在k8s集群内的应用如何访问外部的服务,如数据库服务,缓存服务等?service、endpoint、kube-proxys三种的关系是什么?无头service和普通的service有什么区别,无头service使用场景是什么?deployment怎么扩容或缩容?deployment的更新升级策略有哪些?deployment的滚动更新策略有两个特别主要的参数,解释一下它们是什么意思?deployment更新的命令有哪些?简述一下deployment的更新过程?deployment的回滚使用什么命令讲一下都有哪些存储卷,作用分别是什么?pv的访问模式有哪几种pv的回收策略有哪几种在pv的生命周期中,一般有几种状态存储类的资源回收策略:怎么使一个node脱离集群调度,比如要停机维护单又不能影响业务应用pv存储空间不足怎么扩容?k8s生产中遇到什么特别影响深刻的问题吗,问题排查解决思路是怎么样的?(重点)etcd集群节点可以设置为偶数个吗,为什么要设置为奇数个呢?你们生产环境etcd节点一般是几个节点?etcd节点是越多越好吗?etcd集群节点之间是怎么同步数据的?pod的网络是怎么实现的,比如在node节点上ping一个pod的ip,这个网络流程是什么验证的?一个用户请求流量是如何进入k8s集群内部的?用户访问我们的k8s集群里面的应用网站,出现500报错,你是如何排查这种问题的?k8s后端存储使用的是什么?你们的服务发布怎么做的? 前言 本篇模拟面试官提问的各种docker,k8s问题,意在提高面试通过率,欢迎在评论区探讨,同步进步。
docker的工作原理是什么,讲一下 docker是一个Client-Server结构的系统,docker守护进程运行在宿主机上,守护进程从客户端接受命令并管理运行在主机上的容器,容器是一个运行时环境,这就是我们说的集装箱。
docker的组成包含哪几大部分 一个完整的docker有以下几个部分组成:
1、docker client,客户端,为用户提供一系列可执行命令,用户用这些命令实现跟 docker daemon 交互;
2、docker daemon,守护进程,一般在宿主主机后台运行,等待接收来自客户端的请求消息;
3、docker image,镜像,镜像run之后就生成为docker容器;
4、docker container,容器,一个系统级别的服务,拥有自己的ip和系统目录结构;运行容器前需要本地存在对应的镜像,如果本地不存在该镜像则就去镜像仓库下载。
docker 使用客户端-服务器 (C/S) 架构模式,使用远程api来管理和创建docker容器。docker 容器通过 docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
docker与传统虚拟机的区别什么? 1、传统虚拟机是需要安装整个操作系统的,然后再在上面安装业务应用,启动应用,通常需要几分钟去启动应用,而docker是直接使用镜像来运行业务容器的,其容器启动属于秒级别;
2、Docker需要的资源更少,Docker在操作系统级别进行虚拟化,Docker容器和内核交互,几乎没有性能损耗,而虚拟机运行着整个操作系统,占用物理机的资源就比较多;
3、Docker更轻量,Docker的架构可以共用一个内核与共享应用程序库,所占内存极小;同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高;
4、与虚拟机相比,Docker隔离性更弱,Docker属于进程之间的隔离,虚拟机可实现系统级别隔离;
5、Docker的安全性也更弱,Docker的租户root和宿主机root相同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限和宿主机的root虚拟机权限是分离的,并且虚拟机利用如Intel的VT-d和VT-x的ring-1硬件隔离技术,这种技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离;
6、Docker的集中化管理工具还不算成熟,各种虚拟化技术都有成熟的管理工具,比如:VMware vCenter提供完备的虚拟机管理能力;
7、Docker对业务的高可用支持是通过快速重新部署实现的,虚拟化具备负载均衡,高可用、容错、迁移和数据保护等经过生产实践检验的成熟保障机制,Vmware可承诺虚拟机99.999%高可用,保证业务连续性;
8、虚拟化创建是分钟级别的,Docker容器创建是秒级别的,Docker的快速迭代性,决定了无论是开发、测试、部署都可以节省大量时间;
9、虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化,Docker在Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署。
docker技术的三大核心概念是什么? 镜像:镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
容器:容器是基于镜像创建的,是镜像运行起来之后的一个实例,容器才是真正运行业务程序的地方。如果把镜像比作程序里面的类,那么容器就是对象。
镜像仓库:存放镜像的地方,研发工程师打包好镜像之后需要把镜像上传到镜像仓库中去,然后就可以运行有仓库权限的人拉取镜像来运行容器了。
centos镜像几个G,但是docker centos镜像才几百兆,这是为什么? 一个完整的Linux操作系统包含Linux内核和rootfs根文件系统,即我们熟悉的/dev、/proc/、/bin等目录。我们平时看到的centOS除了rootfs,还会选装很多软件,服务,图形桌面等,所以centOS镜像有好几个G也不足为奇。
而对于容器镜像而言,所有容器都是共享宿主机的Linux 内核的,而对于docker镜像而言,docker镜像只需要提供一个很小的rootfs即可,只需要包含最基本的命令,工具,程序库即可,所有docker镜像才会这么小。
讲一下镜像的分层结构以及为什么要使用镜像的分层结构? 一个新的镜像其实是从 base 镜像一层一层叠加生成的。每安装一个软件,dockerfile中使用RUM命令,就会在现有镜像的基础上增加一层,这样一层一层的叠加最后构成整个镜像。所以我们docker pull拉取一个镜像的时候会看到docker是一层层拉去的。
分层机构最大的一个好处就是 : 共享资源。比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
讲一下容器的copy-on-write特性,修改容器里面的内容会修改镜像吗? 我们知道,镜像是分层的,镜像的每一层都可以被共享,同时,镜像是只读的。当一个容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
一、 Linux的目录结构 1.概述 其采用的是层式的树状目录结构,在此结构中的最上层是根目录”/”,然后再次目录下创建其他目录。在linux系统中,一切皆为文件。
2.Linux的目录结构 /bin【常用】(/user/bin、/user/local/bin)
是Binary的缩写,这个目录存放着最经常使用的命令
/sbin(/user/bin、/user/local/bin)
s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序
/home【常用】
存放普通用户的主目录,在Linux中每个用户都有自己的目录,一般该目录名是以用户的账号命名
/root【常用】
该目录为系统管理员,也称为超级权限者的用户主目录
/lib
系统开机所需要最基本的动态连接共享库,其作用类似于Windows里的DLL文件,几乎所有的应用程序都需要用到这些共享库
/lost+found
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件
一般隐藏起来,窗口输入cd / (进入根目录)->ls(显示的意思)
/etc【常用】
所有的系统管理所需要的配置文件和子目录 my.conf
一般安装mysql等就会出现该目录下的配置文件
/usr【常用】
这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类 似与windows下的program files目录。比如存放的一些浏览器,或者编译器 均会放在该目录下
/boot【常用】
存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件
/proc【不能动】
这个目录是一个虚拟目录,它是系统内存的映射,访问这个目录来获取系统信息
/srv 【不能动】
service缩写,该目录存放一些服务启动之后需要提取的数据
/sys【不能动】
这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现出现的一个文件系统sysfs
/tmp
这个目录是用来存放一些临时文件的
/dev
类似于windows的设备管理器,把所有的硬件用文件的形式存储
/media【常用】
Linux系统会自动识别一些设备,例如U盘等,当识别后,Linux会把识别的设备挂载到这个目录下
/mut【常用】
系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将外部的存储挂载在/mnt上
/opt
这是给主机额外安装软件所摆放的目录。如安装ORACLE数据库,JDK就可以放到该目录下。默认为空
/usr/local【常用】
这是另一个给主机额外安装软件所安装的目录。一般是通过编译源码方式安装的程序
var【常用】
这个目录中存放着在不断扩充着的东西,习惯将被修改的目录放在这个目录下。典型的就是记录各种日志文件
selinux【security-enhanced linux】
SELinux是一种安全子系统,他能控制程序只能访问特定文件,有三种工作模式,可以自行设置
二、远程登录Linux Linux服务器是项目小组开发的,正式上线的项目是运行在公网上的。因此程序员登录需要远程登录到Linux服务器进行项目管理或开发。登录的方式有两种——Xshell和XftpXshell用于操作命令,Xftp主要用于文件的上传与下载 1. Xshel介绍和Xftp介绍 Xshell是目前最好的远程登录到Linux操作的软件,速度流畅并且完美的解决了中文乱码问题,是一个强大的安全终端模拟软件,支持SSH1,SSH2以及Windows下的TELNET协议。可以再windows界面下用来访问远端不同系统下的服务器,从而比较好的达到远程操作终端的目的。
Xftp是一个基于windows平台的功能强大的SFTP、FTP文件传输软件。使用该软件,用户可以在Windows和Linux之间传输文件
2.下载 下载free-for-home-school版本
下载地址:https://www.netsarang.com/en/free-for-home-school/
进入之后,输入邮箱和姓名,点击邮箱发送的链接。
三、XSHELL安装与连接 右键以管理员身份运行该程序进行连接。注意此处我们需要知道虚拟的IP地址。在外界去访问虚拟机时,我们同样需要IP地址用于访问该地址。进入虚拟机后,右键打开终端,输入命令(ifconfig)
此时在windows这边 使用ping+IP地址,查看地址是否连接成功。如果连接成功 可以进行下一步双击打开Xshell
在生产环境中,需要关闭druid的页面,以免被攻击。
application.properties配置文件中添加参数
# Druid 数据源监控配置 # 是否启用StatViewServlet(监控页面)false为不启动 spring.datasource.druid.stat-view-servlet.enabled=true spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* # IP白名单(没有配置或者为空,则允许所有访问) spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.0.1 # IP黑名单 (存在共同时,deny优先于allow) spring.datasource.druid.stat-view-servlet.deny=192.168.0.0 # 禁用HTML页面上的“Reset All”功能 spring.datasource.druid.stat-view-servlet.reset-enable=false # 登录名 spring.datasource.druid.stat-view-servlet.login-username=admin # 登录密码 spring.datasource.druid.stat-view-servlet.login-password=admin
凸优化在学术研究中非常重要,经常遇到的问题是证明凸性。常规证明凸性的方式是二阶导数的黑塞矩阵为半正定,或者在一维函数时二阶导数大于等于零。但很多时候的数学模型并不那么常规、容易求导的,若能够知道一些保留凸性的运算,将能够显著减少证明凸性的难度。这篇博客总结一些这个知识点。
1. 非负加权和 若函数 f 1 , … , f m f_1,\dots,f_m f1,…,fm 为凸函数,参数 w 1 , … , w m w_1,\dots,w_m w1,…,wm 非负,则函数
f = w 1 f 1 + ⋯ + w m f m f=w_1f_1+\dots+w_mf_m f=w1f1+⋯+wmfm
为凸函数。
这可以推广到无限加权和的情况,若函数 f ( x , y ) f(x,y) f(x,y) 对于 y ∈ A y\in \mathcal{A} y∈A 的每个值都是 x x x 的凸函数,并且 w ( y ) ≥ 0 w(y)\geq 0 w(y)≥0,那么函数
前言 公司新需求需要导出ppt给业务用,查阅资料后发现也挺简单的,记录一下。
如有不懂的可以留言!!!
1.安装包 npm install pptxgenjs --save 2.引入包 在需要使用的文件中引入
import Pptxgen from "pptxgenjs" 导出事件
<Button type="primary" @click="exportPPT">导出周报</Button> 这里有几个注意点说一下 slide 当前PPT页,可以通过addText(),addTable()等方法在当前页面添加文字、图表、图片等元素Text 文字,可以对ppt文字颜色、字体大小、字体阴影、背景颜色、文字位置等属性进行配置,达到自己想要的效果Table 表格, 可以添加ppt表格,但是表格内只能放文字和数字Charts 图表 图表,可以支持常见的饼状图、柱状图、折线图等,配置项也挺全的,横纵坐标,legend等啥都有,基本可以满足常用。 3.使用 js代码
exportPPT() { // 1. 创建PPT const pres = new Pptxgen() // 2. 创建一个PPT页面,每调用一次 pres.addSlide() 都可以生成一张新的页面 // 建议把每个页面的构造抽成一个个函数,然后通过函数调用生成新页面,代码不会很乱 const slide = pres.addSlide() // 3. 调用addTetx(),在PPT页面中插入文字“Hello World from PptxGenJS...” // 括号里面是对文字的配置,文字横坐标x为1.5,纵坐标y为1.5,字体颜色 363636…… // 关于坐标长度与px的转换 x 1 = 127~128px 左右 slide.addText('需求进度', { x: 0.2, // 横坐标 y: 0.
github
sublime使用python编写插件,安装好sublime后,就自带了2个库sublime,sublime_plugin,基于这2个库,我们可以开发许多插件,以下就是一个简单的入门实例。
API介绍在API Reference
官方教程在How to Create a Sublime Text 2 Plugin | Envato Tuts+
1.推荐一个截图软件Snipaste
2.打开tools->developer->new plugin
3.保存生成的文件xxx.py到Packages下,新建一个文件夹,自定义名称。
4.sublime会搜索packages下的py文件,用ctrl + ` 打开控制面板。输入view.run_command('example'),就可以看到文本中首行插入了Hello, World!,即执行了 self.view.insert(edit, 0, "Hello, World!")
5.Example就是这个类class的名称,用run command运行它的时候,就执行run这个函数下的指令(大概是这个意思)。一个py文件下可以有多个class,1个class下只有1个run入口。其他教程也有说明,Command前面的字段是命令名称,按大写字母分段,调用时都使用小写。也就是说Command前面可以写Example和example,但不能写ExaMple。
6.self.view.insert(edit, 0, "Hello, World!") 在API手册中看到,
insert(edit, point, string)intInserts the given string in the buffer at the specified point. Returns the number of characters inserted: this may be different if tabs are being translated into spaces in the current buffer. 在指定point的位置插入后面string。
未播放的时候 首先看正常展示的时候,还没又开始播放
这个时候我们打开图层看一下,发现视频时长和播放按钮都是放在
视频封面图上的
播放的时候 我们看到的播放视频的画面
我们发现,我们之前在未播放状态看到的视图,仍然还在封面视图上,只是被视频画面盖住了
然后再看视频画面视图,如下图,该视图也是放在封面视图上面的
和播放按钮拥有同一个父视图,只是画面视图是开始播放视频
的时候在添加到封面视图上的,所以播放按钮被盖住了
在看控制视图的层级,控制视图被添加到视频画面视图上
通过代码查看添加时机 因为我这里是在tableView 中播放视频的,所以这里
使用Playerindex 方式播放视频
我这里在初始换的时候,传控制视图
self.playerController.controlView = self.controlView; 查看zfplayer ,会在设置控制视图的方法中
调用layoutPlayerSubviews方法
layoutPlayerSubviews 方法会将控制视图添加到视频画面视图上
如下图所示,setPlayindex 会触发layoutPlayerSubviews 方法
layoutPlayerSubviews 方法会讲视频视图添加到容器视图上
而容器视图就是cell中的视频封面视图
西门子PLC学习 第一章、电学知识第二章、中间继电器第三章、延时继电器第四章、硬件接线第五章、电路图转梯形图+软件操作第六章、脱离电路图编程第七章、计数器第八章、置位、复位 第一章、电学知识 第二章、中间继电器 第三章、延时继电器 第四章、硬件接线 第五章、电路图转梯形图+软件操作 第六章、脱离电路图编程 第七章、计数器 第八章、置位、复位