Leetcode 题组 26(二叉树)

222. 完全二叉树的节点个数 给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。 示例 1: 输入:root = [1,2,3,4,5,6] 输出:6 分析: 这个题按照正常递归或者层序遍历都可以写,不过因为是完全二叉树,因此可以使用完全二叉树的性值:满二叉树的节点个数为2^N-1,其中N表示层数(root节点为第1层)。 我们可以判断当前节点是否为满二叉树,如果是,就可以返回从这个节点到下面所有节点的个数,如果不是,就需要递归的寻找左子树个数和右子树个数。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int countNodes(TreeNode* root) { // 递归边界 if (!

IR Evaluation

MAP , MRR , NDCG 第一步,读取数据并处理 读取 qrels.txt中的数据,并对格式进行处理,转成字典形式存储在列表中 queryAns = [] with open("qrels.txt", "r") as f: file = f.readlines() for line in file: query_dict = {} line = line.strip("\n") line = line.split(" ") query_dict['queryId'] = line[0] query_dict['tweetId'] = line[2] query_dict['relevant'] = int(line[3]) queryAns.append(query_dict) 处理结果格式如下 每一条数据以字典的形式存储三个字段: { q u e r y I d , t w e e t I d , r e l e v a n t } \{queryId , tweetId , relevant \} {queryId,tweetId,relevant}

使用JS去除字符串中的HTML标签

背景 有时候我们经常需要删除掉字符串中的一些HTML标签 下面我推荐两个办法 正则表达式 使用正则表达式,通常较为简单的字符串情况不会出现问题,建议对数据进行多测试 str.replace(/<[^>]+>/g, '') 使用innerHTML(推荐) 有时候网上的一些正则可能不符合你的需求,此时我们可以通过HTML自带的textContent来解决 推荐这个方案的原因是我们实际上利用了浏览器的自带的API处理了删除标签的功能,会符合浏览器的渲染机制,较为稳定。 const deleteTag = (str) => { const el = document.createElement('div') el.innerHTML = str return el.textContent }

redis做方法缓存

redis做方法缓存 为什么要拿redis做缓存? ​ redis是一个完全基于内存、数据结构简单、采用单线程的工作方式(避免了不必要的上下文切换)、使用IO多路复用的一个key-value类型的数据库。查询速度要远比mysql这种关系型数据库要快得多。 ​ 系统绝大多数场景下都是读多写少,而mysql能够承受的并发量在每秒两三千(百度得到的数据)的时候就会面临宕机的风险了,并且查询速度极慢。 1、查询流程 ​ 在请求达到后端之后,对需要进行缓存的接口,会先去redis中找有无数据,没有的话会继续走正常的业务流程,然后将查询到的结果返回给客户端的同时也放在redis中一份,下次相同请求进来后,就可以直接从redis中拿到数据。 2、代码实现,举个栗子 2.1 自定义缓存注解 @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface RedisCache { int expire() default 86400;//缓存多少秒,默认 24*60*60 1天 String key() default "";//缓存key为空时取方法名 } 2.2 对添加@RedisCache注解的方法进行缓存 @SuppressWarnings("unchecked") @Around("@annotation(com.shao.cacheCompont.RedisCache)") public Object RedisCache(final ProceedingJoinPoint jp) throws Throwable { Method method = getMethod(jp);//获取注解上的方法 RedisCache cache = method.getAnnotation(RedisCache.class); final String cacheKey = cache.key(); StringBuilder buf = new StringBuilder(); if (StringUtil.isNotBlank(cacheKey)) { buf.append(cacheKey); } else { buf.append(jp.getSignature().getDeclaringTypeName()).append(".").append(jp.getSignature().getName()); } Object[] args = jp.

JavaScript中的变量、作用域与内存

JavaScript中的变量、作用域与内存 1.原始值与引用值 ECMAScript包含两种不同类型的数据:原始值和引用值。原始值就是最简单但的数据类型,引用值则是由多个值构成的对象。在javaScript中不允许直接访问内存空间,在操作对象时,实际上操作的时对象的引用,而非对象本身。 动态属性 在用new关键字时,JavaScript会创建一个Object实例,就可以对创建的对象动态添加属性。 let name1="marin"; let name2= new String("mata"); name1.age=27; name2.age=25; console.log(name1.age); //undifined console.log(name2.age); //25 复制值 let name1="mate"; let name2=name1; 此时,name1与name2在内存中是完全独立的,对引用操作时,两个引用互不影响。 let name1=new Object(); let name2=name1; name1.name='mate'; console.log(name2.name) //mate 当赋值变量是Object对象时,存储在变量中的值也会被复制到新变量所在的位置,区别在于,这里复制的实际上是一个指针,它指向堆内存中的对象,操作完成后,两个变量实际上指向同一个对象。 传递参数 ECMAScript所有函数的参数都是按值传递的。当参数无论是原始值还是引用值,都会像复制值那样将复制参数。 function add(num,obj){ num+=10; obj.name="add"; obj=new Object(); obj.name="testAdd"; return num; } let num1=10; let obj=new Object(); let result=add(num1,obj) console.log(num1) //10 console.log(obj.name) //add 确定类型 result=variable instanceof constractor 2.执行上下文与作用域 变量或者函数的上下文决定了它们可以访问哪些对象以及他们的行为。任何变量都存在与某个执行上下文中,这个上下文(作用域)决定了变量的生命周期,以及它可以访问代码的那些部分。 执行上下文分为全局上下文、函数上下文何块级上下文代码执行流每进入一个新的上下文,都会创建一个作用域链,用于搜索函数和变量函数或块的局部上下文不仅可以访问自己作用域内的变量,也可以访问任何包含上下文乃至全局上下文中的变量。全局上下文只能访问全局上下文中的函数和变量,不能访问局部上下文中的任何数据。变量的执行上下文用于确定什么时候释放内存。

python实现nvidia-smi功能

#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/11/24 # @Author : linzhe import pynvml pynvml.nvmlInit() gpunum= pynvml.nvmlDeviceGetCount() for i in range(gpunum): try: handle = (pynvml.nvmlDeviceGetHandleByIndex(i)) # GPU id meminfo = pynvml.nvmlDeviceGetMemoryInfo(handle) print('gpu%d \t used:%5d/%d \t free:%d/%d'%(i, meminfo.used//1048576, meminfo.total//1048576, meminfo.free//1048576, meminfo.total//1048576)) except pynvml.NVMLError_GpuIsLost: print('gpu%d lost'%i) 效果 gpu0 used: 3/11019 free:11016/11019 gpu1 used:10888/11019 free:131/11019 gpu2 used:10888/11019 free:131/11019 gpu3 used: 3/11019 free:11016/11019 gpu4 lost gpu5 used: 3680/11019 free:7339/11019 gpu6 used: 9580/11019 free:1439/11019

(转载)shell命令 DIR=“$( cd “$( dirname “${BASH_SOURCE[0]}“ )“ && pwd )“详解

转载,原文链接 最近经常在bash脚本文件中看到类似于如下所示的语句: DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "${DIR}/.." 刚开始真弄不明白这是什么含义,通过深入学习bash脚本知识,终于理解其含义,现将详细解释记录如下,以备今后不时之需。 ${BASH_SOURCE[0]}表示bash脚本的第一个参数(如果第一个参数是bash,表明这是要执行bash脚本,这时"${BASH_SOURCE[0]}"自动转换为第二个参数),例如: bash modules/tools/planning_traj_plot/run.sh modules/tools/planning_traj_plot/example_data/1_planning.pb.txt modules/tools/planning_traj_plot/example_data/1_localization.pb.tx "${BASH_SOURCE[0]}"代表的是modules/tools/planning_traj_plot/run.sh。 "dirname"表示提取参数里的目录,dirname "${BASH_SOURCE[0]}"表示提取bash脚本第一个参数里的目录,例如modules/tools/planning_traj_plot/run.sh”的目录为"modules/tools/planning_traj_plot。 cd "$( dirname "${BASH_SOURCE[0]}" )"表示切换到刚才提取的目录,例如:对于上述示例中的的目录modules/tools/planning_traj_plot,cd "$( dirname "${BASH_SOURCE[0]}" )"表示在当前目录的基础上,切换到子目录modules/tools/planning_traj_plot。 DIR=cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd则表示,如果第一条语句顺利执行,就执行pwd显示当前目录,并将结果赋值给变量“DIR”。 cd "${DIR}/.."自不必说,就是切换到“DIR"变量所指目录的上一级目录。 下面是完整的示例: 1.run.sh文件内容(省略实际执行部分): #!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" echo ${DIR} cd "${DIR}/.." 2.在Shell终端执行如下命令(当前路径为:/home/davidhopper/code/apollo ) bash modules/tools/planning_traj_plot/run.sh modules/tools/planning_traj_plot/example_data/1_planning.pb.txt modules/tools/planning_traj_plot/example_data/1_localization.pb.tx 结果如下: /home/davidhopper/code/apollo/modules/tools/planning_traj_plot 1

java 实现pdf转换成图片

参考1:java实现pdf转换成图片 来源:java 实现pdf转换成图片_ZZ的博客-CSDN博客_java pdf 转图片 1.maven添加jar <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox</artifactId> <version>2.0.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.9</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> 2.实现代码 /** * 转换全部的pdf * @param fileAddress 文件地址 * @param filename PDF文件名 * @param type 图片类型 */ public static void pdf2png(String fileAddress,String filename,String type) { // 将pdf装图片 并且自定义图片得格式大小 File file = new File(fileAddress+"\\"+filename+".pdf"); try { PDDocument doc = PDDocument.load(file); PDFRenderer renderer = new PDFRenderer(doc); int pageCount = doc.

关于js变量声明的几种方式

1.var::1没有块的概念,可以跨块访问,不能跨函数访问; 2.存在变量提升 2.let:1.let声明的的变量只在它所在的代码块有效; 2.不存在变量提升。let不会像var那样发生“变量提升”,因此,变量需要先声明后使用,否则报错 3.不允许重复声明。 3.const: 1.一旦声明就必须立即初始化; 2.一旦声明,常量值就不能改变(指堆内存中的地址不能改变) 3.其他和let一样 4.function():1.函数声明后不会立即执行,需要调用的时候才会执行; 2.对支持es5和es6浏览器环境在块作用域内有一定区别,所以应该避免在块作用域内声明函数。 5.class: 1.相比于对象原型的方式更清晰 2.更像面向对象编程的语法 6.import: 1.import命令接收一对大括号,其里面的变量名必须与被导入模块对外接口的名称相同 2.用as关键字可以将输入的变量名重命名 3.import命令输入的变零都是只读的 4.import命令具有提升效果,会提升到整个模块的头部,首先执行(因为Import命令是在编译阶段执行的,在代码运行之前) 5.import是静态执行,不能使用表达式和变量 6.import会执行所加载的模块

Python Selenium 抓取Shadow Dom内部元素方法更新

By Mejias 背景: 应团队的PMP的要求,为自己的Team开发了一个内部网站信息抓取的工具(整体代码展示见文章末尾,可能稍微有点长)。上上周周写完测试后推给了大家,没有什么问题。今天Team的一个小伙伴突然告诉我报错,显示是Chrome Driver与Chrome版本不对,搜索Chrome://version,才发现是Chrome自动升级了。这样原来版本的Chrome driver就不支持了,导致程序报错。 在Chrome Driver官网here重新搜索了版本匹配的Chrome Driver并下载安装好之后,再次运行程序,发现前面都运行的很好直到后面首尾部分报错如下: 报错显示的是下面这里出了问题: def control_in_shadow(driver,js): shadow = driver.execute_script(js) return shadow #返回的对象在这里 js = 'return document.querySelector("#ra-shadow-root").shadowRoot' shadow= control_in_shadow(driver,js) shadow.find_element(By.ID,'ra-asin-list-count-input').clear() shadow.find_element(By.ID,'ra-asin-list-count-input').send_keys('1000') shadow.find_element(By.ID,'ra-asin-list-load-btn').click() 上面的代码访问下列Shadow Doml里的元素。 采用的方法就是常说的三步法: 定位到Shadow Dom的Host节点 =》 使用.shadowRoot属性定位到根节点 =》 直接通过页面Element的方法访问Shadow Dom内部的元素。这种方法在未更新chrome driver 的版本之前一直用的很好的。 但是在更新了Chrome版本和chrome driver版本之后就会报错了。原来的方法在新的chrome driver并不适用。于是在收到小伙伴的反馈后,就需要测试代码问题以及修改和Refine了。 测试&发现问题: 首先根据上面的报错可以定位到是下面的代码出了问题。 ​ def control_in_shadow(driver,js): shadow = driver.execute_script(js) return shadow #返回的对象在这里 js = 'return document.querySelector("#ra-shadow-root").shadowRoot' shadow= control_in_shadow(driver,js) shadow.find_element(By.ID,'ra-asin-list-count-input').clear() shadow.find_element(By.ID,'ra-asin-list-count-input').send_keys('1000') shadow.find_element(By.ID,'ra-asin-list-load-btn').click() ​ 因为.execute_script(js)是driver对象自带的方法,这一段执行JS语句也没有报错,所以肯定不是定义的新方法的问题。而且看代码报错是说函数返回的对象是一个dict,而不是原来应该是的remote controlled web element元素,导致web element的查找元素的方法.find_element(By.)使用报错。所以我这里定位到这个返回对象“shadow”是否问题。 为了测试它是否只是一个dict还是说代表了shadowRoot这个节点,我们可以使用shadowRoot的一些属性和方法去测试他是否是一个shadowRoot。

filter的使用

最近有点闲,想想写点什么。。。。 写一点vue的filter过滤器的使用 想一个可以使用过滤器的场景。 写一个表格,里面有几组数据,循环出来,给数组一个状态,根据这个状态来显示不同的东西 以前的想法是在获取到数据的时候处理数据把数据改成状态 那样也可以达到想要的需求 但是有了过滤器 会让你的代码更高级也更方便 先来个数据吧 首先文件夹里面创建一个filter文件夹,里面创建个filter.js,就是要使用的过滤器了,再里面创建个order.js里面是要展示的数据,暴露出来 定义好的数据里面再定义一下status代表的意思,然后再找个页面展示一下 再加个样式,展示出来下面这个样式 现在要写过滤器里面的方法了, 引入并注册使用看效果 刚刚引入使用的时候我发现过滤器没反应,看半天才发现我使用的是暴露出的setStatus,而setStatus不是一个方法,而是里面的setFilter,尴尬。。。 看看效果 完美!但是我又想给这个不同状态改变颜色该怎么办呢? 再使用过滤器!!!过滤器串联一下 给样式添加一下 看看效果 好结束 

TensorFlow2.0 系列开篇: Windows下GPU版本详细安装教程

点击上方“小白学视觉”,选择加"星标"或“置顶” 重磅干货,第一时间送达 【导读】今年三月谷歌在TensorFlow开发者峰会上宣布TensorFlow 2.0 Alpha版本(内部测试版)之后,TensorFlow 2.0 Beta版本(公开测试版本)已经发布。TF2.0相比于1.x版本默认使用Keras、Eager Execution、支持跨平台、简化了API等。这次更新使得TF2.0更加的接近PyTorch,一系列烦人的概念将一去不复返。如果2019的下半年开始入坑TF,那么你将选择进入AI的最佳时机了,Tensorflow社区蓬勃发展,未来可期。接下来就给大家带来TF 2.0 Beta –Window系统下GPU版本的详细完整的安装教程。 目录 1.Anaconda 安装Anaconda 修改路径 修改默认浏览器 2.CUDA10.0 CUDA安装 cuDNN安装 PATH配置 3.TensorFlow2.0 Beta-GPU版本安装与测试 确认显卡 测试 1. Anaconda a. 下载 首先进入Anaconda的官网: https://www.anaconda.com/distribution 选择Windows下Python3.7(注意:必须选择64位,因为TF不支持Python32位的) 下载完成后打开,然后就是傻瓜式的安装,一路next即可。 b. 修改路径 默认地址为C盘(这是默认地址,如果你通常安装在c盘的话,可以忽略此步骤), 如果安装后没有其他的操作的话,打开.juyter文件是没有[jupyter_notebook_config.py] 打开cmd,输入 jupyter notebook --generate-config 回车,会产生[jupyter_notebook_config.py] 用Notepad++打开[jupyter_notebook_config.py],找到c.Notebook 建立你的新工作路径 取消注释,c前面的#要去掉 点击保存,这下就修该好了路径 cmd,输入[jupyter notebook],你就发现你的路径已更改 c. 修改默认浏览器 打开[jupyter_notebook_config.py] 找到你想用的浏览器路径(下面是我的浏览器路径) 打开[jupyter_notebook_config.py] 找到App.browser = '',在这行下面添加以下三行代码 import webbrowser webbrowser.register("chrome",None,webbrowser.GenericBrowser(u"C:\ProgramFiles (x86)\Google\Chrome\Application\chrome.exe")) c.NotebookApp.browser = 'chrome' 这样就修改好了Anaconda使用的浏览器和使用路径,还是非常简单的。现在打开我们的Jupyter Notebook(后面将会在这个文件夹写下Tensorflow2.0的笔记内容) 2. CUDA 10.0 a. CUDA 安装

服务器安装 colmap

Installation — COLMAP 3.7 documentation 按照里面的源码安装尽量安完 apt-get 准备 eigen eigen>3.3 ,不然会报错 从这里下载 eigen 3.3.4 Eigen Releases · libeigen / eigen · GitLab 放在 home 然后 cmake, make, install 即可 cmake .. -DCMAKE_INSTALL_PREFIX=../install/ 准备ceres, googlesource的打不开,用了github上面的, 或者 git clone https://gitee.com/coolke/ceres-solver.git 然后cmake make 即可,它可以自己找到 eigen344 注意 由于对gflags版本有要求,git clone,然后cmake, build 在 ceres的 cmakelists中 SET(gflags_DIR "/home/shilinzhe/gflags_stable/build") cmake 时候指定非sudo安装目录 cmake .. -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=../install/ make 然后 make install 只有经过make install , CeresConfig.cmake这个文件才出现被找到 Installing: /home/shilinzhe/ceres-solver/install/lib/cmake/Ceres/CeresConfig.cmake 准备colmap cmake时候需要额外设置,ceres在哪,安装在哪

桌面显示器带Type-c接口 支持65W充电和投屏方案

随着USB TYPE-C接口的普及,越来越多的手机和笔记本电脑都支持通过C接口输出视频。这个小巧而精密的接口,大有把传统的HDMI和DisplayPort接口取而代之的架势。如今type-c的普及已经非常广泛,不仅手机,笔电,平板用上了type-c接口,而且像台灯,蓝牙音响,无人机,电动工具等小功率设备都开始用上了type-c接口,可谓是进入了我们生活的方方面面。特别是usb4的推出,更是为USB TYPE-C接口一统有线接口形态奠定了基础。在这样的背景下,显示器和电视机采用USB TYPE-C接口就成为了必然。显示器带Type-c接口 支持65W充电和投屏方案Type-c显示器必然是以后的趋势。 深圳市禾川兴科技有限公司 USB Type-C接口,同时具有HDMI/USB扩展和直流供电,桌面式显示器的典型形态,整个显示器通过DC接口输入类似24V/3A的大功率电源,出了满足本身的功率需求,还可以为通过USB Type-C接口接入到显示器的手机或者笔记本电脑提供PD快充。LDR6290,就是专门为这种单USB Type-C接口桌面显示器而设计的专用解决方案。

GAN 的训练

关于GAN训练过程的一点思考 - 知乎 01-GAN公式简明原理之铁甲小宝篇 - 知乎 GAN整整6年了!是时候要来捋捋了! - 知乎 数百篇GAN论文已下载好!搭配一份生成对抗网络最新综述! - 知乎 怎样训练一个GAN?一些小技巧让GAN更好的工作 - 知乎 关于生成器和判别器的梯度 训练GAN的一些骚操作 - 知乎 GAN的优化(六):GAN训练的几个问题 - 知乎 GAN网络训练过拟合如何解决? - 知乎 Github 项目|可视化 GAN 的训练过程 - 知乎 GAN:固定训练好的判别器网络,去指导训练生成器为什么不可以? - 知乎 GAN如何判断 什么时候停止训练? - 知乎 判别器loss为0时候 训练一个GAN loss这样应该怎么改进? - 知乎

Linux /var/log/日志文件太大,清理journal就行

在CentOS 7开始使用的systemd使用了journal日志,这个日志的管理方式和以往使用syslog的方式不同,可以通过管理工具维护。 Linux log日志占用 Linux使用df -h检查磁盘文件,可以看到/run目录下有日志目录/run/log/journal,占用了数G空间。 或者直接在相应目录下执行du --max-depth=1 -h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 8.5G 4.2G 4.4G 49% / tmpfs 16G 1.6G 15G 11% /run [rss@VM_0_16_centos log]# du --max-depth=1 -h 254M ./php-fpm 36K ./anaconda 256K ./redis 4.0K ./chrony 4.0K ./ppp 4.0K ./ntpstats 256K ./letsencrypt 4.0G ./journal 34M ./audit 24K ./tuned

用TypeScript编写Electron + React + Ant-Design 项目

1、首先安装React脚手架 npm install create-react-app -g 2、用create-react-app脚手架创建typescript模板 create-react-app my-app --template typescript 3、安装react-app-rewired以及cross-env npm install react-app-rewired cross-env 4、引入Ant-Design yarn add antd 修改src/App.tsx,引入antd的按钮组件 import React, { FC } from 'react'; import { Button } from 'antd'; import './App.css'; const App: FC = () => ( <div className="App"> <Button type="primary">Button</Button> </div>); export default App; 修改src/App.css,在文件顶部引入antd样式 @import '~antd/dist/antd.css'; 5、将electron引入react 工程,主要是添加electron.js入口文件,以及修改package.json

QT自动适配高分屏的解决方案

使用QT在开发桌面程序的时候,很多时候需要涉及到高分屏的适配问题。如果之前没有做过高分屏适配可能会遇到很多问题,这里提供一套方便的QT高分屏适配方案供大家参考。在适配高分屏的时候需要考虑两个要求: 1.同一屏幕百分比缩放的适配 2.多个屏幕组合的时候自动适配 如果是只有一个屏幕的话,windows是支持百分比缩放的,如果缩放百分比对应的应用也应该进行缩放。windows的缩放设置如下: 如果有多个屏幕,可能会是高分屏和低分屏的组合,这时候如果拖动应用会要求应用自动识别屏幕的分辨率进行适配。 针对上面两个要求,可以采用下面的方案进行高分屏适配。但此方案也有局限性 1.此方案只针对windows生效,Linux不可以 2.要求Qt版本是5.6以上 方案如下: 首先需要在pro文件中添加两个windows库 LIBS += User32.Lib LIBS += gdi32.lib 其次在程序入口里面添加如下设置: #include "mainwindow.h" #include <QApplication> #include <QMessageBox> #include <QDir> #include <Windows.h> #include <WinUser.h> #include <wingdi.h> #pragma execution_character_set("utf-8") int main(int argc, char *argv[]) { double dScaleFactor = 1.0; //应用开启DPI感知 SetProcessDPIAware(); //计算当前屏幕的DPI HDC desktopDc = GetDC(NULL); float horizontal_dpi = GetDeviceCaps(desktopDc, LOGPIXELSX); float vrtical_dpi = GetDeviceCaps(desktopDc, LOGPIXELSY); int hv_dpi = (horizontal_dpi+vrtical_dpi)/2; //计算DPI的缩放系数设置全局的QT缩放系数 dScaleFactor = static_cast<double>(hv_dpi)/96.0; qputenv("QT_SCALE_FACTOR", QString::number(dScaleFactor).

后台开发语言选择哪个,java,c#, python,golang

选java,因为开发人多。 不选C# ,因为框架太垃圾,c#语言比java要牛逼,但java开发人多。 不选python, 因为后台维护太麻烦,python简单开发快,但java开发人多。 不选golang,因为异常处理面向对象麻烦,golang并发牛逼,但java开发人多。 java就是人多,用的人多了,所有的坑都被填完了。

【MyBatis快速入门】MyBatis编程流程

文章目录 0.把数据导入数据库1.下载依赖包2.写配置文件3.写代码访问数据库里的数据3.1 实体类3.2 dao数据访问层3.3 xml配置文件3.4 测试 0.把数据导入数据库 C:\Users\9>mysql -uroot -p*** mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

C语言编译器函数库自带的排序函数——qsort函数及例子

一、qsort函数介绍(可以处理不同类型的数组数据) (详细介绍见qsort_百度百科 (baidu.com)) 头文件: #include<stdlib.h> 函数原型: 二、例子 例一:针对整型值进行排序, 对“4,8,7,5,2,3,5,9,6”进行排序。 #include<stdlib.h> int Compare_int(const void* a, const void* b)//定义比较函数 { int arg1 = *(const int*)a;//先强转,再解引用 int arg2 = *(const int*)b; return (arg1 > arg2) - (arg1 < arg2); /*也可以用以下if判断语句 if(arg1 > arg2) { return 1; } if (arg1 < arg2) { return -1; } else { return 0; }*/ } void Show_int(int arr[], int len)//展示函数 { for (int i = 0; i < len; i++) { printf("

NVIDIA Tegra Xavier 刷机以及pytorch安装

NVIDIA Tegra Xavier 刷机以及pytorch安装 1.使用模块介绍 ​ 核心是nvidia AGX Xavier,载板是瑞泰新时代的,型号是Z508。如下面链接所示。https://ic-item.jd.com/65529044960.html 2.刷机、jetpack安装方法 ​ 该模块直接使用nvidia的sdkmanager刷机会导致部分外设无法使用,需要使用瑞泰新时代提供的刷机工具。 ​ 刷机、jetpack安装请参考Xavier系统烧录说明手册V1.1 ​ 请严格按照教程来。下方是说明手册、全套刷机工具、sdkmenager下载地址。 链接:https://pan.baidu.com/s/1YHpolfTyVo05scsg9Ya10Q 提取码:x533 3.pytorch安装教程 ​ pytorch主要参考了NVIDIA Jetson NX刷机安装pytorch(看这一篇就够了!!!)_qq_37301003的博客-CSDN博客 ​ 我在安装pytorch1.5+torchvision0.6.0时,pytorch1.5安装正常,torchvision0.6.0安装报:segment fault;然后换pytorch1.6+torchvision0.7.0,在安装torchvision0.7.0时,出现fatal error:libavcodec/avcodec.h:No such file or directory. 参考 在Jetson Xavier NX上安装torchvision编译报错:fatal error: libavcodec/avcodec.h: No such file or directory_星空-CSDN博客 后解决。

使用ant-design中v-mode和v-decorator冲突问题

项目场景: 使用ant-design的form组件: 在a-form组件中使用输入框组件时,v-model无法双向绑定数据 问题描述: 启用v-decorator进行输入框数据校验时,v-model绑定数据无法绑定 <a-form :form="form"> <a-form-item label="name"> <a-input v-model="name" v-decorator="['name', { rules: [{ required: true, message: 'Please input your note!' }] }]" /> </a-form-item> </a-form> data(){ return { name: '123', } } 原因分析: 经过反复测试,发现删除v-decorator后,v-model可以正常绑定数据。 解决方案: 加入v-decorator后无法使用v-model进行双向数据绑定,只能通过 setFieldsValue() 方法进行数据改变 <a-form :form="form"> <a-form-item label="name"> <a-input v-decorator="['name', { rules: [{ required: true, message: 'Please input your note!' }] }]" /> </a-form-item> </a-form> mounted(){ this.form.setFieldsValue({ name: '1234' }) }

Vue 对element-ui的Popover进行二次封装

效果: 代码: 全局封装(复用) <template> <div class="screen"> <el-popover :placement="placement" :width="screenWidth" trigger="click" popper-class="popperScreen" :title="title" ref="popoverSH" > <div> <slot></slot> </div> <div style="text-align: center; margin: 10px 0 0 0"> <el-button class="smallBtn" @click="determine">确定</el-button> <el-button class="skyBtn" @click="cancel">重置</el-button> </div> <div slot="reference" class="selectStyle mt5 ml10">{{ screenTitle }}</div> </el-popover> </div> </template> <script> export default { name: "gb-screen", data() { return {} }, props: { // 箭头位置 placement: { type: String, default: 'bottom-start' }, // 宽度 screenWidth: { type: String, default: '400' }, // 标题 title: { type: String, default: '请选择筛选条件' }, // 按钮标题 screenTitle: { type: String, default: '请筛选' } }, methods: { determine() { this.

No appropriate protocol (protocol is disabled or cipher suites are inappropriate)(Java版)

问题 在访问MySQL时出现了,如下错误: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) The following required algorithms might be disabled: SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, include jdk.disabled.namedCurves. Edit the list of disabled algorithms to include required algorithms. You can try to enable TLSv1 or TLSv1.1 first. JDBC driver may have disabled TLS 1.1 and its earlier versions.

Bootstrap V5 图标字体的引入以及使用方法

目录 图标字体使用方法一 文件下载 文件引用 使用图标 图标字体使用方法二 文件下载 文件引入 使用图标 图标字体使用方法一 文件下载 打开官网链接:Bootstrap v5 官网,点击图标库; 点击安装; 页面跳转,点击这里复制; 文件引用 粘贴刚才复制的内容到html文件中(注意自己的css文件需要在引入的文件下方,方便修改) 使用图标 选择自己喜欢的图标,点击复制样式; 回到自己的文件粘贴刚才复制的样式,保存即可; 打开浏览器查看。 图标字体使用方法二 文件下载 打开官网链接:Bootstrap v5 官网,点击图标库; 点击安装; 页面跳转,点击这里下载zip; 页面跳转后,下载zip下图zip并解压; 解压zip找到里面的font文件夹; 文件引入 复制一份刚才的font文件夹到你需要引入的位置,然后引入以下文件即可; 使用图标 选择自己喜欢的图标,点击复制样式; 回到自己的文件粘贴刚才复制的样式,保存即可; 打开浏览器查看,已经成功了!

Webpack 中常用的loader和plugin已经webpack如何配置

dist文件夹存放打包后的文件 动态获取出口路径,需要有webpack init 生成package.js文件 1.1webpack是什么 webpack 是一种前端资源构建工具,一个静态模块打包器 (modulebundler) 。 在 webpack 看来 , 前端的所有资源文件 (js/json/css/img/less/...) 都会作为模块处理。 它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源 (bundle) 1.2webpack五个核心概念 1.2.1Entry 入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图。 1.2.2Output 输出(Output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名。 1.2.3Loader Loader 让 webpack 能够去处理那些非 JavaScript 文件 (webpack 自身只理解 JavaScript) 1.2.4Plugins 插件 (Plugins) 可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩, 一直到重新定义环境中的变量等。 1.2.5Mode 模式(Mode)指示webpack使用相应模式的配置 3.2打包样式资源 css-loder less-loder style-loder 3.3打包HTML资源 HtmlWebpackPlugin 3.4打包图片资源 url-loaderfile-loader 3.6devserver devServer: { // 项目构建后路径 contentBase: resolve ( __dirname , 'build' ), // 启动 gzip 压缩 compress: true , // 端口号 port: 3000 , // 自动打开浏览器 open: true } 运行指令npx webpack-dev-server

图像相关算法整理

图像相关算法整理 1.HE算法(灰度直方图均衡算法) 原理:将原始图像的灰度直方图从比较集中地某个灰度区间变成全部灰度范围内的均匀分布步骤: - (1)遍历每一帧图像中的所有像素,记录每个灰度值出现的像素个数 - (2)统计每个灰度值占总像素的百分比,即每个灰度值出现的概率 - (3)建立一个映射表,对原图像的灰度值一一进行映射,修改成新的灰度值,映射关系为: 新灰度值 = (最大灰度值(255) - 最小灰度值(0))*累计概率缺点:对处理的数据不加选择,他可能会增加背景噪声的对比度并且降低有用信号的对比度。 2.AHE算法(自适应直方图均衡算法) 原理:在HE算法的基础上,将图像划为几块分别处理,每一块统计一个各自专属的分布函数。优点:相对于HE算法而言,算法的时间复杂度提高不少,降低了图像处理效率。缺点:AHE算法在对每个像素块独立进行处理映射,块与块之间没有过渡处理,这样就导致图像呈现出来的效果像被切成了几个块。 3.CLAHE(限制对比度自适应直方图均衡算法) 原理:在AHE算法的基础上,加上阈值,来限制对比度,达到削弱噪声放大问题的效果,并使用线性插值/双线性插值的方法来优化块与块之间的过渡问题。 对于当前块中的像素灰度值,是由其相邻块共同决定的; 如果直方图中统计的灰度值与我们设定的阈值进行对比,超出阈值的部分将其均匀的分布在每一个不同的灰度值下面。 4.BBHE(图像双直方图均衡算法) 原理:基于图像均值来分割输入图像,得到两幅子图,一副是像素值小于或者等于均值的样本集,另一个是像素值大于均值的样本集,分别独立的进行直方图均衡化步骤: - (1)统计所有出现的灰度值的次数 - (2)将次数进行归一化,得到归一化直方图 - (3)计算累计直方图 - (4)将累计直方图进行区间转换 *区间转换公式:结果 = 最小值 + 累计直方图的值 (最大值 - 最小值) 注:累计直方图:每一个概率值代表小于等于此灰度值的概率 5.DES加密算法 几个定义: 密匙:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。对称加密:通信双方同时掌握一个密钥,加密解密都是由一个密钥完成的(即加密密钥等于解密密钥,加解密密钥可以相互推倒出来)。双方通信前共同拟定一个密钥,不对第三方公开。分组加密:分组密码是将明文分成固定长度的组,每一组都采用同一密钥和算法进行加密,输出也是固定长度的密文。 5.1 密匙产生 对于一个64位的密匙而言,其中只有56位是有用的,剩下的8位是用作奇偶验证的。 步骤:(1)将64位密匙通过下图所示的密匙置换表一去掉8个验证位,得到一个56位数据k’; (2)将k’分成左右两块,前28位为C0,后28位为D0; (3)根据轮数分别按照下图所示的表将上一次的两块分别循环左移1位或者2位,得到Ci,Di; (4)将Ci,Di合并得到56位数据,再通过下图所示压缩置换表得到子密匙Ki。 5.2 S盒(代换选择) S盒是整个变换中唯一的非线性运算过程。 步骤:(1)48位数据划分成8个盒,每个盒输入为6位数据; (2)通过6位数据中的第1,6组成二进制数作为行数,中间4位组成的二进制数作为列数; (3)将对应的行列的数在下图中找到对应的十进制数,再按照四位二进制输出 5.3加密步骤 (1)64位明文使用下图所示初始置换表进行置换得到新数据(表中的数据表示第多少位的数据放到该位置) (2)分成左右两块,L0(前32位)R0(后32位) (3)i<=16时,对于Li而言,等于R(i-1),对于Ri而言,先要让R(i-1)进行扩充置换操作得到48位数据,置换表如下第一个图所示,在与K(i-1)进行异或操作,得到新的48位数据,再对该数据通过S盒得到32位数据,下一步通过置换表得到一个新的32位数据,最后与L(i-1)进行异或操作得到Ri。 (4)经过十六轮之后,将L16和R16合并作为输入块,通过下图所示的逆置换表进行逆置换操作,得到最后的密文并输出。

vue 复制 粘贴div标签内容

vue 复制 粘贴div标签内容 安装clipboard.js npm install clipboard 在vue页面引入clipboard.js import Clipboard from 'clipboard';//引入安装复制插件 html代码 <button class="btn" data-clipboard-target="#text" <!--这里绑定的是要复制的标签的id--> data-clipboard-action="copy" //这个加不加都可以 @click="btnCopy" <!--这里是触发的方法--> > 复制 </button> <div id="text">这里是要复制的内容</div> vue.js代码 btnCopy() { let textUrl = new Clipboard('.btn'); textUrl.on('success', (e)=> { console.log(e.action); this.$message('复制成功'); textUrl.destroy() }); textUrl.on("error", () => { consold.log("没有复制成功") this.$message('没有复制成功'); textUrl.destroy(); }); }

Springboot jpa/mybatis连接数据库失败

Springboot jpa/mybatis连接数据库失败 记录一下这个困扰我三天的问题。 先记录一下具体错误,再去分析为什么吧 spring-boot提供了两种配置方式来配置项目信息,properties和yml 前提: 我在服务器上用docker创建了一个mysql容器,MySQL版本是5.7.3 在自己本地电脑上装的MySQL版本是8.0.20 在本地的navicat上也连接上了服务器上的mysql数据库 后续: 创建springboot项目后在pom.xml里面配置好了jpa、数据库驱动、连接池如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>cn.freespider</groupId> <artifactId>blog</artifactId> <version>0.0.1-SNAPSHOT</version> <name>blog</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.

Type-C接口LDR9201兼容性最好的数字转模拟音频解决方案

目前手机大部分都取消了3.5mm耳机接口,那么用有线耳机的用户就需要用到一个Type-C转3.5mm耳机接口的转接器,这里笔者分析了市面上大部分的转接器都是大同小异,直到我了解到乐得瑞科技推出的LDR9201音频芯片,确实有不少过人之处。 LDR9201 是深圳市乐得瑞科技推出的高度集成的单芯片 USB 音频控制器,内置时钟,为 耳机应用节省外部 12MHz 晶振。LDR9201 支持 96 KHz 24 位采样率与外部音频编解码器 (24 位/96KHz I2S 输入和输出),并内置 16/24 位 ADC 立体声、16/24 位 DAC 立体声、耳 机驱动器、五段硬件均衡器、音频 PLL、USB 时钟振荡器和 USB FS 控制器。外部 EEPROM 如 24C02~24C16 的连接为 USB VID/PID/产品字符串、默认增益设置和其他定制需求提供了灵活 性。LDR9201 为 Windows / MAC / Android 等操作系统的 USB 音频解决方案提供最简洁的 BOM。 特点: ◇ 符合 USB 2.0 规范的全速运行模式 ◇ 符合 USB 音频设备类规范 v1.0 ◇ 支持 44.1KHz/48KHz/96KHz、16bit/24bit 采样率 ◇ 嵌入式数字混音器,开机后默认混音器静音(由操作系统控制) 当设置单声道 ADC 时,两个 DAC 通道都与该单个 ADC 数据混合 设置立体声 ADC 时,左声道 DAC 与左声道 ADC 数据混合,右声道 DAC 与右声道 ADC 数 据混合

tomcat高版本之URL解析异常解决

IllegalArgumentException 一、项目场景: 例如:由于Apache的tomcat的版本升级,遵循RFC 7230 and RFC 3986规范解析请求地址。同时添加了对于http头的验证请求。 导致报文存在导致特殊字符(不在解析范围内的)tomcat7.0.65以上的版本会出现java.lang.IllegalArgumentException。 请求报文如下: http://127.0.0.1:8180/appname/doTestTransaction.action?reqJson={"app.xxx":"xxx","app.xxx":"xxx","app.xxx":"xxx",""app.xxx":"xxx"":[{"app.xxx":"xxx","app.xxx":"xxx","app.xxx":"xxx"}]} 二、问题描述: java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:476) ~[tomcat-embed-core-8.5.28.jar:8.5.28] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:687) ~[tomcat-embed-core-8.5.28.jar:8.5.28] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.28.jar:8.5.28] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.28.jar:8.5.28] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.28.jar:8.5.28] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.28.jar:8.5.28] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_161] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_161] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.28.jar:8.5.28] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161] 原因分析: tomcat高版本严格按照RFC 3986规范解析地址。 该规范只允许包含 a-zA-Z 0-9 - _ . ~ 以及所有保留字符 !

面试官:说说你对状态模式的理解?应用场景?

一、是什么 状态模式,允许一个对象在其内部状态改变时来改变它的行为 关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变 把事物的每种状态都封装成单独的类,跟此种状态有关的行为都被封装在这个类的内部 只需要在状态类的管理类中,把某个请求委托给当前的状态对象即可,该状态对象会负责渲染它自身的行为 通用结构如下: 「状态管理类」:在这个构造函数内部,初始化每种状态类的实例。状态管理者将持有这些状态对象的引用,以便把请求委托给状态对象 「各个状态类:」 将每种状态封装成单独的类,与此状态有关的行为都封装在这个类的内部 二、使用 实现一个灯泡,对应打开和关闭状态,如下: class Light { construct () { this.state = 'off' this.button = null } // 创建一个button负责控制电灯的开关 init () { const button = document.createElement('button') this.button = document.body.appendChild(button) this.button.innerHTML = '开关' this.button.onclick = () => { this.buttonWasPressed() } } buttonWasPressed () { if (this.state === 'off') { console.log('开灯') this.state = 'on' } else if (this.state === 'on') { console.log('关灯') this.state = 'off' } } } const light = new Light() light.

turtle标准库的使用

turtle标准库的使用 一. 导入方式 1.import turtle 用这种方式导入turtle库,调用函数时需要turtle.<函数名>()来调用函数。 2.from turtle import * *的意思是导入turtle库中所有函数,这样导入后面调用函数时不需要加turtle.做前缀。 3.import turtle as t 给turtle库起别名叫t,这样调用函数时用t.<函数名>()来调用函数。 二.函数 1.窗体函数setup() turtle.setup(width,height,startx,starty) width:设置窗口宽度,如果值是整数,表示的是像素值;如果值是小数,表示的是窗口宽度与屏幕的比例。 height:设置窗口高度,与上同。 startx:窗口左侧与屏幕左侧的像素距离,不给默认中央。 starty:窗口顶部与屏幕顶部的像素距离,不给默认中央。 2.画笔状态函数 pendown():放下画笔 penup():拿起画笔 pensize():设置画笔线条粗细 pencolor():设置画笔颜色 import turtle turtle.pencolor('blue')//设置为画笔蓝色 下面三个函数要配合使用: color():设置画笔和填充颜色 begin_fill():填充前用 end_fill():填充结束 import turtle turtle.color('blue','red') #画笔颜色蓝,填充颜色红 turtle.begin_fill() #准备填充 for i in range(3): #循环三次 turtle.fd(100) #前进100像素 turtle.left(120) #左转120度 turtle.end_fill() #填充结束 通过上述操作最终我们可以得到一个蓝边内部填充红色的三角形 filling():返回填充状态,True为填充 clear():清空窗口 hideturtle():隐藏画笔形状 showturtle():显示画笔形状 reset():清空窗口,并重置位置 write():输出字符串 3.画笔运动函数 forward():沿着指定方向前进距离 backward():沿着相反方向后退指定距离 setheading(angle):设置朝向方向 circle(r,e):绘制一个半径为r旋转角度为e的圆或弧 undo():撤销最后一步动作 right(angle):向右旋转angle角度 left(angle):向左旋转angle角度 goto(x,y):移动到绝对坐标(x,y)处//不提笔会留下痕迹 speed():设置绘制速度,参数为0-10

C# Task和异步方法

ThreadPool中有若干数量的线程。当有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务,任务执行完毕后线程不会销毁,而是被线程池回收以供后续任务使用。当线程池中所有的线程都被占用,又有新任务要处理时,线程池会新建一个线程来处理该任务。如果线程数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行。ThreadPool相对于Thread来说可以减少线程的创建,有效减小系统开销。但是ThreadPool不能控制线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知,即不能有效监控和控制线程池中的线程。因此NET4.0在ThreadPool的基础上推出了Task。Task拥有线程池的优点,同时也解决了使用线程池不易控制的弊端。 1.无返回值的Task的创建和执行 using System; using System.Threading.Tasks; using System.Threading; namespace TaskDemo { class Program { static void Main(string[] args) { // 实例化一个Task,通过Start方法启动 Task task = new Task( () => { Thread.Sleep(1000); Console.WriteLine($"NEW实例化一个task,线程ID为{Thread.CurrentThread.ManagedThreadId}"); } ); task.Start(); // Task.Factory.StartNew(Action action)创建和启动一个Task Task task2 = Task.Factory.StartNew( () => { Thread.Sleep(500); Console.WriteLine($"Task.Factory.StartNew方式创建一个task,线程ID为{Thread.CurrentThread.ManagedThreadId}"); }); // Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task Task task3 = Task.Run( () => { Thread.Sleep(200); Console.WriteLine($"Task.Run方式创建一个task,线程ID为{Thread.CurrentThread.ManagedThreadId}"); }); Console.WriteLine("执行主线程"); Console.Read(); } } } 运行结果: 2.用Task.Result获取返回值的Task的创建和执行 namespace TaskDemo { class Program { static void Main(string[] args) { // 有返回值的启动task Task<string> task = new Task<string>( () => { Thread.

webpack及babel配置

请先确认自己的电脑已经安装了 node 和 npm,没有安装的请先安装,以下操作需在安装了这两个的基础上操作 webpack配置 1. 创建一个空文件夹 2. 创建 package.json 文件- - -npm init。 使用编辑器打开该文件夹,此处我使用的编辑器为 vscode,再命令行输入命令‘npm init’,会出现一些选项,可以都直接回车,默认设置,全部回车完成后,会生成一个 “package.json” 文件。如下: 如果要更改信息可以直接在改文件中修改 如果希望 “package.json” 文件全部是默认设置,跳过提问信息,可以直接执行命令 ‘npm init -y’ eg: 3. 安装 webpack 相关 3个包:webpack、webpack-cli、webpack-dev-server 执行命令 “npm i webpack webpack-cli webpack-dev-server --save-dev”(这是项目安装,不是全局安装) 安装 webpack 有全局安装 和 项目安装 两种, 建议项目安装,因为可能有好几个项目,使用的 webpack包版本不同, 全局安装的话只有一个版本,不便开发,全局开发是 “npm i webpack -g” 这种 带 “-g” 的 项目安装就是每一个项目独立的 webpack包,方便 使用 npm 安装webpack、webpack-cli、webpack-dev-server 这3个包 i 是 install 的简写 –save-dev 的意思是将安装包记录到 package.json 文件中,开发环境下需安装(有开发环境和生产环境,开发环境是指本地开发时的环境,生产环境是指放到线上运行时的环境)

ARM 内存管理翻译笔记

参考文献: 1.《ARM Cortex-A(armV7)编程手册V4.0》 2.《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition》 3.《深入理解Linux内核》 注意:尽量阅读原文ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition,作者只做了自己需要了解的部分的翻译。尽量避免断章取义。 1.Virtual Memory System Architecture (VMSA)虚拟内存系统架构 B3.1 About the VMSA 关于VMSA 在VMSAv7中,内存管理单元(MMU)控制地址转换、访问权限和内存属性的确定和检查,以及处理器进行的内存访问。MMU由系统控制寄存器控制,也可以禁用MMU。 每个MMU使用一组地址转换和内存映射表中的相关内存属性。对于MMU,转换表定义了以下属性: 访问安全或不安全地址映射内存访问权限控制:不访问、只读、只写、只读/写内存区域属性:顶层属性、内存类型、设备类型等地址转换映射: 如果只有一个转换阶段,那么就是从虚拟地址(VA)到物理地址(PA)如果由两个转换阶段,那么第一阶段从虚拟地址转到中间物理地址(IPA),第二阶段从IPA转到PA,如下图 系统控制协处理器(CP15)寄存器控制VMSA,包括定义转换表的位置,以及启用和配mmu。此外,它们还会报告在内存访问过程中发生的任何故障。 B3.1.1 Address types used in a VMSA description VMSA介绍中用到的地址 对VMSAv7的描述引用了以下地址类型: 虚拟地址: 指令中使用的地址,作为数据或指令地址,是虚拟地址(VA)。PC、LR或SP中的地址是VA。VA映射从零运行到VA空间的大小。对于ARMv7,最大VA空间为4GB,最大VA范围为0x00000000-0xFFFFFFFF。 中间物理地址:在提供两个地址转换阶段的转换中,IPA是第1阶段转换后的地址,也是第2阶段转换的输入地址。在只提供一个地址转换阶段的转换机制中,IPA与PA相同。 在ARM VMSA实现中,只提供了一个地址转换的阶段: 如果实现不包含虚拟化扩展 安全状态执行时 在Hyp模式下执行。 B3.1.2 Address spaces in a VMSA implementation VMSA中的地址空间 ARMv7体系结构支持: 最多32位的VA地址空间。实际宽度为具体实现定义一个高达40位的IPA地址空间。转换表和相关的系统控制寄存器定义了所实现的地址空间的宽度。 备注:大型物理地址扩展程序定义了两种转换表格式。长描述符格式允许以4kb的粒度访问完整的40位IPA或PA地址空间。短描述符格式: 允许访问32位PA地址空间,但最小访问单位为4KB。用于访问40位的PA地址空间,但最小访问单位为16MB。 B3.1.3 About address translation 地址转换 地址转换是将一种地址类型映射到另一种地址类型的过程,例如,将VAs映射到IPAs,或将VAs映射到PAs。转换表定义了从一种地址类型到另一种地址类型的映射。

Android开发一年的总结

从一开始的懵懵懂懂,但是充满兴趣,勇于挑战,然后会做一点点东西,有了一点点的喜悦和成就感。到现在仍然只是会做一点点东西,这一点点东西犹如无根浮萍,离开百度就无依无靠,不能给我踏实感和自信心。 迷茫之后是找文章来看,发现看过之后感觉懂了,过了两天又不知所云。编程的世界里东西太多,今天这里看一点,明天又因为工作的事那里看一点,反反复复,浪费了精力和时间,收获很少。 重新拾起博客,告诫自己:不能要求面面俱到,只求以点破面。做一件事,并把它做好。

Navicat 中创建MySQL函数失败的解决

在Navicat中经常需要创建函数或者过程,在默认环境中,创建函数通常会报错,类似如“ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQ L DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)”///“Error Code: 1655 Cannot create stored routine `myproc`. Check warnings”等错误提示。 在网络上找了许久,说法很多,原因也很多,总结下来有如下几个原因: 1、函数创建开关未打开,导致不能创建函数 可以在控制台运行 SET GLOBAL log_bin_trust_function_creators = 1; 即可打开创建开关,经过测试正常。 2、MySQL创建函数的方法不同 MySQL需要在执行的SQL前加delimiter,定义个开始字符和结束字符,告诉MySQL解释器函数体结束了。常见delimiter后跟//或$$,当//出现之后,MySQL解释器才正式执行。例子如下: DELIMITER // CREATE DEFINER = CURRENT_USER FUNCTION `Test`(`ttt` varchar) RETURNS char BEGIN #Routine body goes here.

java split()方法

今天是圣诞节,我是中国人,无视圣诞节。 文章可能有点长,看下来必定有所收获。 没有学过正则表达式的去b站看,一个半小时应该可以看完,要看请点这里 这是必备的前置技能,不懂得话没法真正明白split用法 方法1:split(String regex) split()方法:分割字符串,参数regex称为分割符,可以使用正则表达式来表示 public String[] split(String regex) { return split(regex, 0); } 1 2 3 入门案例1 分割符可以是任意字母,符号,数字,字符串等等,这个基本都会 @Test public void splitDemo1(){ String str= "1a2"; String[] split = str.split("a"); //split:{"1","2"} for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } } 1 2 3 4 5 6 7 8 9 运行结果 1 2 1 2 注意:String类型是不可变的!分隔符会把字符串拆成若干个子字符串,然后生成一个String数组 入门案例2 分割符可以用正则表达式来表示 @Test public void splitDemo2(){ String str= “a33b444c555d”;

C语言程序设计(第4版)苏小红 课后程序参考6.9

利用e=1+1/1!+1/2!+...+1/n!,编程计算e的近似值,直到最后一项的绝对值小于10^-5为止,输出e的值并统计累加的项数。 (我用外部函数定义了阶乘,这样使得逻辑更加清晰明了,也可以将阶乘写入循环中,亦可实现。) 参考代码: #include<stdio.h> #include<math.h> long fact(long a); //声明定义函数 int main(void) { int count=1; long a=1; double e=1.0; do { e = e + (1.0 / fact(a)); a++; count++; } while (fabs(1.0 / fact(a-1))>=1e-5); printf("e的估计值为:%lf,累加的项数为:%d\n", e, count); printf("%ld",fact(5)); return 0; } long fact(long a) //构造外部阶乘函数 { int i; long b=a; for (i = 1; i <b; i++) { a = a * i; } return a; } 参考截图:(截图中有错误(打错了,在此纠正):for循环内部应该为:i<b)

面试官:说说你对装饰者模式的理解?应用场景?

一、是什么 装饰者模式(Decorator Pattern)就是动态的给类或对象增加职责的设计模式。它能在不改变类或对象自身的基础上,在程序的运行期间动态的添加职责,跟继承相比,装饰者是一种更轻便灵活的做法 这种设计模式非常符合敏捷开发的设计思想:先提炼出产品的最小可用产品,再通过快速迭代的方式添加功能 在生活中,同一张图片,组合不同的滤镜就会有不同的体验 这里实际上就应用了装饰者模式:是通过滤镜装饰了照片。在不改变对象(照片)的情况下动态的为其添加功能(滤镜) 二、使用 在es6上,增添了类的装饰器,用来注释或修改类和类方法,使用类的装饰器实际上就应用了装饰者模式(关于类装饰器的使用这里不再陈述)如下: 在JavaScript 中可以很方便地给某个对象扩展属性和方法,但却很难在不改动某个函数源代码的情况下,给该函数添加一些额外的功能 要想为函数添加一些功能,最简单粗暴的方式就是直接改写该函数,但这是最差的办法,直接违反了开放-封闭原则,如下: var a = function () { alert(1); } // 改成 var a = function () { alert(1); alert(2); } 实际开发中,比如我们想给 window 绑定 onload 事件,但是又不确定这个事件是不是已经被其他人绑定过,为了避免覆盖掉之前的 window.onload 函数中的行为,我们一般都会先保存好原先的 window.onload,把它放入新的 window.onload 里执行 window.onload = function () { alert(1); } var _onload = window.onload || function () { }; window.onload = function () { _onload(); alert(2); } 同样,我们还可以使用AOP 面向切面编程来装饰函数 什么是面向切面编程?举个例子,餐前洗手、饭后漱口,吃饭这个动作相当于切点,我们可以在这个切点前、后插入其它如洗手等动作 下面则使用AOP来修饰onLoad: 首先定义Function.prototype.before 方法和 Function.

Swin Transformer对CNN的降维打击

一、前言 一张图告诉你Transformer现在是多么的强!几乎包揽了ADE20K语义分割的前几名! 该文章详细解读Swin-transformer的相关内容以及高明之处。看完学不会,你在评论区打我!CNN已然在计算机视觉领域取得了革命性的成果,拥有着不可撼动的地位。Transformer最初用于NLP领域,但Transformer凭借其强大的特征表征能力,已经在cv领域杀出了一条血路。 paper链接:https://arxiv.org/pdf/2103.14030.pdf 代码链接:https://github.com/microsoft/Swin-Transformer 二、Swin Transformer 2.1 背景 Transformer最开始用于NLP领域,但其强大的表征能力让cv领域的研究人员垂涎欲滴。然而从NLP转为cv领域,存在两个天然的问题。 1.相较于文本,图像中像素的分辨率更高2.图像的视觉实体尺寸之间差异很大 传统Transformer(例如transformer、ViT等)尽管有强大的特征表达能力,但其巨大计算量的问题让人望而却步。与传统Transformer不同的是,Swin-Transformer解决了Transformer一直饱受诟病的计算量问题。那么,Swin-Transformer是如何解决的计算量问题呢?让我们继续往下看吧。 2.2 Architecture概况 学习swin transformer之前,我们首先需要熟知以下几个概念: Resolution:假设一张图像的分辨率为224x224,这里所说的224就是像素。Patch:所谓的Patch就是由多少个像素点构成的,假设一个patch的size为4x4,则这个patch包含16个像素点。Window:window的size是由patch决定的,而不是由像素点,假设window的size为7x7,则该window包含49个patch,而不是49个像素点。 在对swin-transformer网络进行讲解之前,我们首先需要明确一点:无论是transformer还是swin-transformer结构,都不会改变输入的形状,换句话说,输入是什么样,经过transformer或swin-transformer后,输出跟输入的形状是相同的。 一般而言,我拿到一篇论文之后,会首先分析每个块的输入输出是怎样的,先从整体上对网络结构把握,然后在慢慢的细化。我们首先来梳理一下swin-transformer每个块的输入输出。 stageLayersizeinput image224x224x3patch partition224/4 x 224/4 x 4x4x31linear embedding224/4 x 224/4 x 961swin transformer224/4 x 224/4 x 962patch merging224/8 x 224/8 x 1922swin transformer224/8 x 224/8 x 1923patch merging224/16 x 224/16 x 1923swin transformer224/16 x 224/16 x 1924patch merging224/32 x 224/32 x 3844swin transformer224/32 x 224/32 x 384 从结构图中可以看到,swin-transformer网络结构主要包括以下层: 1.Patch Partition:将输入图像划分为若干个patch2.Linear Embedding:将输入图像映射要任意维度(论文中记为C,即C=96)3.

C语言排序函数qsort用法

qsort函数简介 排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n) 功能: 使用快速排序例程进行排序头文件:stdlib.h用法: void qsort(void* base, size_t num, size_t width, int(__cdecl*compare)(const void*, const void*));参数: 待排序数组,排序之后的结果仍放在这个数组中数组中待排序元素数量各元素的占用空间大小(单位为字节)指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数) qsort要求提供一个自己定义的比较函数。比较函数使得qsort通用性更好,有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。 如比较函数 int cmp(const void *a, const void *b) 中有两个元素作为参数(参数的格式不能变),返回一个int值,比较函数cmp的作用就是给qsort指明元素的大小是怎么比较的。 对int型数组排序 int num[100]; int cmp_int(const void* a, const void* b) //参数格式固定 { return *(int *)a - *(int *)b; } qsort(num, 100, sizeof(num[0]), cmp_int); 可见,参数列表是两个空指针,现在他要去指向你的数组元素。所以转换为你当前的类型,然后取值。默认升序排列(从小到大),如果想降序排列返回*b-*a即可。 对char型数组排序(同int类型) char word[100]; int cmp_char(const void* a, const void* b) //参数格式固定 { return *(char *)a - *(char *)b; } qsort(word, 100, sizeof(word[0]), cmp_char); 对double型数组排序 double in[100]; int cmp_double(const void* a, const void* b) //参数格式固定 { return *(double *)a > *(double *)b ?