webpack4打包实战

一、模块化打包工具的由来 ES Module存在环境兼容问题,通过模块化方式划分的模块较多,网络请求频繁,在前端应用开发中不仅仅需要JavaScript代码需要模块化,随着应用的日益复杂,html,css同样也面临相同的问题,也就是说,所有的前端资源都需要模块化。 所需要的工具需要满足的条件: 新特性代码编译模块化JavaScript打包支持不同文件类型的资源模块 打包工具:解决前端整体的模块化,并不单指JavaScript模块化 二、模块打包工具概要 核心: 模块打包器(Module bundler)模块加载器(loader)代码拆分(code splitting)资源模块(asset module) 打包工具解决的是前端整体的模块化,并不单指javascript模块化 三、webpack 快速上手 具体过程如下 创建package.json,执行命令:yarn init --yes安装webpack:yarn add webpack webpack-cli --dev查看webpack版本:yarn webpack --version 或 npx webpack -v打包:执行yarn webpack,此时会生成一个dis文件夹,文件中有main.js修改html的js引入路径,并去掉type=module也可以在script中定义: "scripts": { ​ "build":"webpack" }, //后期只使用:yarn build即可 // heading.js export default () => { const element = document.createElement('h2') element.textContent = 'Hello World!' element.addEventListener('click',()=>{ alert('hello webpack') }) return element } //index.js import createHeading from './heading.js' const heading = createHeading() document.body.append(heading) <!

vue3-父子组件间通信

文章目录 方案一:props/emitsprops:父组件->子组件emits:子组件->父组件 方案二:v-model/ emits方案三:ref/emits应用场景 在实际业务开发的过程中,我们时常会遇到组件间的通信问题,比如:父子组件间通信、同级组件间通信等。本篇文章中主要介绍父子组件间通信。父子组件间通信主要有以下常见形式: 方案父组件向子组件子组件向父组件props/emitspropsemitsv-model/emitsv-modelemitsref/emitsrefemits 不再说明!!!父组件->Parent.vue;子组件->Children.vue,并且代码主要展示template和script部分 方案一:props/emits props/emits是最常用的形式,也是最基础的方案。其主要过程是: 1、父组件->子组件:子组件先定义props对象并渲染到标签里,然后在父组件中调用子组件,通过属性的方式“: 变量名= ”绑定在标签上。 2、子组件->父组件:父组件先声明数据变量和更新函数然后通过“@函数名= ”绑定事件,然后子组件通过emits向父组件发送更新信号,一般伴随着数据变量。 props:父组件->子组件 首先要在子组件Children.vue定义props对象并且使用。我们先来看一下下面的代码: // Children.vue <script> export default defineComponent({ // props: ['title', 'index', 'userName', 'uid'] props: { // 可选,并提供默认值 title: { type: String, required: false, default: '默认标题', }, // 默认可选,单类型 index: Number, // 添加一些自定义校验 userName: { type: String, // 在这里校验用户名必须至少 3 个字 validator: (v) => v.length >= 3, }, // 默认可选,但允许多种类型 uid: [Number, String], }, // 在这里需要添加一个入参 setup(props) { // 该入参包含了当前组件定义的所有 props console.

如何将img转换成vmdk

使用StarWind V2V Converter这款软件可以方便的将img格式转换成vmdk格式 StarWind V2V Converter 使用步骤如下 1.打开StarWind V2V Converter软件 选择“是” 2.选择本地文件选项 选择“local file” 3.点击下一步 选择“next” 4.选择需要转换的文件 选择需要转换的文件 5.点击下一步 选择“next” 6.选择本地文件 选择“local file” 7.点击下一步 选择“next” 8.选择vmdk并点击下一步 选择“vmdk”并点击“next” 9.选择“VMware Workstation growable image”并点击下一步 选择“VMware Workstation growable image”并点击“next” 10.选择文件路径并点击转换 选择路径并点击“Convert” 11.完成转换点击结束 点击“finish” ⚠️注意:在中文路径下转换可能会出错,建议选择英文路径。

PTA作业

目录 9-1 求最大值及其下标 9-2 选择法排序 9-3 将数组中的数逆序存放 9-4 找出不是两个数组共有的元素 9-5 求一批整数中出现最多的个位数字 9-1 求最大值及其下标 本题要求编写程序,找出给定的n个数中的最大值及其对应的最小下标(下标从0开始)。 输入格式: 输入在第一行中给出一个正整数n(1<n≤10)。第二行输入n个整数,用空格分开。 输出格式: 在一行中输出最大值及最大值的最小下标,中间用一个空格分开。 输入样例: 6 2 8 10 1 9 10 输出样例: 10 2 #include <stdio.h> main() { int n,i,j; scanf("%d",&n); int a[11]; for(i=0;i<n;i++) scanf("%d",&a[i]); for(j=0;j<n;j++) { if(a[0]<a[j]) { a[0]=a[j]; i=j; } else if(a[0]==a[j]) { a[0]=a[j]; if(i>j) { i=j; } } } printf("%d %d",a[0],i); } 9-2 选择法排序 本题要求将给定的n个整数从大到小排序后输出。 输入格式: 输入第一行给出一个不超过10的正整数n。第二行给出n个整数,其间以空格分隔。 输出格式: 在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。 #include <stdio.h> void SelectSort( int nums[10], int n ); int main(){ int n, i; scanf("

在 Linux 上搭建 VisualSVN Server(svn 服务端)

1、检查是否安装了低版本的 SVN # rpm -qa | grep subversion 如果已安装 SVN,则会返回版本信息。这时需要卸载旧版本的 SVN。 # 卸载旧版本 SVN # yum remove subversion 2、安装 SVN visualsvn web site 点击直达 # yum install subversion 3、检查安装是否成功 # svnserve --version 4、代码库创建 # mkdir -p /opt/svn/repositories # svnadmin create /opt/svn/repositories 执行上面的命令后,自动建立 repositories 库,查看 /opt/svn/repositories(路径和库名可以根据自己的需要修改) 文件夹发现包含了 conf,db,format,hooks,locks, README.txt 等文件,说明一个 SVN 库建立完成。 5、配置代码库 进入上面生成的文件夹 conf 下,进行配置 # cd /opt/svn/repositories/conf 5.1 用户密码 passwd 配置 # vi passwd 5.2 权限控制 authz 配置 # vi authz 目的是设置哪些用户可以访问哪些目录,authz 文件的内容如下:

前端页面适配之postcss-px-to-viewport

一:简介 postcss-px-to-viewport 是一个 PostCSS 插件,用于将 CSS 中的 px 单位转换为 vw 或 vh 单位。它可以帮助我们实现在不同屏幕尺寸下的自适应布局,以提高页面的响应性和可用性。 二:postcss-px-to-viewport原理 遍历 CSS 文件中的所有样式规则,找到其中所有的 px 单位值。将每个 px 值根据设备屏幕的宽度和高度转换为对应的 vw 或 vh 值。例如,如果设备屏幕的宽度为 750px,样式表中有一个宽度为 100px 的元素,那么插件将把它转换为 13.33vw(100/750*100)的值。生成转换后的 CSS 文件。 三:实现步骤 1.安装 postcss-px-viewport 插件及其依赖: npm install postcss-px-viewport postcss-viewport-units postcss-preset-env -D 其中,postcss-px-viewport 是主要的插件,postcss-viewport-units 和 postcss-preset-env 是其依赖,用于支持更多的 CSS 新特性和语法转换。 2.在项目根目录下创建 postcss.config.js 文件,配置 postcss-px-viewport 插件: module.exports = { plugins: { 'postcss-px-to-viewport': { unitToConvert: 'px', // 需要转换的单位,默认为"px" viewportWidth: 320, // 设计稿的视口宽度 unitPrecision: 5, // 单位转换后保留的精度 propList: ['*'], // 能转化为vw的属性列表 viewportUnit: 'vw', // 希望使用的视口单位 fontViewportUnit: 'vw', // 字体使用的视口单位 selectorBlackList: [], // 需要忽略的CSS选择器 minPixelValue: 1, // 最小的转换数值,如果为1的话,只有大于1的值会被转换 mediaQuery: false, // 媒体查询里的单位是否需要转换单位 replace: true, // 是否直接更换属性值,而不添加备用属性 exclude: [], // 忽略某些文件夹下的文件或特定文件 include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//) landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape) landscapeUnit: 'vw' // 横屏时使用的单位 }, 'postcss-preset-env': { browsers: 'last 2 versions' //指定只对最近 2 个版本的浏览器进行兼容性处理。 } } } 四:postcss-px-to-viewport的优缺点 优点:

内存泄漏和内存溢出的区别

参考答案 内存溢出(out of memory):指程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory。内存泄露(memory leak):指程序在申请内存后,无法释放已申请的内存空间,内存泄露堆积会导致内存被占光。memory leak 最终会导致 out of memory。 1、概念的区分 1.1、 内存泄露 memory leak 程序运行结束后,没有释放 所占用的内存空间。 一次内存泄漏 似乎不会有大的影响,但内存泄漏 不断累积,最终可用内存会变得越来越少。 比如说,总内存大小是100 MB,有40MB的内存一直无法回收,那么可用的只有60MB 。这40MB的就是内存泄漏。 内存泄漏,就是 程序运行结束后,没有释放的内存。 1.2、 内存溢出 out of memory 程序运行时,在申请内存空间时,没有足够的内存空间供其正常使用,程序运行停止,并抛出 out of memory 。 比如程序运行时申请了一个10MB 空间, 但是当前可用内存只有5MB,程序无法正常执行,这就是内存溢出。 内存溢出 ,可以理解为 程序运行需要的内存 大于当前可用的内存。 1.3 举例 1)单例模式中,单例的生命周期和应用程序是一样长的,所以单例程序中如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致 内存泄露 的产生。 2)一些提供close的资源未闭导致 内存泄漏 。数据库连接(dataSource.getConnection() ),网络连接(socket)和 IO流的连接必须在finally中 close,否则不能被回收的。 3)读取大文件,一次读取的文件大于可用内存,会导致 内存溢出 。可用内存是1G,怎么读取2G的文件呢?建一个100MB的字节数组,读10次。 2、二者的区别和联系: 2.1、区别 内存泄露: 程序运行结束后,所占用的内存没有全部释放。 内存溢出:程序运行时,需要的内存大于当前可用的内存, 内存不足,程序无法继续执行,抛出 “内存溢出”,程序运行中断,结束。 2.2、联系 一次 内存泄露 可能对程序运行没有明显的影响,多次 内存泄露 最终会导致 内存溢出 。

Vue-控制台显示:You are running Vue in development mode.Make sure to turn on production mode when..

控制台显示:You are running Vue in development mode.Make sure to turn on production mode when deploying for production.See more tips at https://vuejs.org/guide/deployment.html 如下图所示: 解决方法①: 在代码里添加输入: <script type="text/javascript" > Vue.config.productionTip = false //阻止vue在启动时生成生产提示 </script> 如果方法①解决不了, 方法②: 在vue.js中查找以下代码(查找代码快捷键:Ctrl+Shift+F),注释掉。 目标代码块: if (config.productionTip !== false && typeof console !== 'undefined') { // @ts-expect-error console[console.info ? 'info' : 'log']("You are running Vue in development mode.\n" + "Make sure to turn on production mode when deploying for production.

使用PowerShell运行第一个Python程序

使用PowerShell运行第一个Python程序 1-在PowerShell中切换当前路径2-使用Notepad++文本编辑器3-运行Hello World程序 在开发open MV之前需要掌握Python编程的一些语法及规范,open MV入门教程中使用的是PowerShell来运行Python程序,这里老师推荐使用的是Phython2。在搭建环境到运行第一个程序之前遇到了一些问题,总结一下: 1-在PowerShell中切换当前路径 方法1:打开PowerShell,并输入Set-location -Path加将要切换的路径: Set-location -Path F:\ABC\PhyProject // F:\ABC\PhyProject为将要切换到的路径 回车 PS C:\Python27> Set-location -Path F:\ABC\PhyProject PS F:\ABC\PhyProject> 方法2:使用cd指令,进入指定目录 PS C:\Python27> cd F:\ABC\PhyProject PS F:\ABC\PhyProject> 2-使用Notepad++文本编辑器 Notepad++ 就是增强的记事本,可以免费使用,自带中文并支持很多计算机编程语言,不仅有语法高亮度显示,也有语法折叠功能,并且支持宏以及扩充基本功能的外挂模组。 Notepad++安装包下载和安装可以参考以下链接,这位老师写的很详细: https://blog.csdn.net/weixin_53928448/article/details/125584962 3-运行Hello World程序 第一步:编辑代码 在指定工程文件夹中使用Notepad++新建一个python文件,并命为hello.py,在文件中输入代码: print 'hello World!' 第二部:运行代码 将PowerShell工作路径切换到工程文件夹,在控制台输入:python hello.py PS F:\ABC\PhyProject> python hello.py hello World! PS F:\ABC\PhyProject> 向前迈进的一小步,未完待续…

集成运放及其经典电路详解

文章目录 【 1. 什么是集成运放 】【 2. 集成运放的电压传输特性 】【 3. 比例运算电路 】1. 反相比例2. 同相比例3. 电压跟随器 【 4. 加减运算电路 】1. 求和反相求和运算电路同相求和运算电路 2. 加减运算电路 【 5. 积分运算电路 】【 6. 微分运算电路 】【 7. 对数运算电路 】【 8. 指数运算电路 】【 9. 仪表放大器 】【 10. 经典放大电路 】 【 1. 什么是集成运放 】 全称为:集成运算放大器 我们拆解来看: 集成:将电路封装,留出接口,使其模块化,便于移植。运算:这里涉及到的是一些数学运算,不过这里的运算对象不是简单的数字,而是电参量,是对电参量进行了加减乘除、积分、微分等计算。放大器:就是把电参量进行放大,比如把电压从1V放大至5V。 总的来说,就是通过内部元器件的电参量关系将电参量进行运算,达到放大的目的。 【 2. 集成运放的电压传输特性 】 集成运放有 同相输入端 UP和 反相输入端 UN,这里的“同相”、“反相”是指运放的输入电压UP、UN与输出电压UO之间的相位关系。从外部看,可以认为集成运放是一个双端输入、单端输出,具有高差模放大倍数、高输入电阻、低输出电阻、能较好地抑制温度漂移的 差分放大电路 。集成运放的输出电压UO与输入电压即同相输入端与反相输入端之间的电位差UP-UN之间的关系曲线称为 电压传输特性 ,即:UO=f(UP-UN)。对于正、负两路电源供电即 双电源供电的集成运放的电压传输特性 如图4.1.2(b)所示。从图示曲线可以看出,集成运放有线性放大区域(称为线性区)和饱和区域(称为非线性区)两部分。在线性区,曲线的斜率为电压放大倍数;在非线性区,输出电压只有两种可能的情况,+UOM或-UOM。由于集成运放放大的是差模信号,且没有通过外电路引入反馈,故称其电压放大倍数为差模开环放大倍数,记作Aod,因而当集成运放工作在线性区时有:uo= Aod(uP- uN),通常Aod非常高,可达几十万倍,因此 集成运放电压传输特性中的线性区非常之窄。 集成运放的三大特性:虚短、虚断、虚地虚短:UP=UN,两输入端电压相等。虚断:IP=IN=0,两输入端的输入电流为0。虚地:UP=UN=0,当信号反向输入时存在(即信号从负输入端流进,而正输入端接地) 【 3. 比例运算电路 】 1.

笔记本电脑连接不上WiFi怎么办?4个实用解决方法!

案例:笔记本电脑连接不上WiFi怎么办 “朋友们,想问问大家知道为什么我的笔记本电脑连接不上WiFi呢?试了好几遍还是无法连接,遇到这种情况我应该怎么解决呢?感谢大家!” 在现代生活中,笔记本电脑成为了人们必不可少的工具之一。当笔记本电脑连接不上WiFi时,这将极大地影响我们的生产和生活。笔记本电脑连接不上WiFi怎么办?这4个实用的方法你会吗?一起来学学吧! 操作环境: 演示机型:联想GeekPro2020 系统版本:Windows 10 一、笔记本电脑怎么连接WiFi 经常需要使用笔记本的朋友可能知道,没有网络的电脑就如喝不到水的乌鸦,会让很多工作都无法正常进行。笔记本电脑无线网络连接不上,可能是由各种原因造成的,比如WiFi密码错误、网络信号问题、网络设置问题、网卡驱动问题、多台设备同时连接等,今天小编给大家介绍4种实用的解决方法! 方法一:检查WiFi密码是否正确 连接WiFi时,正确输入WiFi密码是连接的前提条件。因此,如果笔记本电脑无法连接WiFi,首先应该检查是否输入了正确的WiFi密码。 注意:输入密码时应注意大小写和特殊字符,可以在其他设备上检查一下WiFi密码是否正确。 方法二:检查WiFi信号 WiFi信号差是连接不上WiFi的常见原因之一。如果我们的笔记本电脑距离WiFi路由器太远,或者电脑和路由器之间的障碍物过多,比如隔墙等,都可能会由于信号遮挡而让我们无法连接WiFi。因此,如果发现无法连接WiFi,我们可以将笔记本电脑靠近WiFi路由器,或移除周围的障碍物,以获得更好的WiFi信号。 方法三:检查网络设置 如果网络被禁用了,我们的笔记本电脑是无法找到WiFi的,当发现笔记本电脑无法连接WiFi时,我们可以先查看网络是否被禁用了,具体操作如下: 打开【设置】,点击【网络和Internet】,找到【更改适配器选项】; 2.进入后找到要连接的网络,单击右键选择【连接/断开连接】。 方法四:检查网卡驱动问题 网卡驱动程序的问题也可能导致笔记本电脑无法连接WiFi。例如,网卡驱动程序过期或损坏,都可能导致WiFi连接不上。这时我们可以通过查看网卡驱动来解决,具体操作如下: 点击进入【此电脑】,再点击【管理】;在【设备管理器】中查看是否有黄色图标,若有黄色图标,则需要重新安装网卡驱动。 3.若无黄色图标,展开【服务和应用程序】,单击【服务】,找到【WLAN AutoConfig】,单击右键选择【启动】。 笔记本电脑连接不上WiFi的原因是多样的,解决的方式也各有不同。我们可以根据实际情况采取不同的方法。笔记本电脑连接不上WiFi怎么办?相信大家看完本文已经知道该怎么操作了,有需求的朋友可以进行尝试啦! 往期推荐: 怎样找回删除的照片?4个方法快速找回! u盘不显示怎么办?正确做法快收藏! 电脑速度慢怎么办?这些方法帮你快速提速!

父传子,子组件是弹窗,如何监听子组件中表单的变化

本来是用watch监听form表单数据中的变化的,但是发型弹窗关闭,打开时也会触发watch监听函数;又试了一下同时监听子组件的visible和form,还是不行。 解决方案:在打开子组件时,复制一份给preForm,并转为字符串保存下来。在打开修改弹窗,按下确定按钮时,对比form表单和preForm中的内容!!!

前端JS/TS面试题

JS面试题总结 一、this指向问题(1)this的理解(2)怎样改变this的指向问题(3)Call,bind,apply三者的区别(4)容易判读错的几种this情况(5)this指向问题,说输出;这两中a,b写法,在内存消耗上有什么区别 二、手写节流(throttle)和防抖(debounce)节流(throttle):防抖(debounce):改进:实现第一次点击和最后一次点击生效 三、js事件循环机制(宏任务,微任务,同步任务,异步任务)(1) JS事件循环机制概念(2)为什么js是单线程(3)线程和进程是什么?举例说明(4)js引擎的执行栈(5)setTimeout、Promise、Async/Await 的区别(6) Web Worker 标准(7)浏览器是多进程的浏览器包含的进程浏览器多进程的优势进程间的通信(进程通信) 什么是进程的死锁介绍一下银行家算法linux中硬链和软链的区别介绍一下linux文件绝对路径和相对路径四、跨域(1)为什么会出现跨域问题?(2)同源策略(3)为什么需要同源策略(跨域限制)(4)什么是跨域(5)怎么允许跨域(跨域解决办法)A、JSONPB、 CORS跨域资源共享:简单请求非简单请求(预检请求) C、Nginx反向代理D、webpack (在vue.config.js文件中)中 配置webpack-dev-server 五、es6的新特性common js和es6模块的区别 六、Symbol(es6新增)Symbol的应用场景 七、let var const的区别const是怎么实现的只能赋值一次 八、介绍下set,weakset,map,weakmap的区别Set:Weakset:Map:Weakmap: 九、原型和原型链(1)构造函数(2)为什么引入原型对象prototype(3) 原型对象(4)构造函数,实例对象,原型对象三者之间的关系(5)原型链(6)原型链打印题踩坑 10、了解JS的继承吗?ES5继承与ES6继承的区别(1)继承:(2)Es5和es6继承的区别:(3)js继承的六种方法: 11、js如何定义一个类并实现继承;要求不能使用es6的语法(手写一个寄生组合式继承)组合继承(构造函数和原型链实现继承)寄生组合式继承Es6实现继承 12、讲一讲Promise;语法Promise的缺点:Promise用法Promise.thenPromise.catchPromise.allPromise.anyPromise .finallyPromise .racePromise.allSettled 13、如何中止promise链式调用14、promise发生错误,怎么捕捉15、手写promise;手写promise.all;手写promise.any;手写promise.finally;手写Promise.race;手写Promise.allSettled手写Promise手写Promise.all:手写Promise.any:手写Promise.finally:手写Promise.race:手写Promise.allSettled: 17、什么是事件委托(事件代理),为什么在父元素上绑事件,子元素上点击可能触发。事件流/事件传播事件委托的实现 18、js数据类型,怎样判断数据类型;基本数据类型和引用数据类型的区别;怎么判断一个数组是不是Array类型(insatnceof,object.prototype.toString.call);堆和栈是什么js数据类型堆和栈判断方法Typeof:Instanceof:Object.prototype.toString.call():可以精准判断数据类型 19、undefined和null的区别20、箭头函数与普通函数的区别是什么?21、构造函数可以使用new生成实例,那么箭头函数可以吗?为什么?箭头函数不能使用new生成实例New的过程: 22、循环(遍历)的方法,各个方法的区别遍历 23、除了for...of还有哪些方法可以遍历字符串,数组中reduce方法有哪些参数,是怎样使用的24、怎么让对象的一个属性不可被改变(1) Object.defineProperty()(2)object.preventExtensions() 25.对浏览器的理解26.对浏览器内核的理解27.浏览器所用的内核28.浏览器内核比较29.浏览器的渲染原理30、重排重绘什么时候发生重排?什么时候发生重绘?如何减少重排重绘?浏览器的优化机制 31、flat数组扁平化flat方法递归处理(递归遍历每一项,若为数组继续遍历,否则concat(拼接))用reduce实现的数组扁平化(遍历数组每一项,若为数组就继续遍历,否则就concat(连接))扩展运算符已知如下数组:var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];编写一个程序将数组扁平化并去除其中重复部分数据,最终得到一个升序且不重复的数组 32、什么是闭包;闭包的作用;使用闭包实现每秒钟打印数组中的一个数组[5,4,3,2,1]使用闭包实现每秒钟打印数组中的一个数组[5,4,3,2,1]闭包:闭包产生的原因:闭包的作用:缺点: 33、输出什么/函数每秒依次输出(1)怎么修改可以让上面代码从1到5秒依次输出0-4,写出你能想到的所有方法 33、手写:ajax请求,解释状态码含义;手写ajax状态码含义 34、手写ajax请求,用promise封装35、== 和===的区别36、JS隐式转换37、如何让if(a==1&&a==2&&a==3)条件成立?38、JS的垃圾回收机制v8引擎对垃圾回收做了哪些优化增量标记:对活动对象和非活动对象进行标记懒性清理:V8采用的是惰性清理来释放内存并发回收: 38、内存泄露(memory leak)39、内存三大件40、浏览器存储方式39、JS的设计模式模块模式原型模式观察者模式单例模式工厂模式 为什么JS单例模式不会产生互锁现象(异步) 40、考查原型和函数的打印题41、手写代码:浏览器打开了一个页面,在控制台执行脚本,获取页面TagName种类。42、连续赋值-输出以下代码的执行结果并解释为什么?(连续赋值的坑)43、操作DOM的方法创建新节点添加节点删除节点替换节点获取/查找节点属性操作getQuerySelector和getClassName的区别 44、求两个数组的并集和交集和差集45、数组的常用方法46.

安装SeisMix计算跨密度混合面

conda create -n SeisMix python=3.8 conda env list conda activate SeisMix conda config --add channels conda-forge cat ~/.condarc conda install mtspec numpy scipy segyio gsw jupyter matplotlib git https://github.com/alex-dickinson/SeisMix.git

java-EasyExcel导出excel设置单元格为文本格式(含代码)

java-EasyExcel导出excel设置单元格为文本格式(含代码) 在使用EasyExcel导出excel模板时。我们会发现导出的日期和大长度数字都会自动更换格式,不是文本格式。并且在空白单元格输入日期也是格式有问题的,如下所示,可以看到当输入相同的日期时,格式会变成自适应,不是文本格式了,所以我们需要从代码里设置,导出表格的单元格固定是文本(我的项目中使用EasyExcel是2.0+的版本,不同版本可能代码实现是不同的,但是原理都是一样的)。 一、设置空白单元格的格式为文本 新建一个handler实现SheetWriteHandler接口,在创建单元格时设置格式为文本 public class CustomSheetWriteHandler implements SheetWriteHandler { // 设置100列column private static final Integer COLUMN = 100; @Override public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { } @Override public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { for (int i = 0; i < COLUMN; i++) { // 设置为文本格式 SXSSFSheet sxssfSheet = (SXSSFSheet) writeSheetHolder.getSheet(); CellStyle cellStyle = writeWorkbookHolder.getCachedWorkbook().createCellStyle(); // 49为文本格式 cellStyle.setDataFormat((short) 49); // i为列,一整列设置为文本格式 sxssfSheet.setDefaultColumnStyle(i, cellStyle); } } } 二、设置含有数据的单元格的格式为文本 因为在自己的项目中发现,如果只是完成上面第一步,会发现导出的模板中,含有数据的单元格的格式还是常规,当重新输入后,日期又自适应,变成不是文本字符串了,所以我这里还是设置了含有数据的单元格的格式为文本

苹果电脑录屏,掌握这两种方法就足够

案例:苹果电脑怎么录制电脑屏幕视频? “我看到我身边的同学可以录制电脑屏幕,我也想尝试一下。可是它们使用的电脑是Windows电脑,而我的电脑是苹果电脑。他们录制电脑屏幕的方法并不适用于我的电脑,有没有小伙伴知道苹果电脑录屏怎么录吗?” 在现今的数字时代,屏幕录制已成为我们日常生活和工作中必不可少的一部分。苹果电脑用户也不例外。苹果电脑录屏功能在哪里?苹果电脑录屏软件哪个好用?本文将向大家介绍两种最常用的苹果电脑录屏工具:QuickTime Player和数据蛙录屏软件,帮助读者轻松地完成苹果电脑的屏幕录制。 一、苹果电脑录屏功能在哪 我们可以使用苹果电脑应用中的QuickTime Player(视频播放器,也可以用于简单的屏幕录制),进行苹果电脑录屏。如果您想要录制精美、专业的录屏,您可以尝试一下这款苹果电脑录屏神器——数据蛙录屏软件。 二、苹果电脑录屏怎么录 录屏方法1.使用QuickTime Player QuickTime Player是Mac系统中自带的多媒体播放器和屏幕录制软件,非常简单易用,无需下载安装。 使用QuickTime Player进行苹果电脑录屏 演示机型:华硕 TUF Dash FX516PM 系统版本:Windows10 软件版本:QuickTime Player 步骤1.点击打开QuickTime Player,点击“文件”菜单,选择“新建屏幕录制”。 步骤2.在出现的录制窗口中,点击红色圆形按钮开始录制。 备注:录制前,也可以通过下拉菜单选择麦克风、摄像头等选项。 录屏方法2.使用数据蛙录屏软件 数据蛙录屏软件是一款专业的屏幕录制工具,可广泛应用于游戏录制、教育培训、工作演示等领域。 使用数据蛙录屏软件进行苹果电脑录屏 演示机型:惠普(HP)战X 系统版本:Windows10 软件版本:数据蛙录屏软件 步骤1:数据蛙录屏软件是一款专为苹果电脑录屏设计的软件。录制前,需要进行下载。 步骤2:进入“视频录制”页面,录制前,可以设置录屏的范围、选择是否录制麦克风声音和摄像头视频。也可以在【设置】页面对录屏格式、帧率等进行设置,点击“REC”按钮开始录制。 步骤3:录制完成后,可以对文件进行处理(高级剪辑),点击“完成”按钮结束录制。 很多小伙伴进行苹果电脑录屏后,会发现录屏没有声音。备注:苹果电脑录屏怎么录内部声音?您可以在录制前,开启扬声器,这样可以成功录制内部声音。 以上是两款软件的简单介绍,以及使用它们进行录屏的方法,苹果电脑录屏软件哪个好用?相比QuickTime Player,数据蛙录屏软件具有以下优势: 功能强大、页面友好;可以录制屏幕、麦克风声音、摄像头画面,还可以进行视频剪辑和添加字幕等操作;流畅无水印录制视频;支持无限时长录制。 本文介绍了苹果电脑录屏两种方法:使用自带的QuickTime Player和第三方录屏软件数据蛙录屏软件。其中QuickTime Player可以方便录制简单的视频。想要录制专业复杂的内容,数据蛙录屏软件是一个更好的选择。它支持更多的录制模式,录制更高品质的视频,并支持自由编辑,是一个功能更加全面的苹果电脑录屏工具。如果您想更好地录制苹果电脑,可以下载此软件进行录制操作哦! 往期回顾: 电脑怎么既录屏又录人脸?分享2个宝藏方法,轻松学会!https://mp.csdn.net/mp_blog/creation/editor/129714266 电脑锁屏快捷键是什么?如何快速进行电脑锁屏https://blog.csdn.net/shujuwa_data/article/details/129726948 电脑自带录屏怎么使用?教您2招,快速搞定https://blog.csdn.net/shujuwa_data/article/details/129724121?spm=1001.2014.3001.5501

Uduino和unity的联动(存在不认识设备的情况如何操作)

Uduino在导入unity有可能会出现找不到设备,此时我们可以导入Uduino Library这个插件,此时我们需要把Uduino/Arduino这个文件夹下面的文件目录拷贝到C:/Users/admin/Documents/Arduino/libraries(默认是这个目录下面) 此时我们能发现Unity可以认识Arduino设备,此时我们就可以正常看见我们的设备了 下面是示意代码 using System.Collections; using System.Collections.Generic; using UnityEngine; using Uduino; public class ArdunioTest : MonoBehaviour { /// <summary> /// 小灯管脚 /// </summary> int pin11; /// <summary> /// 按钮管脚 /// </summary> int pin2; /// <summary> /// Arduino设备 /// </summary> UduinoDevice arduinoDevice; public GameObject myCube; // Start is called before the first frame update void Start() { //当连接板子时触发 UduinoManager.Instance.OnBoardConnected += OnArduinoConnected; } /// <summary> /// 当板子链接时 /// </summary> private void OnArduinoConnected(UduinoDevice device) { //拿到pin口 pin11 = UduinoManager.

使用VS2019编译C语言遇到的字符类型输入问题

使用vs2019编译c语言程序时,发现scanf(“%c”,&d);无法输入结果 问题描述 提示:发现在循环中,始终无法输入字符,输入字符语句一直被跳过 for (int i = 0; i < num; i++) { printf("请输入第%d个学生的姓名:",i+1); scanf("%s",parr[i].name); printf("请输入第%d个学生的年龄:", i + 1); scanf("%d", &parr[i].age); printf("请输入第%d个学生的分数:", i + 1); scanf("%f", &parr[i].score); printf("请输入第%d个学生的性别:", i + 1); scanf(" %c",&parr[i].sex); printf("\n第%d个学生的性别为:%c", i + 1,parr[i].sex); } 原因分析: 提示:查阅资料发现在 "%c"前加一个空格即” %c“即可正常输入 scanf 在接受数据时,误接收到了上一个”\n“ 导致程序直接跳过字符输入语句 原因:%c只能接收单个字符 解决方法: 方法一:再加一句scanf。 方法二:使用函数fflush,清除流,就是在每个接收字符的scanf语句前面,加上fflush(stdin); 方法三:在%c前面加空格,抵消掉\n https://blog.csdn.net/i1178632444/article/details/5028198 https://blog.csdn.net/ztmajor/article/details/80728602

typedef uint8_t u8;(stm32数据类型)

在stm32单片机的库文件里有这么一段u8和u16的定义 typedef uint8_t u8; typedef uint16_t u16; 而uint8_t和uint16_t的定义是这样的 typedef unsigned char uint8_t; typedef unsigned short int uint16_t; 意味着u8就是就是指代的unsigned char 意味着u16就是就是指代的unsigned short int C语言之数据类型详解_c语言数据类型_supergirl091的博客-CSDN博客 为什么这么定义? u8-----可以理解为无符号的8位2进制的数据,就是11111111-00000000,注意这里全部是正数,没有负数,第一位并不是符号位,u就是unsigned char的首字母,8就是8个位的意思。 u16同理 这种写法能很容易的表明有几个位,8位?16位?而最常见的数据类型就是无符号,所以u8的使用频率非常高,每次都老老实实的写unsigned char有点太烦人了,于是用u8来替代,简明易懂。 在单片机和操作系统中 typedef 会经常用到,它可以为某一个类型自定义名称。和#define比较类似。但是又有不同的地方。 typedef 创建的符号只能用于数据类型,不能用于值。而#define 创建的符号可以用于值。 typedef 是由编译器来解释,而不是预处理器。 typedef 使用起来更加灵活。 typedef的4种常见用法: 一、给已定义的变量类型起个别名 二、定义函数指针类型 三、定义数组指针类型 四、定义数组类型 总结一句话:“加不加typedef,类型是一样的“,这句话可以这样理解: 没加typedef之前如果是个数组,那么加typedef之后就是数组类型; 没加typedef之前如果是个函数指针,那么加typedef之后就是函数指针类型; 没加typedef之前如果是个指针数组,那么加typedef之后就是指针数组类型; typedef的4种常见用法_暴躁的野生猿的博客-CSDN博客

UnicodeDecodeError: utf-8 codec can t decode byte 0x8b in position 1: invalid start byte

今天爬虫自己blibli主页,但是一直显示这个错误,我去了主页上审查元素,明明主页上也是utf-8编码,但是就是错误,后面发现是自己响应头中加了这句 'accept-encoding': 'gzip, deflate, br', Accept-Encoding设置在请求头当中,会告诉服务器,我可以接受哪种编码压缩。 原因:浏览器访问网页添加"Accept-Encoding" = “gzip,deflate,br”没出错,是因为浏览器会自动解压缩从服务器中返回的对应的gzip压缩的网页;而我们编写的代码中,没有自动解码,将压缩后的数据当做普通的html文本来处理,会乱码。 解决方法: 1、直接删了'accept-encoding': 'gzip, deflate, br’ 2、删除gzip,br,变成'accept-encoding': 'deflate‘也可以 不过建议直接删除就行。

https对于http增加了什么协议?

具体来说,HTTPS协议对HTTP协议进行了加强,主要增加了以下协议: SSL/TLS协议:这是HTTPS的核心安全协议。它提供了一种安全的通信机制,可以在客户端和服务器之间建立一个安全通道,从而保证数据的机密性、完整性和可靠性。SSL/TLS协议使用数字证书来验证通信双方的身份,并使用公钥加密算法来加密数据。 加密算法:HTTPS使用一系列加密算法来保护通信数据的机密性。常用的加密算法包括AES、DES、3DES和RC4等。 数字证书:数字证书用于验证通信双方的身份。数字证书是由认证机构(CA)颁发的一种电子文档,包含了通信双方的公钥、通信双方的身份信息以及认证机构的数字签名等信息。 对称密钥加密:HTTPS在建立安全通道之后使用对称密钥加密算法来加密数据。对称密钥加密算法是一种速度较快、处理量较小的加密算法,可以在通信双方之间快速、可靠地加密和解密数据。 通过以上协议,HTTPS可以确保通信内容的安全性和完整性,保护用户的隐私和数据安全。

GPT 4.0 你知道的和你不知道的?

GPT 4.0 人工智能聊天机器人 介绍GPT 4.0之前,先给大家介绍一下整理的一个类ChatGPT相关的工具,有可以总结论文的、微软作图的、反ChatGPT检测的、数据标注的等等工具,感兴趣的小伙伴可以访问:github链接 言归正传 今天我们主要介绍一下GPT 4.0. 思维导图 基本上解决了之前以字符为粒度的问题。 代码生成和Debug的能力 运行成功!Amazing! 图片理解 GPT-4可以按像素处理其中的文字和图片,并给出对整篇论文的总结摘要 做物理题 总结 发布GPT-4的API https://openai.com/waitlist/gpt-4-api 公布技术论文 * 公开System Card https://cdn.openai.com/papers/gpt-4.pdf ChatGPT Plus:集成GPT-4的ChatGPT升级版 https://chat.openai.com/chat 工具整理: https://github.com/pengwei-iie/A_survey_and_tools_of_ChatGPT 更多有趣MRC文章见:复旦团队发布国内首个模型MOSS 类ChatGPT 【OpenAI 多模态预训练】VideoGPT?微软透露GPT-4或将在下周发布 GPT4来了?10秒钟做一个网站 ChatGPT?听说Biying把它下架了 又一个国内类ChatGPT模型?【秘塔科技上线自研LLM大模型「对话写作猫」】 BERT用于文本分类方法 利用逆向思维的机器阅读理解 相关文献 情感支撑对话综述 Bi-directional Cognitive Thinking Network for Machine Reading Comprehension 论文阅读 证据推理网络 Hybrid Curriculum Learning for Emotion Recognition in Conversation

使用JMeter 进行压力测试

前言 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。 一、准备工作 安装Java环境以及jmeter 二、实现步骤 1.启动jmeter 进入bin目录,使用jmeter.bat启动程序。 启动之后会有两个窗口,一个cmd窗口,一个JMeter的 GUI。 cmd窗口: 其中cmd窗口中的提示信息意思为 不要使用GUI运行压力测试,GUI仅用于压力测试的创建和调试;执行压力测试请不要使用GUI。使用下面的命令来执行测试: jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder] 并且修改JMeter批处理文件的环境变量:HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" JMeter : 2.创建测试 1.创建线程组 在“测试计划”上右键 【添加】-->【线程(用户)】-->【线程组】 设置线程数和循环次数。这里设置线程数为200,循环两次。 2.配置元件 在刚刚创建的线程组上右键 【添加】-->【配置元件】-->【HTTP请求默认值】配置需要进行测试的程序协议、地址和端口,当所有的接口测试的访问域名和端口都一样时,可以使用该元件,一旦服务器地址变更,只需要修改请求默认值即可。 3.构造HTTP请求 在“线程组”右键 【添加-】->【samlper】-->【HTTP 请求】设置需要测试的API的请求路径和数据。 4.添加HTTP请求头 在创建的线程组上右键 【添加】-->【配置元件】-->【HTTP信息头管理器】可以在这里配置token以及Content-Type 5.添加断言 在创建的线程组上右键 【添加】-->【断言】-->【响应断言】 根据响应的数据来判断请求是否正常。我在这里只判断的响应代码是否为200。还可以配置错误信息 6.添加察看结果树 在创建的线程组上右键 【添加】-->【监听器】-->【察看结果树】 然后点击运行按钮就可以看到结果 7.添加聚合报告 在创建的线程组上右键 【添加】-->【监听器】-->【聚合报告】 然后点击运行按钮就可以看到结果了 8.测试计划创建完成 保存测试计划

RK3588参数 rk3288处理器属于什么档次

RK3588是瑞芯微旗下最新的8K旗舰SoC芯片,采用ARM架构,主要用于PC、边缘计算设备、个人移动互联网设备和其他数字多媒体应用。 RK3588集成了四核Cortex-A76和四核Cortex-A55,以及单独的NEON协处理器,支持8K视频编解码。许多功能强大的嵌入式硬件引擎为高端应用提供了优化的性能。具有丰富的功能接口,可满足不同行业的产品定制需求。 rk3588芯片架构图 RK3588具有十分丰富的拓展接口,高度集成化的SoC设计,可有效降低整机成本。 RK3588集成了嵌入式ARM Mali G610 3D GPU,支持OpenGLES 1.1、2.0、3.2,OpenCL 2.2和Vulkan1.2。带有MMU的特殊2D硬件引擎将最大限度地提高显示性能,并提供非常平稳的操作。 RK3588引入了新一代完全基于硬件的最大4800万像素ISP(图像信号处理器)。它实现了许多算法加速器,如HDR、3A、LSC、3DNR、2DNR、锐化、dehaze、鱼眼校正、伽马校正等。 内置NPU支持INT4/INT8/INT16/FP16混合运算,运算能力高达6TOPS。此外,凭借其强大的兼容性,基于TensorFlow/MXNet/PyTorch/Caffe等一系列框架的网络模型可以轻松转换。 RK3588具有高性能四通道外部内存接口(LPDDR4/LPDDR4X/LPDDR5),能够维持要求的内存带宽,还提供一整套外围接口,以支持非常灵活的应用程序。SCENSMART.COM RK3588性能怎么样这些点很重要 http://www.adiannao.cn/dy 处理器 四核ARM Cortex-A76 和四核Cortex-A55 组成的八核CPU处理器,高性能,低功耗和缓存应用处理器 全面实施ARM体系结构v8-A指令集,ARM Neon Advanced SIMD (单指令,多数据) 支持加速媒体和信号处理 ARMv8密码学扩展 信任区技术支持 每个Cortex-A76集成64KB L1指令缓存、64KB L1数据缓存和512KB L2缓存 每个Cortex-A55集成32KB L1指令缓存、32KB L1数据缓存和128KB L2缓存  大集群和小集群共享3mb L3缓存  CPU核心系统的八个独立电源域,支持内部电源开关,并根据不同的应用场景从外部打开/关闭  PD_CPU_0: 1 Cortex-A55 + Neon + FPU + L1/L2小集群I/D缓存  PD_CPU_1: 第二Cortex-A55 + Neon + FPU + L1/L2小集群I/D缓存  PD_CPU_2: 第三Cortex-A55 + Neon + FPU + L1/L2小集群I/D缓存

VScode和phpstudy制作网页的配置问题

自己摸索出来的,试过了,可以用。 步骤1 下载VS code: https://code.visualstudio.com/Download 步骤2 下载phpstudy: https://www.xp.cn/ 步骤3 phpstudy中的配置 phpstudy里需要下载的软件 步骤4 配置环境变量:此电脑—>右击—>属性—>高级系统设置 步骤5 VS code需要下载的扩展 注意 我用的数据库是phpstudy里自带的(下图) 点击“管理” 有啥问题可以留言讨论 (•̀ᴗ• ) 我不会总有大佬会!◔.̮◔✧

电视盒子cpu天梯图排行榜 2023电视盒子cpu对比评测

一、2023电视盒子cpu对比评测 目前国内主流就是晶晨、瑞芯微、mtk、全志等品牌处理器芯片,晶晨、瑞芯微是用的比较多的,也是比较好的,接下来就来看看这两个芯片的主流cpu对比: 电视盒子选哪款好这些点很重要看过你就懂了 http://www.adiannao.cn/dy 1.晶晨芯片 晶晨半导体的机顶盒解决方案支持许多业界的格式和标准,既有多款视频样式的高清晰输出,又有支持带IPTV功能的DVB标准。其全面广泛的功能为客户设计下一代机顶盒提供了良好的支持和平台。 1.1 晶晨S922X 在传统电视盒子上,晶晨S922X处理器就是四核A73架构,采用了目前最先进的10nm技术制造,可以提供比Cortex-A72高出30%的持续处理能力,非常适合移动设备和消费级设备使用,也是目前国内主流中性能配置是最高的。 电视盒子cpu天梯图排行榜 2023电视盒子cpu对比评测 1.2 晶晨A311D 这款芯片和上面的晶晨S922X是一个级别的,不同的是,这款芯片不仅拥有晶晨最好的配置,同时加入了人工智能的元素,拥有一块5T算力的NPC,对于算力的认知通俗点讲就是20个晶晨A311D芯片就能实现特斯拉的无人驾驶功能,在跑分参数方面,晶晨A311D芯片为单核1359分,多核3688分。 1.3 晶晨S912 晶晨S912芯片的配置是一款8核64位高端全4K多媒体处理器,采用28nm HKMG工艺,SoC内部集成的资源相当丰富,八核64位 ARM Cortex-A53 处理器,ARM Mali-T820MP3 GPU,支持超高清4K 60fps硬件解码,支持H.265/VP9 10比特, H.264和AVS+等众多格式。 1.4 晶晨S9105X4 晶晨S905X4采用12nm制程,核心架构是四核Cortex-A55,整数计算能力(DMIPS)较高,可达21800+。DMIPS这里就不进行科普了,我们一般都把MIPS作为性能指标的单位,越高当然越好。 1.5 晶晨S9105X3 这个比上一个晶晨S905X4芯片的配置要低一些,不过在整体算力上也是挺高的。 2.瑞芯微芯片 2.1 瑞芯微RK3566 瑞芯微RK3566是一款面向物联网应用的SoC,采用A55架构处理器,搭载G52图形处理器,支持双屏异显,且有着强大的视频解码能力并能高效并发处理多小图解析,最终实现8-10路1080P30 H264/H265、HDR10、图像后处理、动态码率、帧率、分辨率调节等功能。具体可以看这个内容:瑞芯微RK3566芯片性能怎么样?瑞芯微RK3566评测怎么样?. 2.2 瑞芯微RK3399 瑞芯微RK3399是由本土芯片厂商瑞芯微(Rockchip)研发的高性能、低功耗“中国芯”,使用六核大LITTLE处理器:包括四核的Cortex-A53和双核的Cortex-A72,主频可达2.0GHz。芯片兼容3G、4G网络通讯,接口资源丰富、整体性能方面优异,比如USB3.0、MIPI双摄像头等设备接口。在操作系统的使用上也有很多可选性,用户可以选择Android/Linux/Debain等作为操作系统,也可以选择菲尼克斯、Flint OS等轻型办公开发环境,常用软件都可兼容。 2.3 瑞芯微RK3368 瑞芯微RK3368采用八核64位ARM Coretex-A53内核架构,28nm工艺设计,运行主频为1.5GHz;GPU为PowerVR G6110,支持OPENGL ES 3.1; RK3368视频能力超强,支持4K×2K视频,H.264/H.265硬解码以及HDMI 2.0@60Hz输出;系统平台为Android 5.1 Lollipop;支持Security OS及主流DRM 与HDCP2.2安全标准。

使用json server 模拟接口(mock数据的创建以及增删查改)

mock数据是用来模拟后端提供的数据,用json文件代替接口 1.安装 npm install -g json-server 2.使用步骤 在src文件下新建文件夹mock,创建data.json文件 src/mock/data.json 写模拟数据 3.注意:data文件模拟数据的书写要求非常严格: 1)所有的key必须添加双引号"",而且必须要有id这个key 2)所有的key都代表一个接口 3)所有的key对应的value,最外层必须是一个数组 例: { "newgoods":[ { "id": 1, "name": "裤子", "price": 79, "sales": 4070000, "stock": 50000 }, { "id": 2, "name": "袜子", "price": 29, "sales": 4070000, "stock": 50000 } ], "user":[ { "id": 1, "name": "maria", "sex":"女", "age": 13 }, { "id": 2, "name": "lucy", "sex":"女", "age": 20 }, { "id": 3, "name": "George", "sex":"男", "age": 18 } ] } 4.

使用Java实现远程文件下载到本地目录

使用Java实现远程文件下载到本地目录 文章目录 使用Java实现远程文件下载到本地目录前言一、正文介绍二、测试介绍总结 前言 今天开发时遇见了一个下载附件的需求,他的附件是存在一个网盘里查询时只是给我返回了一个https的路径,需要通过这个路径把附件下载到本地的目录里 一、正文介绍 import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; /** * @Author * @Date * @Version 1.0 * <p>备注:远程文件下载到本地 方法二选一<p> */ public class downloadUtil { /** * 下载远程文件并保存到本地 * * @param remoteFilePath-远程文件路径 * @param localFilePath-本地文件路径(带文件名) */ public static void downloadFile1(String remoteFilePath, String localFilePath) { URL urlfile = null; HttpURLConnection httpUrl = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; File f = new File(localFilePath); try { urlfile = new URL(remoteFilePath); httpUrl = (HttpURLConnection) urlfile.

conda环境安装

之前用的anaconda,并且程序都在一个环境下用,有时会乱,现在用minconda anaconda官网production-anaconda distribution页面最下面一行,有miniconda的链接https://docs.conda.io/en/latest/miniconda.html conda create -n envkunpy python=3.9 # 创建名为envkunpy的环境,并安装python3.9版本 conda info --envs # 查看所有已安装虚拟环境 conda activate envkunpy #激活envkunpy环境 conda list #查看当前环境下安装的包 conda config --add channels conda-forge # 有的包找不到,添加一个新的源 cat ~/.condarc #显示当前有的源 conda deactivate #退出虚拟环境 conda remove -n envkunpy --all # 删除名为envkunpy的虚拟环境

理解与使用torch的CrossEntropy Loss

交叉熵误差函数形式不难,但是使用起来却容易出错,这里记录一下自己的理解。 使用形式 torch提供了类和函数两种形式来使用交叉熵误差函数,其中类的形式在源码中调用了函数形式,所以使用哪一种都可以: importtorch.nnasnnimporttorch.nn.functionalasF# 函数形式:out=F.cross_entropy(pred,target)# 类的形式:func=nn.CrossEntropy()# 括号不要掉,定义一个对象out=func(pred,target) 底层计算逻辑 假设输入的是一个shape=[3, 5]的张量,3表示batch_size(N),5表示类别数(C),这一步可以是神经网络的最后一层全连接层的输出。先定义好输入和标签: a=torch.randn(3,5)print(a)----------------tensor([[-0.6311,0.4457,0.5320,0.5855,-0.2480],[0.5942,0.2531,0.7998,-0.4247,-0.2831],[1.5852,1.9026,0.7302,-2.0489,-0.5581]])target=torch.tensor([2,4,3],dtype=torch.long) 对于这样的输出容易理解:3个样本,每一个样本分别属于5种类别的“得分”。因为概率值一定是[0, 1]的数,所以需要使用softmax函数来将“得分”转化为“概率值”: input=a.softmax(dim=1)print(input)----------------------tensor([[0.0835,0.2451,0.2672,0.2818,0.1225],[0.2691,0.1913,0.3305,0.0971,0.1119],[0.3398,0.4668,0.1445,0.0090,0.0399]]) 这里的dim参数为什么=1呢?因为我们需要知道的是,每一个样本属于C种类别的概率是多少,所以样本与样本之间是独立的,而这里每一行是一个样本,所以需要沿着横轴同时将5个数据映射到softmax函数。 随后,就可以计算交叉熵误差,公式: �=−∑�=1��������ln⁡������ 代码: -(torch.log(input[0][target[0]])+torch.log(input[1][target[1]])+torch.log(input[2][target[2]]))/3----------------------tensor(2.7411) 这里有几个问题: 代码这样写看上去target中的值只是索引? target值确实是索引,只是这里的处理逻辑和torch的处理逻辑不同,torch先将target转换成shape同input的one-hot编码形式: importtorchimporttorch.nn.functionalasFdefto_one_hot(tensor,num_clsses):asserttensor.dim()<=1,"[Error] tensor.dim >= 1"one_hot=torch.zeros(len(tensor),num_clsses)idx=range(len(tensor))one_hot[idx,tensor.reshape(-1,)]=1returnone_hotbatch_size=10num_classes=5target=torch.randint(num_classes,size=(batch_size,))# 非delta标签分布target_delta=to_one_hot(target,num_classes) 然后将target和input进行元素对应相乘,然后使用log函数。这里的处理方式就直接分别取出三个样本的标签值的索引,三个样本的标签索引分别是2, 4, 3,所以应该取出这三个值: 然后映射到log函数中: torch.log 得到三个负值,三个负值相加取均值,得到一个batch的平均损失值(如果从input中选出的三个值越大,那么映射到log中值的绝对值越小,也就是损失越小)。 2. 取均值还是累加和? torch源码默认取的是均值,可以传入reduction参数来修改: defcross_entropy(input:Tensor,target:Tensor,weight:Optional[Tensor]=None,size_average:Optional[bool]=None,ignore_index:int=-100,reduce:Optional[bool]=None,reduction:str="mean",# 默认取均值)->Tensor: 基于上述案例使用封装函数 注意这里的a是softmax操作前的结果,这是由于函数内部有softmax操作,具体见官方文档: F.cross_entropy(a,target)----------------------tensor(2.7411) binary cross entropy loss 交叉熵误差函数还有一种特殊情况,即二值交叉熵误差。比如一个正负例预测问题中,希望网络输出结果为1或0,网络输出的是一个值,需要首先将该值隐射到sigmoid函数中,以限制值的范围到(0, 1),然后再和标签值进行计算。其中pred的shape=(N, ),target的shape=(N, )。使用方式如下所示: defloss_fn(pred,target):pred=pred.reshape(-1)target=target.reshape(-1)critical=nn.functional.binary_cross_entropy_with_logits(pred,target)returncritical 这里使用了binary_cross_entropy_with_logits,该函数自带sigmoid操作,所以网络输出值直接传进来即可,不需要我们自己手动sigmoid。 另外,如果我们的输入值趋近于0或1,那么经过log函数得到的结果趋近于无穷大,这种情况下反向求导会无法继续计算下去,pytorch的解决方案是将经过Log后的结果限制在[-100, 100]内的范围,这样就可以保证梯度存在且可以继续计算。 Reference: (62条消息) pytorch语义分割中CrossEntropyLoss()损失函数的理解与分析_北斗星辰001的博客-CSDN博客

pyecharts 图表更改颜色

基本结构: from pyecharts import * import pandas as pd page = Page() df = pd.read_csv('12个城市的空气和环境数据/PRSA_Data_20130301-20170228/PRSA_Data_Tiantan_20130301-20170228.csv', encoding='utf-8') df.dropna(inplace=True) df.reset_index(drop=True, inplace=True) # 添加 x轴数据 month = [] for i in range(1, 13): month.append(i) pm25 = df.groupby(['month'])['PM2.5'].mean() temp = df.groupby(['month'])['TEMP'].mean() bar = Bar("月份", "PM2.5-TEMP", title_color="green") bar.add('PM2.5', month, pm25, item_color='#00c853') bar.add('TEMP', month, temp, xaxis_name="月份", yaxis_name="PM2.5/温度") page.add_chart(bar, 'bar') page.render("颜色.html") 1. 对于整个条形图 title_color 设置标题的颜色 subtitle_color 设置副标题的颜色 background_color 设置背景颜色 简单实验一下: bar = Bar("月份", "PM2.5-TEMP", title_color='green', subtitle_color='yellow',background_color='#64b5f6') 2.

Airflow环境搭建

1 Airflow简介 1.1 简介 Apache Airflow是⼀个提供基于DAG(有向⽆环图)来编排⼯作流的、可视化的分布式任务调度平台(也可单机),与Oozie、Azkaban等调度平台类似。Airflow在2014年由Airbnb发起,2016年3⽉进⼊Apache基⾦会,在2019年1⽉成为顶级项⽬。Airflow采⽤Python语⾔编写,并提供可编程⽅式定义DAG⼯作流(编写Python代码)。当⼯作流通过代码来定义时,它们变得更加可维护、可版本化、可测试和协作。 Airflow的可视化界⾯提供了⼯作流节点的运⾏监控,可以查看每个节点的运⾏状态、运⾏耗时、执⾏⽇志等。也可以在界⾯上对节点的状态进⾏操作,如:标记为成功、标记为失败以及重新运⾏等。在Airflow中⼯作流上每个task都是原⼦可重试的,⼀个⼯作流某个环节的task失败可⾃动 或⼿动进⾏重试,不必从头开始跑。 Airflow通常⽤在数据处理领域,也属于⼤数据⽣态圈的⼀份⼦。当然Airflow也可以⽤于调度⾮数据处理的任务,只不过数据处理任务之间通常都会存在依赖关系。⽽且这个关系可能还⽐较复杂,⽤crontab等基础⼯具⽆法满⾜,因此更需要被调度平台编排和管理。 例如: 时间依赖:任务需要等待某⼀个时间点触发 外部系统依赖:任务依赖外部系统需要调⽤接⼝去访问 任务间依赖:任务 A 需要在任务 B 完成后启动,两个任务互相间会产⽣影响 资源环境依赖:任务消耗资源⾮常多, 或者只能在特定的机器上执⾏ Airflow拥有和 Hive、Presto、MySQL、HDFS、Postgres 和 S3 交互的能力,并且拥有很好地扩展性。除了一个命令行界面,该工具还提供了一个基于 Web 的用户界面让您可以可视化管道的依赖关系、监控进度、触发任务等。 传统 Workflow 通常使用 TextFiles (json,xml/etc ) 来定义 DAG ,然后 Scheduler 解析这些 DAG 文件形成具体的 TaskObjec t执行; Airflow 没这么干,它直接用 Python 写 DAG definition ,一下子突破了文本文件表达能力的局限,定义 DAG 变得简单。 1.2 设计原则 动态:Airflow配置为代码(Python),允许动态生成pipeline。 这允许编写动态实例化的pipelines代码。 自定义:轻松定义自己的opertators,执行程序并扩展库,使其符合适合您环境的抽象级别。 优雅:Airflow精益而明确。 使用强大的Jinja模板引擎将参数化脚本内置于Airflow的核心。 可扩展:Airflow具有模块化体系结构,并使用消息队列来协调任意数量的工作者。 Airflow已准备好扩展到无限远。 特点 Python脚本实现DAG,非常容易扩展 可实现复杂的依赖规则 外部依赖较少,搭建容易,仅依赖DB和rabbitmq 工作流依赖可视化。有一套完整的UI,可视化展现所有任务的状态及历史信息 完全支持crontab定时任务格式,可以通过crontab格式指定任务何时进行 业务代码和调度系统解耦,每个业务的流程代码以独立的Python脚本描述,里面定义了流程化的节点来执行业务逻辑,支持任务的热加载 1.3 功能简介 2 Airflow架构详解 2.

caj文件怎么转换成pdf格式?三步搞定

当我们需要查阅一些文献资料时,往往会遇到CAJ文件格式的问题。这种格式需要使用专业的阅读工具才能打开,让我们的阅读体验变得十分不便。为了解决这个问题,我们可以将CAJ文件转换成PDF文件格式。这样,无论我们使用什么设备,都可以轻松地打开文件。那么怎么转换呢?今天教大家三步搞定。 步骤一:访问记灵在线工具 打开您的浏览器,访问记灵在线工具的官方网站(https://remeins.com/)。在网站首页的输入框中输入CAJ,找到并打开CAJ转PDF功能菜单。 步骤二:上传Caj文件 在“CAJ转PDF”的页面中,点击“选择文件”按钮,然后在弹出的对话框中选择要转换的Caj文件。您可以一次选择多个文件,或者拖拽文件到页面中直接上传。 步骤三:开始转换并下载 上传完成后,点击页面底部的“确认转换”按钮,等待转换过程完成。转换时间根据文件大小和网络速度而异,通常只需要几秒钟到几分钟不等。转换完成后下载即可得到转换后的文件。 总之,将Caj文件转换成PDF格式是一件很简单的事情,只需要三个步骤即可完成。首先需要打开在线转换工具,然后将Caj文件上传,最后进行转换并保存为PDF格式即可。

出现java.lang.NullPointerException的可能原因及解决方案

出现 java.lang.NullPointerException 错误通常是因为代码中出现了一个空引用,即 null。当尝试对这个空引用进行操作时,就会出现 NullPointerException 错误。以下是可能导致该错误的几个原因: 对象未被正确初始化:当对象未被正确初始化时,它的值将为 null。在尝试访问该对象的方法或属性时,就会出现 NullPointerException 错误。参数为空:如果将 null 作为方法的参数传递,当方法尝试访问该参数时,就会出现 NullPointerException 错误。数组为空:如果数组不被正确地初始化,或者数组的某个元素为 null,当尝试访问该元素时,就会出现 NullPointerException 错误。集合为空:如果集合不被正确地初始化,或者集合中包含 null 元素,当尝试访问该元素时,就会出现 NullPointerException 错误。在多线程应用中,有些线程可能会修改或清空对象或集合,而其他线程仍在使用这些对象或集合,从而导致 NullPointerException 错误。类路径不正确:当类路径不正确时,Java 可能无法正确加载类。这可能会导致 NullPointerException 错误。 综上所述,最常见的原因是对象未被正确初始化或者有 null 值的参数、数组或集合。因此,开发人员需要避免这些情况并进行适当的错误处理。 解决方案: 检查空引用 在代码中检查可能出现空引用的地方,并在使用前判断是否为null。可以使用if语句或者三目运算符进行判断。检查调用方法的参数 如果是调用方法出现了NullPointerException错误,可以检查传递给方法的参数是否为null。在方法中使用断言或者if语句进行判断。检查类的初始化 如果是在类的构造函数或者静态初始化块中出现了NullPointerException错误,可以检查类的初始化是否正确。检查类中的变量是否被正确初始化,是否有空指针异常。使用Optional类 Java 8引入了Optional类,可以避免空引用的问题。使用Optional类,可以将可能为空的变量包装在Optional对象中,然后使用Optional类的方法进行操作。使用断言 可以使用断言对空引用进行检查,如果为空则抛出异常。在Java中使用assert语句进行断言。使用日志 使用日志记录空引用的位置和原因,有助于快速定位和解决问题。 综上所述,避免空引用是解决java.lang.NullPointerException错误的最有效方法。

vscode编辑rmarkdown文件无法运行

问题 使用vscode编辑rmarkdown文件无法运行代码块 没有出现运行按钮 原因 这是因为文件后缀没有与rmarkdown关联。 解决办法 在设置中,搜索找到这个项目:Files.Associations,把其设置更改为下面内容: 代码就可以运行了~ 参考

模板引擎Freemarker基础知识

Freemarker是什么 FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 常用的java模板引擎还有 Jsp、Freemarker、Thymeleaf 、Velocity 等。 freemarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件) freemarker作为springmvc一种视图格式,默认情况下SpringMVC支持freemarker视图格式。 FreeMarker 基础指令 map即为freemarker静态化所需要的数据模型 List指令 1、注释,即:<#‐‐被注释的内容‐‐> 2、插值(Interpolation):即 ${…} 部分,freemarker会用真实的值替换 ${…} 中的内容 3、FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。例如:<#list stuMap?keys as k> ,就是获取stuMap中的所有的key作为一个list集合,然后取list集合中的一个key赋值给k. 4、文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容。 解释Demo: <#list stus as stu> <tr> <td>${stu_index + 1}</td> <td>${stu.name}</td> <td>${stu.age}</td> <td>${stu.mondy}</td> </tr> </#list> 其中: _index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始 遍历Map数据 姓名:${stuMap['stu1'].name}<br/> 或者 姓名:${stuMap.stu1.name}<br/> 其中stuMap是一个map集合,stu1是map集合中的一个元素对象,name是stu1的一个属性,如果采用list集合去遍历的话,第二种方法就不适用了。 if指令 if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。 例如: <td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td> 意思就是如果stu的姓名是小明的话,就加背景色 其它指令 运算符 1、算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 2、逻辑运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:!

短链接是怎么设计的?带你入门

文章目录 前言一、短链1、原理1.1 短链生成原理1.2 短链跳转原理: 2、设计:2.1 短链需求2.2 考虑的问题? 二、实践案例1、设计表:2、生成短链: 前言 说到 URL 你肯定不陌生,浏览器输入一段 URL,立马就跳转到你想要的网站,不过你应该也遇到过一些带了很多参数、特别长的 URL,看起来就乱糟糟的,能不能把它变短一点? 首先你要知道的是,长链是没法压缩成短链的,那我们这里怎么设计短链? 答案是:映射。 将需要的长链生成对应的短链,你可以把这个映射关系放在缓存、也可以放在数据库。然后,每次访问短链的时候,都需查到这个对应关系,并重定向到真正长链接对应的网址。 短链设计本身很简单,不过现在的需求量非常大,这个量级上去了,简单的东西都会变得复杂,因此,本文从简入深探讨锻炼设计原理与方法。 一、短链 URL 短链,就是把原来较长的网址,转换成比较短的网址,比如这样:https://s.xxx.com/1WB5A3。那这样设计的好处? 首先,网址短、美观、便于发布、传播,可以写更多有意义的文字。 其次,省钱省成本:在短信中,如果含长网址的短信内容超过 70 字,就会被拆成两条发送,而用短链则可能一条短信就搞定,如果短信量大也可以省下不少钱。 再则,易识别:我们平常看到的二维码,本质上也是一串 URL ,如果是长链,对应的二维码会密密麻麻,扫码的时候机器很难识别,而短链则不存在这个问题。 另外,出于安全考虑,不想让有意图的人看到原始网址。 1、原理 1.1 短链生成原理 获取短链: 短链标志(flag)长度一般 5 - 7位,一般由数字、字母(可选择区分大小写)等字符组成。有几种常见的获取方式: 1)截取前缀:我们可以从众多 hash 算法中选择一种(比如 MD5),将 url 经过 hash 计算之后得到一串字符,然后截取前缀 5 - 7位即可。 案例如下: public static String toHex(String url) { String hash = Md5.hash(url); return hash.substring(0, 6); } 2)除法取模:选择一种 hash 算法可以输出 32 位、64位 … 的整数 x,对字符集合大小取模,得到下标 id,记录下来,从指定的字符编码集合中找到对应字符,循环该操作直到 x 小于编码集大小。

sheng的学习笔记-IO多路复用,NIO,BIO,AIO

基础概念 IO分为几种:同步阻塞的BIO,同步非阻塞的NIO,异步非阻塞AIO,IO多路复用,信号驱动IO(不常用) 对于一个network IO,它会涉及到两个系统对象,一个是调用这个IO的process(Thread),另一个是系统内核。当一个read/recv读数据的操作发生时,该操作会经历两个阶段: (1)等待数据准备 (2)将数据从内核拷贝到进程中 BIO:同步并阻塞 服务端处理请求是串联的。也就是说如果这个请求被阻塞了,那么剩下的请求都要被阻塞``等待``上一个请求处理完成才行。所以,我们上面说,在 服务器读数据的时候,数据还没到(数据还没读到用户态),那么服务器被阻塞,然后其他客户端的请求也不能被处理。 比如: 小明和小红两个人访问同一个服务,然后小明先点,但是数据没被处理完成,然后小红在进行发送请求,此时服务器就将小红的请求挂起,等待小明的处理完成在进行处理。 而且小明发了申请,服务器没有返回响应之前,小明也不能动,阻塞在那里等待到应答,才能继续做别的事情 . NIO:同步非阻塞 用户线程发起IO请求后,立即返回;这时候可以干点别的,过一会再查,但需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。 虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。 当用户进程发出read操作时,如果kernel中的数据还没准备好,那么它并不会block用户进程,而是立刻返回一个error。当用户进程接收到一个error,就会知道数据还没准备,于是用户就可以做点其他的,过一段时间,再次发送read操作,一旦kernel的数据准备好了,他就会立马把数据拷贝到了用户内存,然后返回。 在这种非阻塞IO模式下,用户进程就不断的询问kernel的数据准备好了没,若没有,返回给 用户一个error,在两次询问期间,用户进程可以干点其他的,若数据准备好了,就直接拷贝,这个询问过程叫轮询。在拷贝数据整个过程,进程任仍然处于阻塞状态 IO多路复用 一个线程内同时处理多个IO请求,这就是IO多路复用 相当于select\epoll,这种IO方式也称为事件驱动IO,select\epoll的好处在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select\epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据响应了,就通知用户进程。 当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。 这个图和blocking IO的图其实并没有太大的不同,事实上还更差一些。因为它不仅阻塞了还多需要使用两个系统调用(select和recvfrom),而blocking IO只调用了一个系统调用(recvfrom),当只有一个连接请求的时候,这个模型还不如阻塞IO效率高。但是,用select的优势在于它可以同时处理多个connection,而阻塞IO那里不能,我不管阻塞不阻塞,你所有的连接包括recv等操作,我都帮你监听着(以什么形式监听的呢?先不要考虑,下面会讲的~~),其中任何一个有变动(有链接,有数据),我就告诉你用户,那么你就可以去调用这个数据了,这就是他的NB之处。 select模块及使用方法:select的优势在于处理多个连接,不适用于单个连接 虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。以下是改良版: reactor设计模式,就是基于IO多路复用,可以参考 https://blog.csdn.net/coldstarry/article/details/129433822 AIO:异步IO 用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel操作系统会等待数据(阻塞)准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。 貌似异步IO这个模型很牛~~但是你发现没有,这不是我们自己代码控制的,都是操作系统完成的,而python在copy数据这个阶段没有提供操纵操作系统的接口,所以用python没法实现这套异步IO机制,其他几个IO模型都没有解决第二阶段的阻塞(用户态和内核态之间copy数据),但是C语言是可以实现的,因为大家都知道C语言是最接近底层的,虽然我们用python实现不了,但是python仍然有异步的模块和框架(tornado、twstied,高并发需求的时候用),这些模块和框架很多都是用底层的C语言实现的,它帮我们实现了异步,你只要使用就可以了,但是你要知道这个异步是不是很好呀,不需要你自己等待了,操作系统帮你做了所有的事情,你就直接收数据就行了,就像你有一张银行卡,银行定期给你打钱一样。 信号驱动IO 信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作 通知应用程序处理IO, 是开始处理IO, 这个时候还是存在阻塞的,将数据从内核态拷贝进入到用户态的过程至少是阻塞住的 (应用程序将数据从内核态拷贝到用户态的过程是阻塞等待的, 和异步IO的区别) (此处是区分信号驱动IO和异步IO的关键所在) 信号驱动IO, 我们提前在信号集合中设置好IO信号等待, 注册好对应的IO处理函数 handler,IO数据准备就绪后,会递交SIGIO信号,通知应用程序中断然后开始进行对应的IO处理逻辑. 但是通知处理IO的时候存在将数据从 内核空间拷贝到用户空间的过程,(而异步IO是数据拷贝完成之后内核再通知应用程序直接开始处理, 应用程序直接处理,不需要拷贝数据阻塞等待) 各IO对比 参考文章 https://blog.csdn.net/guorui_java/article/details/107081776 https://www.cnblogs.com/zhangxiaoji/p/16152141.html https://zhuanlan.zhihu.com/p/555459665 https://www.cnblogs.com/12345huangchun/p/10066840.html https://blog.csdn.net/leftfist/article/details/105020228

git将文件或目录添加进了.gitignore文件,为什么不生效?

如题,之所以将文件添加进了.gitignore文件但不生效,是因为该文件已经被add进git仓库了,已经被git托管了,这时git就没法ignore了。解决办法是先用git rm --cached将这些文件从git仓库中取消托管并提交,然后.gitignore文件才会生效。详细见如下描述。 已经添加到git仓库中的文件,如果在.gitignore中加入忽略,是不会生效的,因为他们已经添加到git仓库中了。 要先git rm --cached在git仓库中删除这些文件,然后再用git commit 提交这个删除操作。然后,.gitignore中对这些文件的忽略才会生效。 注意:git rm --cached只是让git不再托管这些文件,一定要加上--cached选项,如果不加,git不仅删除此文件的托管关系,还会从硬盘上删除此文件,可怕~~ 例: mokar@ubuntu:~/temp/555$ tree . ├── aa │ └── aa.c └── bb └── bb.c 此例中,aa bb文件夹下两个文件都已经git add了: mokar@ubuntu:~/temp/555$ git status On branch master nothing to commit, working directory clean 此时编写.gitignore文件,将bb文件夹下的文件忽略掉,不会生效: mokar@ubuntu:~/temp/555$ cat .gitignore bb/ 将ignore文件提交。 此时改动bb.c看看: mokar@ubuntu:~/temp/555$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "

Java优化(三) 日志打印

目录 1、选择恰当的日志级别2、日志要打印出方法的入参、出参3、选择合适的日志格式4、遇到if...else...等条件时,每个分支首行都尽量打印日志5、日志级别比较低时,进行日志开关判断6、不能直接使用日志系统(Log4j、Logback)中的 API,而是使用日志框架SLF4J中的API7、建议使用参数占位{},而不是用+拼接8、建议使用异步的方式来输出日志9、不要使用e.printStackTrace()10、异常日志不要只打一半,要输出全部错误信息11、禁止在线上环境开启 debug12、不要记录异常,又抛出异常13、避免重复打印日志14、日志文件分离15、核心功能模块,建议打印较完整的日志16、 springboot整合logback进行日志管理 1、选择恰当的日志级别 常见的日志级别有5种,分别是error、warn、info、debug、trace。日常开发中,我们需要选择恰当的日志级别 序号日志级别描述1error错误日志,指比较严重的错误,对正常业务有影响,需要运维配置监控的2warn警告日志,一般的错误,对业务影响不大,但是需要开发关注3info信息日志,记录排查问题的关键信息,如调用时间、出参入参等等4debug用于开发DEBUG的,关键逻辑里面的运行时数据5trace最详细的信息,一般这些信息只记录到日志文件中 trace<debug<info<warn<error 级别排序,从左到右,级别越来越高 只有当日志级别大于你设置的日志级别才会输出。设置日志的级别是INFO那么比INFO级别高的日志级别会输出到日志文件或者控制台,比INFO级别低的不会输出 2、日志要打印出方法的入参、出参 我们并不需要打印很多很多日志,只需要打印可以快速定位问题的有效日志。 public String testLogMethod(Document doc, Mode mode){ log.debug(“method enter param:{}”,userId); String id = "dmjxsy"; log.debug(“method exit param:{}”,id); return id; } 3、选择合适的日志格式 理想的日志格式,应当包括这些最基本的信息:如当前时间戳(一般毫秒精确度)、日志级别,线程名字等等。在logback日志里可以这么配置: <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern> </encoder> </appender> 4、遇到if…else…等条件时,每个分支首行都尽量打印日志 当碰到if…else…或者switch这样的条件时,可以在分支的首行就打印日志,这样排查问题时,就可以通过日志,确定进入了哪个分支,代码逻辑更清晰,也更方便排查问题了。 if(user.isVip()){ log.info("该用户是会员,Id:{},开始处理会员逻辑",user,getUserId()); //会员逻辑 }else{ log.info("该用户是非会员,Id:{},开始处理非会员逻辑",user,getUserId()) //非会员逻辑 } 5、日志级别比较低时,进行日志开关判断 对于trace/debug这些比较低的日志级别,必须进行日志级别的开关判断。 正例 Persion persion= new Persion (12345L, "18", "男"); if (log.isDebugEnabled()) { log.debug("userId is: {}", persion.

编译ORTP库遇到的问题

转自:【HD-G2UL-EVM开发板体验】基于RTP协议的实时流传输实现 - 单片机/MCU论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 前言 RTP(Real-timeTransportProtocol)是用于Internet上针对多媒体数据流的一种传输协议,做流媒体传输方面的应用离不开RTP协议的实现及使用。可在项目中应用RTP协议实现流媒体(音视频)的传输,比如我们的游戏机项目实现就可以通过RTP推流音视频到PC,通过PC显示和播放音频,这样就不需要使用开发板的LCD和音频模块,刚好开发板也没有附带LCD,所以我们就这么干了。RTP实现有一些开源库可以选择,这里选择ORTP库,这个库是纯使用c语言编写,移植比较简单。 开发环境搭建 交叉编译 WSL中 sudo apt install make git clone https://github.com/dmonakhov/ortp.git cd ortp/ ./autogen.sh 报如下错误 lhj@lhj:~/ortp$ ./autogen.sh + rm -rf config.cache autom4te.cache + libtoolize --copy --force ./autogen.sh: 36: ./autogen.sh: libtoolize: not found + aclocal ./autogen.sh: 37: ./autogen.sh: aclocal: not found + autoheader ./autogen.sh: 38: ./autogen.sh: autoheader: not found + automake --force-missing --add-missing --copy ./autogen.sh: 39: ./autogen.sh: automake: not found + autoconf

Jmeter 压力测试步骤详解

目录 1、准备工作:安装 Jmeter 2、开始压力测试 (1)首先需要创建线程组 (2)创建 HTTP 请求 (3)添加察看结果树 (4)添加聚合报告 3、完整的测试步骤图示 Jmeter 压力测试官方文档:Apache JMeter - Apache JMeter Distributed Testing Step-by-step 什么是压力测试? 压力测试就是被测试的系统,在一定的访问压力下,看程序运行是否稳定/服务器运行是否稳定(资源占用情况)。 例如: 模拟2000个用户同时到一个购物网站购物,测试这些用户打开页面的速度是否会变慢,或者网站是否会奔溃。 1、准备工作:安装 Jmeter 安装 Jmeter 之前需要先安装好 JDK 环境。// Jmeter 是 Java 工具下载 Jmeter 安装包(压缩包,windows 环境为 zip 格式):Apache JMeter - Apache JMeter™解压安装包,进入 bin 目录,点击 jmeter.bat 启动 Jmeter。 2、开始压力测试 (1)首先需要创建线程组 点击 jmeter.bat 启动 Jmeter 后会弹出可视化窗口,按如图步骤,使用 Jmeter 创建线程组: 创建完创建线程组后,界面如下: 线程组参数详解: 线程数:虚拟用户数。一个虚拟用户占用一个进程或线程。设置多少虚拟用户数在这里也就是设置多少个线程数。 Ramp-Up Period(in seconds)准备时长:设置的虚拟用户数需要多长时间全部启动。如果线程数为10,准备时长为 2,那么需要 2 秒钟启动 10 个线程,也就是每秒钟启动 5 个线程。 循环次数:每个线程发送请求的次数。如果线程数为 10,循环次数为 100,那么每个线程发送 100 次请求。总请求数为 10*100=1000 。如果勾选了“永远”,那么所有线程会一直发送请求,一到选择停止运行脚本。 Delay Thread creation until needed:直到需要时延迟线程的创建。 调度器配置:设置线程组启动的开始时间和结束时间(配置调度器时,需要勾选循环次数为永远) 调度器配置参数:

内存溢出、内存泄露的概述及常见情形

内存溢出(OutofMemoryError) 简述 java doc 中对 Out Of Memory Error 的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。 JVM 提供的内存管理机制和自动垃圾回收极大的解放了用户对于内存的管理,由于 GC(垃圾回收)一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现内存泄漏和内存溢出问题。但是基本不会出现并不等于不会出现,所以掌握 Java 内存模型原理和学会分析出现的内存溢出或内存泄漏仍然十分重要。 大多数情况下,GC 会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的 Full GC 操作,这时候会回收大量的内存,供应用程序继续使用。 在抛出 OutofMemoryError 之前,通常垃圾收集器会被触发,尽其所能去清理出空间。例如:在引用机制分析中,涉及到 JVM 会去尝试回收软引用指向的对象等。在 java.nio.BIts.reserveMemory() 方法中,System.gc() 会被调用,以清理空间。 当然,也不是在任何情况下垃圾收集器都会被触发的。比如,分配了一个超大对象,类似一个超大数组超过堆的最大值,JVM 可以判断出垃圾收集并不能解决这个问题,所以直接抛出 OutofMemoryError。 内存溢出的常见情形 不同的内存溢出错误可能会发生在内存模型的不同区域,因此,需要根据出现错误的代码具体分析来找出可能导致错误发生的地方,并想办法进行解决。 栈内存溢出(StackOverflowError) 栈内存可以分为虚拟机栈(VM Stack)和本地方法栈(Native Method Stack),除了它们分别用于执行 Java 方法(字节码)和本地方法,其余部分原理是类似的。 以虚拟机栈为例说明,Java 虚拟机栈是线程私有的,当线程中方法被调度时,虚拟机会创建用于保存局部变量表、操作数栈、动态连接和方法出口等信息的栈帧(Stack Frame)。 具体来说,当线程执行某个方法时,JVM 会创建栈帧并压栈,此时刚压栈的栈帧就成为了当前栈帧。如果该方法进行递归调用时,JVM 每次都会将保存了当前方法数据的栈帧压栈,每次栈帧中的数据都是对当前方法数据的一份拷贝。如果递归的次数足够多,多到栈中栈帧所使用的内存超出了栈内存的最大容量,此时 JVM 就会抛出 StackOverflowError。 总之,不论是因为栈帧太大还是栈内存太小,当新的栈帧内存无法被分配时,JVM 就会抛出 StackOverFlowError。 优化方案: 可以通过设置 JVM 启动参数 -Xss 参数来改变栈内存大小。 注:分配给栈的内存并不是越大越好,因为栈内存越大,线程多,留给堆的空间就不多了,容易抛出OOM。JVM的默认参数一般情况没有问题(包括递归)。 递归调用要控制好递归的层级,不要太高,超过栈的深度。 递归调用要防止形成死循环,否则就会出现栈内存溢出。 堆内存溢出(OutOfMemoryError:java heap space) 堆内存的唯一作用就是存放数组和对象实例,即通过 new 指令创建的对象,包括数组和引用类型。 堆内存溢出又分为两种情况: Java 虚拟机的堆内存设置不够

ggplot2绘制柱状图_分组柱状图步骤

#柱状图调节柱形宽度、柱形间距 #先准备三列,group_number为分组,name是x因变量,value是y轴自变量 #此代码中,图例为透明背景,且图例图案距离编名0.5cm(均可修改), theme(legend.title=element_text(size = 20,face = "bold",margin = margin(r=20)), legend.text=element_text(size = 20,face = "bold",margin = margin(r=20)), #legend.position=c(0.28, 0.78), #图例在绘图区域的位置 #legend.position='top',#图例放在顶部 legend.spacing.x = unit(0.5, 'cm'), #柱状图无背景图#柱状图边框为黑色加粗 theme(panel.grid.major=element_line(colour=NA), panel.background = element_rect(fill = "transparent",colour = NA), plot.background = element_rect(fill = "transparent",colour = NA), panel.grid.minor = element_blank())+ #柱状图分组绘制 #柱状图调节柱形宽度、柱形间距 geom_bar(stat = "identity", position=position_dodge(0.9), width = 0.8, colour = "black", size=1.2)+#边框颜色为黑色 #柱状图上添加具体值,并调节值显示位置 geom_text(aes(y=value+0.5,label=value),#将weight赋值给每一列 #vjust=1.2,#位置参数 position = position_dodge(0.8), colour="black", size=10)+##颜色字体大小 #柱状图消除图形与x轴间空隙,且保留y轴空隙 scale_y_continuous(limits =c(0, 18) ,expand = c(0,0))+#消除与x轴的间隙 #选择自己喜欢的柱状颜色

公式排版-制表位

1.在 布局-栏-更多栏 里根据自己文档的格式查看每栏的宽度 2.如要设置公式居中,编号右对齐,计算制表位公式为: 居中:栏宽度÷2 右对齐:栏宽度 如我这篇文档用的是两栏,栏宽度为24.86,则居中的制表位值为12.43,右对齐的制表位值为24.86 3.制位符的设置可以 ①右键要排版的段落-段落-制表位,设置制表位的值大小,起到的功能(居中/左对齐/右对齐) ②在 样式-创建新样式-格式-制表位,为公式单独制作一个格式(制表位设置方法同上)

【保姆级】python最新版3.11.1开发环境搭建,看这一篇就够了

【保姆级】Python最新版开发环境搭建,看这一篇就够了(适用于Python3.11.2安装) 文章目录 【保姆级】Python最新版开发环境搭建,看这一篇就够了(适用于Python3.11.2安装)一、Python解释器安装Windows安装步骤环境变量配置(非必要)MacOS安装步骤Linux安装步骤 二、PyCharm安装三、创建Python工程 工欲善其事必先利其器,在使用Python开发程序之前,在计算机上搭建Python开发环境是必不可少的环节,目前Python最新稳定版本是3.11.1,且支持到2027年,如下图所示 本文手把手带你从0 到1搭建Python最新版3.11.1开发环境,堪称保姆级教程,快快收藏啦~ 一、Python解释器安装 我们可以直接去Python官网下载相应操作系统的安装包:https://www.python.org/ 由于我本地是win11环境,直接识别下载了windows的安装包,需要注意3.11.1要求windows必须是win7以上才行,推荐大家使用win10或win11! Windows安装步骤 1、windows版的Python安装包是exe文件,只需要无脑点击即可,这里记得选中“Add python.exe to Path”,可以避免人工再去配置环境变量 2、这里为了方便,我们直接选择“Install Now”,默认会把必备的都装上 3、安静等待安装~ 4、然后如果弹出下面这个框,点击“Disable path length limit”的按钮,然后点击close关闭。“Disable path length limit”是指,禁用系统的Path长度自动限制,能给我们避免很多的麻烦。禁用路径长度限制更改计算机配置,以允许包括Python在内的程序绕过260个字符的“最大路径”限制。这是说明你电脑对Python的一些限制,点击它然后确定权限就可以了 5、Win + R 快速打开cmd,输入python --version可以验证是否正确安装 环境变量配置(非必要) 1、如果忘了选中“Add python.exe to Path”,可能这里无法正确执行python命令,需要手动添加环境变量 2、右键我的电脑,点击属性,弹出如下界面 3、点击高级系统设置,出现下图,选择环境变量 4、找到系统变量里面的Path,编辑它,将python解释器所在路径粘贴到最后面,再加个分号,至此环境变量配置完成,再打开命令行输入python即可看到正确的显示。 MacOS安装步骤 macOS的安装步骤与Windows类似,其Python安装包是pkg文件,下载下来一直点双击即可完成安装。 macOS默认已经带了Python开发环境,一般是Python2.7版本,因为这个版本是Python2应用最广泛的版本,有点像JDK8。 Python支持多版本共存,所以我们可以不用管原始版本,记得添加PATH环境变量哟~ Linux安装步骤 Linux版的Python安装程序与上述2种操作系统安装步骤有些差异,由于Linux发行版特别多,所以官网上Linux的Python是以源码形式发布的,需要我们使用GCC编译和安装 1、安装依赖包、下载Python3.11.1 # 安装python依赖 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel gcc make # 下载安装包 wget https://www.python.org/ftp/python/3.11.1/Python-3.11.1.tgz 2、编译源码 # 解压 tar -zxf Python-3.

Zotero入门——安装插件

目录 引言插件安装步骤缺省插件Zotero Connector 其他插件zoteroquicklookJasminumGreen Frog(绿青蛙)ZotfileDoI manager 引言 【注意】以下插件所适用的Zotero版本为最新版本:Zotero 6.0 插件安装步骤 下载所需的插件; 打开管理插件页面:(管理插件的位置:点击菜单栏的工具–插件)(zotero更新后的版本叫做附加组件,而不是插件了) 安装插件 :Zotero插件的后缀为.xpi格式的文件,直接拖动.xpi的文件到如下图所示的插件管理页面就可以提示安装了(也可以点击左上角Extensions找到对应的插件进行安装),安装插件后要重新启动Zotero才生效; 缺省插件 以下插件都是Zotero自带的插件,也就是安装Zotero后就已经集成到软件中 Zotero LiberOffice IntergrationZotero PDF TranslateZotero Word for Windows Intergration Zotero Connector 插件功能 Zotero Connector会在您浏览网页时自动感知内容,并允许您只需单击一下即可将其保存到Zotero。 这个插件是在Zotero官网下载安装包界面中就提示要下载的浏览器插件。 在谷歌学术、IEEE、WOS数据库或者某个具体期刊等都可以直接抓取条目信息! 安装步骤:如果你用的是Edge浏览器,直接点击install Edge Connector就可以安装;如果是其他浏览器,点击下面的Zotero Connectors for other browsers,然后选择你所使用的浏览器安装插件就可以。安装完成后浏览器插件页面上会有一个文件夹或者文件的图标,这个就是Zotero Connector插件! 其他插件 zoteroquicklook 插件功能:可以通过预览窗口快速查找并阅读对应文献条目下的PDF文件。而Zotero 6.0自带的PDF阅读功能只能新建窗口来打开对应条目下的PDF。安装步骤: 下载QuickLook软件并安装 下载链接: https://apps.microsoft.com/store/detail/quicklook/9NV4BS3L1H4S?hl=zh-cn&gl=CN 下载zoteroquicklook_zotero beta 6.0.xpi插件并安装到Zotero中,安装完插件记得重启Zotero 百度网盘链接:https://pan.baidu.com/s/1rEnpsn63L-ulGm56AZQ7-g 提取码:EMTC ——(插件来源于B站Up主,注明他的地址:https://www.bilibili.com/read/cv15720656 )使用步骤: (1)单击对应条目,按空格(space)键,可弹出Quicklook的预览窗口,如下图所示。 (2)如果想要用Zotero自带的PDF阅读器浏览和编辑,和默认的打开方式一样就可以,也就是双击条目即可打开 插件的GitHub地址:目前开发者已经不更新了,但是issues里有讨论怎么解决问题的。等到后续下个版本Zotero不适用再去更新。 https://github.com/mronkko/ZoteroQuickLook Jasminum 插件功能: 主要用的还是前三个功能,对于知网下载的学位论文或者期刊论文等中文文献识别,其次就是功能1合并作者姓名的功能,具体效果在插件步骤中演示。 拆分或者合并Zotero中条目的作者姓名;根据知网上下载的文献文件来抓取引用信息(就是根据文件名);添加中文PDF/CAJ时,自动拉取知网数据,该功能默认关闭。需要到设置中开启,注意添加的文件名需要含有中文,全英文没有效果(还是根据文件名)为知网的学位论文 PDF 添加书签更新中文 translators拉取文献引用次数,是否核心期刊 安装步骤: 下载插件: GitHub下载插件:https://github.com/l0o0/jasminum/releases 百度网盘下载:https://pan.baidu.com/s/10KpghZ72uQ6H2jeKP_Lckw 提取码:EMTC

【XML文件解析(二)】

文章目录 概要:本期主要讲解Qt中的QDomDocument类来实现XML文件的解析。一、创建xml文件二、在XML文件中插入元素三、在XML文件中删除元素四、在XML文件中修改元素值五、读取XML文件内容六、查询XML文件中元素的值结尾 概要:本期主要讲解Qt中的QDomDocument类来实现XML文件的解析。 XML操作类如下图: XML文件如下图: 一、创建xml文件 函数名:CreateXmlFile 参数:_path(传入xml文件生成路径) 功能:在指定位置生成一个空的xml文件 bool XmlOperation::CreateXmlFile(QString _path) { if(_path == "") { qDebug()<<"输入xml文件路径有误!"; return false; } QFile _file(_path); if(!_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug()<<"Open "<<_path<<"failed!"; return false; } QDomDocument _doc; //xml文件声明 QDomProcessingInstruction _instruction = _doc.createProcessingInstruction("xml","version=\'1.0\' encoding=\'utf-8\'"); _doc.appendChild(_instruction); //创建根元素 QDomElement _root = _doc.createElement("root"); _doc.appendChild(_root); //写入到文件 QTextStream outFile(&_file); //缩进4格 _doc.save(outFile, 4); _file.close(); return true; } 二、在XML文件中插入元素 函数名:AddXmlNode 参数:_path(传入xml文件生成路径)_map(传入元素名和对应值) 功能:在指定位置的xml文件中插入元素 bool XmlOperation::AddXmlNode(QString _path, QMap<QString, QString> _map) { if(_path == "