Android10(Api 29)新特性适配小结

文档说明 本文档主要对影响比较大的部分进行简单总结,内容并不全面; 本文档基于谷歌AndroidQ官方文档和华为Q版本应用兼容性整改指导(华为的有点过时); 所用测试机:Google初代Pixel,AndroidQ-beta6-190730.005 版本号对应关系 Android-Q = Android-10 = Api29 Android-P = Android-9.0 = Api28 目录 文档说明 设备硬件标识符访问限制原来的做法替代方案 禁止后台启动Activity情况描述解决方法 后台应用增加定位限制情况描述解决方法 分区存储情况描述解决方法方法一、停用过滤视图,使用旧版存储模式方法二、将文件存储到过滤视图中,官方推荐。方法三、使用存储访问框架(SAF),由用户指定要读写的文件。方法四、获取用户指定的某个目录的读写权限1. 申请目录的访问权限2. 通过Uri读写文件 设备硬件标识符访问限制 限制应用访问不可重设的设备识别码,如 IMEI、序列号等,系统应用不受影响。 原来的做法 // 在AndroidQ上以下方法都会有问题 // 返回:866976045261713; TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); tm.getDeviceId(); tm.getSubscriberId(); tm.getDeviceId(TelephonyManager.PHONE_TYPE_NONE); //返回:66J0218B19000977; Build.getSerial(); 在低于AndroidQ的系统上没问题 在AndroidQ及以上的系统上运行时: 如targetSdkVersion<Q,返回null或“unknown”; 如targetSdkVersion>=Q,抛异常: SecurityException: getDeviceId: The user 10196 does not meet the requirements to access device identifiers. 受影响的方法 Build getSerial() TelephonyManager getImei()getDeviceId()getMeid()getSimSerialNumber()getSubscriberId() 替代方案 方案一: 使用AndroidId代替,缺点是应用签署密钥或用户(如系统恢复出产设置)不同返回的Id不同。与实际测试结果相符。 经实际测试:相同签名密钥的不同应用androidId相同,不同签名的应用androidId不同。恢复出产设置或升级系统没测。 // 返回:496836e3a48d2d9d String androidId = Settings.

unity 生成缩略图 , 图片缩放

public static Texture2D Resize(Texture2D source, int newWidth, int newHeight) { source.filterMode = FilterMode.Point; RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight); rt.filterMode = FilterMode.Point; RenderTexture.active = rt; Graphics.Blit(source, rt); var nTex = new Texture2D(newWidth, newHeight); nTex.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0); nTex.Apply(); RenderTexture.active = null; return nTex; }

5分钟掌握矩阵乘法的Strassen算法

By LongLuo 机器学习中需要训练大量数据,涉及大量复杂运算,例如卷积、矩阵等。这些复杂运算不仅多,而且每次计算的数据量很大,如果能针对这些运算进行优化,可以大幅提高性能。 一、矩阵乘法 假设 A A A为 m × p m \times p m×p的矩阵, B B B为 p × n p \times n p×n的矩阵,那么称 m × n m \times n m×n的矩阵 C C C为矩阵 A A A与 B B B的乘积,记作 C = A B C = AB C=AB,称为矩阵积(matrix product)。 其中矩阵 C C C中的第 i i i行第 j j j列元素可以表示为: ( A B ) i j = ∑ k = 1 p a i k b k j = a i 1 b 1 j + a i 2 b 2 j + ⋅ ⋅ ⋅ + a i p b p j (AB)_{ij} = \sum_{k=1}^{p}{a_{ik}b_{kj}} = a_{i1}b_{1j} + a_{i2}b_{2j} + \cdot\cdot\cdot + a_{ip}b_{pj} (AB)ij​=k=1∑p​aik​bkj​=ai1​b1j​+ai2​b2j​+⋅⋅⋅+aip​bpj​

UmiJS之路由

路由 umi 会根据pages目录自动生成路由配置。 约定式路由 基础路由 假设 pages 目录结构如下: + pages/ + users/ - index.js - list.js - index.js 那么,umi 会自动生成路由配置如下: [ { path: '/', component: './pages/index.js' }, { path: '/users/', component: './pages/users/index.js' }, { path: '/users/list', component: './pages/users/list.js' }, ] 动态路由 umi 里约定,带 $ 前缀的目录或文件为动态路由。 比如以下目录结构: + pages/ + $post/ - index.js - comments.js + users/ $id.js - index.js 会生成路由配置如下: [ { path: '/', component: './pages/index.js' }, { path: '/users/:id', component: '.

下一代的多语言JVM:GraalVM

GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言,包括: 基于JVM的语言,比如Java, Scala, Kotlin和Groovy解释型语言,比如JavaScript, Ruby, R和Python配合LLVM一起工作的原生语言,比如C, C++, Rust和Swift GraalVM能有效地支持多语言应用,你可以在一个进程里同时使用多种编程语言而不会带来明显的性能开销——这样你就可以根据具体问题来选择不同语言的解决方案了。 GraalVM的设计目标是可以在不同的环境中运行程序:在JVM中、或者编译成独立的本地镜像、亦或是将Java及本地代码模块集成为更大型的应用。本文先简单介绍下GraalVM能干什么、如何开始使用它以及有哪些需要特别关注的点。 GraalVM的组件 GraalVM是一个大型项目,它有很多可插拔的组件,这使得它几乎无所不能。随便列举几点,它可以更快地运行Java程序,可以取代Nashorn来运行Node.js程序,可以运行Ruby, Python还有R。它可以把Java程序编译成只有数M大小的可执行的本地镜像,可以在Docker容器中运行,而加载时间只有几毫秒。它可以像数据库执行存储过程那样执行JavaScript代码,却不会像数据库那样要消耗太多资源。 GraalVM是一个开源项目,绝大部分是由Java编写的,不是本地代码(native code)的专家也可以参与这个项目中来。也就是说日常用于Java开发的工具就可以用来开发GraalVM。我们先来简单看下它有哪些组件。 JIT编译器Graal 没有一款优秀的JIT编译器,很难称得上是一款高性能的虚拟机。GraalVM的核心便是Graal编译器。Graal可以当作JIT编译器来使用,也可以用作提前编译的静态编译器。 正如GraalVM中的其它组件一样,Graal也是用Java语言来编写的。常见的编译器优化它都能支持:公共表达式消除(common subexpression elimination)、无用代码消除、常量折叠等等。内联及逃逸分析算法是它的看家本领。Graal是一款积极优化的编译器,它的中间代码(或中间表示,Intermediate representation,IR)所使用的程序依赖图(program dependence graph)和HotSpot虚拟机中C2编译器所用的非常相似,尽管它们两者有着显著的不同。在编译期间,高级操作(比如加载Java字段)的中间代码会被转换为底层操作(比如读取地址+偏移量处的数据)的中间代码。而底层中间代码最终会被翻译为机器代码。除了用于分析JIT编译的标准JVM参数(-XX:+PrintCompilation, XX:+PrintAssembly等)外,GraalVM还发布了一款叫Ideal Graph Visualizer的工具,它可以用来调试及分析依赖图的转换过程。 Truffle GraalVM下一个关键的组件便是Truffle了,它是一款编程语言的实现框架。Truffle提供了一套API,你可以用它来基于源程序的抽象语言树(AST)来开发一门语言的解释器。AST求值是程序执行的相对比较简单的方式,因此实现一个解释器要比开发一个优化的编译器要容易得多。不过Truffle可以使用Graal编译器对这些解释器进行优化,因此它们的峰值性能与传统编译器不相上下,有时甚至还要更好。 Truffle使用了一项叫部分求值(partial evaluation)的技术来编译目标语言的解释器。简单来说,给Truffle一个语言解释器和一段程序,它会为这段给定的程序生成一个定制版的解释器。它会把执行时期收集到的分析及类型信息关联到依赖树的节点上,然后使用这些分析数据来进行优化。Truffle需要运行时的编译器支持部分求值,而Graal很好地满足了这项要求。 Truffle上实现的很多语言的解释器都能给我们带来不少灵感。比如js的引擎,LLVM的bitcode解释器,Ruby解释器,Python解释器,以及R解释器——这还只是GraalVM团队的官方项目。Github上还能找到其它语言的解释器的实现。甚至还有为了演示及教学Truffle单独创建的一门语言,你可以亲自体验下。 Truffle的精华之处在于,运行的时候所有的解释器都通过同样的协议来互相操作不同编程语言中的对象,也就是说,JavaScript, Python, Ruby等不同的编程语言或它们的组合所写出来的程序,从运行时的视角来看是没有任何区别的。运行时可以像正常优化代码那样,去优化用不同语言写出来的多语言程序,语言边界的跨越不存在任何性能开销。这就为所有生态系统下的库和模块都敞开了大门,你只需要选择最合适的语言去解决你要解决的问题就可以了,而不用为了项目所用的某个语言去专门实现一些缺少的模块。 Truffle的另一个好处是它对语言的实现进行了虚拟化,也就是说在运行时看来所有语言都是一样的。这样研发工具也可以是多语言的。比如说你可以用JavaScript的调试器来调试Ruby程序,或者使用VisualVM来分析JavaScript程序的内存使用,就像你在JavaScript,Java语言中使用这些工具一样。 本地镜像 GraalVM还有许多其它组件,比如说SubstrateVM,这是一个Java编写的小型虚拟机,它可以将Java应用编译成本地镜像。GraalVM的本地镜像不依赖于JVM来运行,也不需要加载和初始化Java类——并且启动速度还非常快。Graal编译器在生成镜像的过程中,会分析应用的类信息,并将它们提前编译成机器代码。SubstrateVM提供了所有虚拟机所应有的功能:垃圾回收,线程调度,代码缓存等等。它的代码也可以被Graal提前编译。因此它生成的可执行文件的峰值性能可能不如完全预热后的JIT编译的代码那么高,但是它的执行性能很稳定,运行时的开销也很低,并且启动时间是毫秒级的。在某些生产环境比如云或者无服务的部署中,对于长期运行的程序而言,启动时间要比对峰值性能来得重要。 除此之外,GraalVM还可以嵌入到其它的运行时平台中,对它们进行扩展以便支持多语言。目前实验版的Oracle DB就嵌入了GraalVM,你可以使用JavaScript而不是PL/SQL来编写存储过程。同样的功能也通过MySQL插件的方式提供了,因此你也可以在MySQL中使用GraalVM。这项功能看上去可能很鸡肋,不过它让你可以自由选择熟悉的编程语言或者已有的代码库和模块。 GraalVM初体验 体验GraalVM有很多种方式,这取决于你想付出多大的努力。 你当然可以从源码开始编译GraalVM,正如前面所说的,它是遵循带有类路径异常的GPL2许可(GPL2 with the classpath exception license)的开源项目——和OpenJDK相同的许可协议。不过最简单的方式还是去下载预先编译好的二进制包。 发布版和JDK的功能类似,除此之外还有一个JavaScript引擎、Node.js的实现、LLVM bitcode的解释器,以及本地镜像功能。 先下载一个GraalVM的发布版,将它解压到$GRAALVM_HOME目录下。然后便可以通过GraalVM来运行java了: > $GRAALVM_HOME/bin/java -version java version "1.8.0_172" Java(TM) SE Runtime Environment (build 1.8.0_172-b11) GraalVM 1.0.0-rc3 (build 25.71-b01-internal-jvmci-0.45, mixed mode) 你也可以运行JavaScript程序——比如这个单行小程序:

ansible-playbook创建用户

创建用户 [devops@server4 ansible]$ cat inventory [test] 172.25.25.4 [root@server1 ansible]# vim createuser.yml --- - hosts: localhost tasks: - name: create user user: name: "{{ item }}" state: present loop: - user1 - user2 - user3 [devops@server1 ansible]$ ansible-playbook createuser.yml 创建失败,没有权限,授权 vim /etc/sudoers devops ALL=(ALL) NOPASSWD:ALL [devops@server1 ansible]$ ansible-playbook createuser.yml cat /etc/passwd 2.创建用户及密码 [root@server1 ansible]# cat createuser.yml --- - hosts: test tasks: - name: create user user: name: "{{ item.user }}" password: "

推荐一些团队博客和个人博客地址

推荐一些我关注的博客地址,博客地址持续在 博客书签收藏夹 | 签叶 http://kleaves.xyz/c/751201 更新 团队博客 阿里中间件团队博客 http://jm.taobao.org/ 阿里, 中间件, 博客, Java 美团技术团队 https://tech.meituan.com/有赞技术团队 https://tech.youzan.com/ Thoughts, stories and ideas. 360 Netlab Blog http://blog.netlab.360.com/ Network Security Research Lab at 360 故宫博物院 https://www.dpm.org.cn/Home.htmlNoOps http://noops.me/ 小米运维部非官方博客,关注系统、网络、运维、私有云、安全、数据库、内核... 个人博客 开涛的博客 http://jinnianshilongnian.iteye.com/ 《亿级流量网站架构核心技术》作者 温少的日志 http://www.blogjava.net/jobs/ Druid项目的主要负责人 Ha0's Home https://t.hao0.me/出家如初,成佛有余 https://www.yeeach.com/ 曾经的第三方支付从业者,现在区块链从业者 CD826 - 简书 https://www.jianshu.com/u/8f959a9cbc66 Spring Cloud Septvean | 文七 https://septvean.com/ 一些游记 薛定谔的风口猪 http://jaskey.github.io/vpsee https://www.vpsee.com/ 虚拟化技术 云计算 Linux/Mac 性能优化 服务器架构 | VPS 产品和服务 付磊-起扬的博客-云栖社区-阿里云 https://yq.

机器学习三要素:模型、策略和算法

机器学习在干嘛?就是利用已有数据,找到一些合适的数学模型去描述它,然后做一些预测分析,从而优化企业的流程或者提高决策效率。机器学习的核心是:模型、策略和算法 机器学习的目的——模型(Model) 模型就是用来描述客观世界的数学模型,模型是从数据里抽象出来的。在进行数据分析时,我们通常手上只有数据,然后看数据找规律,找到的规律就是模型。就跟我们小时候做猜数字游戏似的,1,4,16...()...256...括号里面是什么?只有把这串数抽象成模型,我们才能知道括号里面是什么。 再举个例子,购买产品的顾客到达服务台的时间是什么模型?也许是一个泊松分布。股票价格随时间的变化是什么关系?是基于布朗运动的二项随机分布... 模型可以是确定的,也可以是随机的,无所谓,总之用数学可以描述,只要数学可以描述的,就可以进行预测分析。所以,我们的根本目的,是找到一个模型区描述我们已经观测到的数据。 如何构造模型——策略(Strategy) 例如,我们想用一个正态分布去描述一组数据,我们就要去构造这个正态分布,实际上就是预测这个分布的参数,例如:均值?方差?...但是,我们需要有一系列的标准去选择合适的模型,模型不是拍脑袋来的。我想用正态分布,理由呢?我想用二项分布,凭啥呢?我想让正态分布的均值为0.5,凭什么0.5比0.2好?所以,需要有一些列标准来证明一个模型比另一个模型好,这就是策略。 不同的策略,对应不同的模型的比较标准和选择标准。就和选班干部一样,选帅的,那就让吴彦祖当班长;选逗比的,也许选出来的是王宝强;选会唱歌的,没准是周杰伦...所以,最终确定的模型是什么,实际上就跟两件事有关,1)我们的数据是什么? 2)我们选择模型的策略是什么? 说到策略,一般会讲到,经验风险最小化作为常用的标准。经验风险最小指的是,用这个模型,用在已有的观测数据上,基本上是靠谱的。但在已有观测数据不足的情况下,我们也可以采用结构风险最小化作为标准。这也是我们在机器学习的时候用到的准则。经验风险和结构最小化是一个参数优化的过程,我们需要构造一个损失函数来描述经验风险,损失函数可以理解为我们预测一个数据错了给我们带来的代价。每个人对损失函数的定义都不同,所以优化出来的结果也不同,这也导致最终我们学习到的模型会各种各样,解决一个问题的方案有多种多样... 模型的实现——算法(Algorithm) 我们有了数据,有了学习模型的策略,然后就要开始去构造模型了,如果模型的基本形式有了,就是一个优化模型参数的问题了。面对复杂的数学优化问题,我们通常难以通过简单的求导获得最终结果,所以就要构造一系列的算法。 我们的目标是让算法尽量高效,更少的计算机内存代价,更快的运算速度,更有效的参数优化结果... 总结:在进行机器学习时,只要把握住模型、策略和算法这三个要点即可。商业决策的基础是对客观环境进行描述,我们用数学模型去描述预测,所以要采取一定的策略选择合适的模型,而模型的构造本质是数学参数优化问题,在大数据的环境下要构造合适的算法去解决对应的优化问题,这就是整个机器学习的方法构造理念。

使用IDEA导入项目时没有项目路径的问题解决

选择File–>project Sturcture(图1)–>Modules + (图2)–>import Module -->选择项目位置–>选择import module from model --> 选择Maven(图3)–>一路next直到finish–>加入点击Add Content Root加入项目路径 ok. 图1 图2 图3

宝塔利用Git + WebHook 实现与码云同步

一、给Linux服务器安装Git 1、git宝塔面板自带,直接安装就好 ​​​​​​ 2、把上图的ssh-rsa全部字符串添加到码云部署项目公钥设置里 这样git就配置好了,为了避免每次都拉代码的时候都需要输入账号密码,打开git终端可以做如下配置 // Git全局配置用户名与邮箱 git config --global user.name "username" git config --global user.email "your@email.com" // 避免每次拉代码都需要输入账号密码 作如下配置 git config --global credential.helper store // 会生成.gitconfig 的文件,查看 cat .gitconfig // 报错cat: .gitconfig : No such file or directory cat ~/.gitconfig // 显示内容 [user] name = username email = your@email.com [credential] helper = store // 第一次pull会提示输入用户名密码,后续就不会提示输入密码了 [root@VM_0_7_centos ~]# git pull Username for 'https://gitee.com': your@email.com Password for 'https://xxxx@xxxx.com@gitee.com':yourPassword(看不到输入内容) 二、配置WebHook 1、在宝塔面板中找到WebHook安装,添加一个Hook

Exception in thread "main" java.lang.ClassNotFoundException:

hadoop jar wordcount.jar input/testdata /output 命令出现标题的错误的话 改成 hadoop jar wordcount.jar jar中主类的绝对路径(cn.lg.project.WordcountMain) input/testdata /output hadoop文件系统路径 /user/hadoop (实在是晚上顿悟,,,,) maven打包过程中一些资源没有 可以去 加号这里添加,把除了java文件以外的文件放进来打包成jar。 pom.xml可以配置打包的过程,但我试了下 没什么卵用,有待研究。 小心拼下错误 导致依赖导入不进去 ,别着急仔细看。 能把wordcount 运行出来很开心了。。。 在运行中 输入目录可以存在 输出目录不能存在 会报错 。。。待更 晚安

SSM练习-Boot客户管理系统的实现--项目介绍篇

SSM练习-Boot客户管理系统的实现 项目介绍 系统功能模块 系统架构设计 根据功能不同,项目结构可以划分为以下层次 持久对象层(持久层):该层由若干持久化类(实体类)组成 数据访问层(DAO层):该层由若干的DAO接口和Mybatis映射文件组成,接口和映射文件名必须一致 业务逻辑层(Service层):该层由若干Service接口和实现类组成。在本系统中,业务逻辑的接口统一使用Service结尾,其实现类以Impl结尾,该层用于实现系统的业务逻辑 Web表现层:该层主要包括SpringMVC中的Controller类和JSP页面。Controller类主要负责拦截用户请求,并调用业务逻辑层中相应组件的业务逻辑方法来处理用户请求,然后将相应的结果返回给JSP页面。 数据库设计 本系统主要涉及到用户登录和客户信息管理,所有会有系统用户表和客户信息表,又由于客户信息中的客户来源和所属行业等内容是根据数据字典表中的信息查询出来的,所有还会有一个数据字典表。 系统用户表 客户信息表 数据字典表 项目源码 推荐SSM jar包大全

载波与测距码

一、载波 可运载调制信号的高频振荡波称为载波。GPS所用的载波有L1、L2载波。 L1载波:由卫星上的原子钟所产生的基准频率f0(10.23MHz)倍频154倍后形成,f1=154*f0=1575.42MHz,入1=19.03cm L2载波:由卫星上的原子钟所产生的基准频率f0(10.23MHz)倍频120倍后形成,f1=120*f0=1227.60MHz,入2=24.42cm 那么原子钟是怎么产生基准频率的呢? 简单来说,原子钟就是一个由铯原子和石英组成的反馈系统,石英就像果冻一样,碰一下,抖一阵,铯原子在石英振动频率有所减缓的时候再使石英恢复初始振频,这样便使石英以恒定的频率永远振动着了,这个频率就是基准频率。 随着GPS现代化的实施,在blockIIF卫星中将增设一个新的载波L5,f5=115*f0=1176.45MHz 采用多个载波频率的主要目的是为了更好地消除电离层延迟,组成更多的线性组合观测值。 二、测距码 测距码是用于测定从卫星至接收机间的距离的二进制码

js根据key值排序

const unordered = { '1': 'foo', '2': 'bar', '5': 'br', '13': 'ar', '111': 'baz' }; const ordered = {}; Object.keys(unordered).sort().forEach(function(key) { ordered[key] = unordered[key]; }); console.log(JSON.stringify(ordered)); 对象动态添加新属性: //创建obj对象 var obj = new Object(); //为对象添加动态属性 obj.userName = "admin"; obj.passWord = "123456"; //输出 console.log(obj); 转载于:https://www.cnblogs.com/lxqboke/p/11346383.html

MySQL编程:将查询到的字段赋值给变量

变量名必须以@开头(文中定义为@xxx),即会话变量。并且不必须要提前声明 方法一: 赋值且查看赋值过程:select @变量1 := 字段1,@变量2 := 字段2 from 数据表 where 条件; 最后打印@xxx。类型应该也是可以对的上的 这是日期类型。 这是int型(int型的查询显示结果为右对齐) 方法二 只赋值,不看过程:select 字段1,字段2… from 数据源 where条件 into @变量1,@变量2… 如果是在函数中使用,必须用这种方式 😁欢迎加入QQ群交流: [游戏-Web-开发技术栈 ☄️] '300567032’ 点击下方图标一键加入!

数据库之元数据——DatabaseMetaData的getMetaData()方法的简单使用

DatabaseMetaData和ResultSetMetaData就是两个常用的获取数据库元数据相关信息的接口,本文讲解DatabaseMetaData和ResultSetMetaData接口获取元数据的方法。 package com; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; public class testMatadata { public static void main(String[] args) { Connection conn=null; //1. JDBC连接MYSQL的代码很标准。 String DRIVER="com.mysql.jdbc.Driver"; String URL="jdbc:mysql://127.0.0.1:3306/test"; String USER="root"; String PASSWORD="root"; try { //1.加载驱动程序 Class.forName(DRIVER); //2.获得数据库链接 conn=DriverManager.getConnection(URL, USER, PASSWORD); DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = null; System.out.println("数据库已知的用户: "+ dbmd.getUserName()); System.out.println("数据库的系统函数的逗号分隔列表: "+ dbmd.getSystemFunctions()); System.out.println("数据库的时间和日期函数的逗号分隔列表: "+ dbmd.getTimeDateFunctions()); System.out.println("数据库的字符串函数的逗号分隔列表: "+ dbmd.getStringFunctions()); System.out.println("数据库供应商用于 'schema' 的首选术语: "+ dbmd.getSchemaTerm()); System.out.println("数据库URL: "

【s3c2440】第一课:程序烧写方法

此系列笔记以韦东山老师的开发板为主。 本节会获得的知识: 使用openJTAG烧写的方法 使用DNW和uboot烧写的方法 整个操作系统的烧写方法 1、安装USB驱动和openJTAG驱动 在win10上安装openJTAG需要禁用驱动程序强制签名,详情在参考手册中。这里有简单的步骤: (1)禁用驱动程序强制签名: 设置->更新和安全->选“恢复”-> 立即重启->疑难解答->高级选项->启动设置->点击“重启”,重启后按数字7,禁用驱动程序强制签名,自动重启完成 (2)安装驱动: 设备管理器->更新驱动程序软件->手动查找驱动->选择驱动所在的位置->下一步完成 USB驱动也不是ch340的驱动,运行此程序即可安装:PL2303_Prolific_DriverInstaller_v1.7.0.exe 2、烧写软件oflash(不支持JLINK) 3、安装一个终端 //Xshell推荐 新建一个串口终端:波特率115200 无流控 com口请自行打开设备管理器查看。 4、烧写 (1)使用并口工具烧写:接线,使用oflash烧写,重新上电观察效果(电脑都没有并口了小老弟) (2)使用openJTAG烧写:接线,使用oflash烧写(oflash烧写完后自动复位开发板,运行程序) 使用场景:烧写uboot必备 命令如下: oflash xxx.bin 0#选择OpenJTAG 1#选择s3c2440 0#选择Nand Flash 0#再次确认Nand Flash 0#烧写到块0 也可以直接oflash 0 1 0 0 0 xxx.bin (3)使用jLink烧写:((没有jLink 操作不来) jLink只支持Nor Flash,不支持Nand Flash,烧好u-boot.bin,使用Nor启动 (4)使用Nor Flash上的uboot来烧写 切记要把uboot烧写到nor Flash!! 使用场景:烧写大型文件,如OS 步骤: oflash 0 1 1 1 0 uboot.bin 设置为nor Flash启动 连接USB到电脑(需要装驱动程序,在USB DNW里有安方法) 上电后快速在xshell里按空格进入uboot 在xshell中输入n #Download u-boot to Nand Flash

String的几种replace()方法

String 和 StringBuilder中都有replace方法,今天我们来看看。 String: String replace(char oldChar, char newChar) 用新字符newChar 替换所有的 旧字符oldChar 。 String replace(CharSequence target, CharSequence replacement) 用新字符串replacement替换所有的 旧字符串target。 String replaceAll(String regex, String replacement) 用新字符串replacement 替换所有的 正则模式匹配的串。——(替换的是模糊字串) String replaceFirst(String regex, String replacement) 用新字符串replacement 替换第一个 正则模式匹配的串。——(替换的是模糊字串) StringBuilder: replace(int start,int end,String str) 用str 替换 start–end的子串。//不包括end

PyTorch中AdaptiveAvgPool函数解析

自适应池化(AdaptiveAvgPool1d): 对输入信号,提供1维的自适应平均池化操作 对于任何输入大小的输入,可以将输出尺寸指定为H*W,但是输入和输出特征的数目不会变化。 torch.nn.AdaptiveAvgPool1d(output_size) #output_size:输出尺寸 对输入信号,提供1维的自适应平均池化操作 对于任何输入大小的输入,可以将输出尺寸指定为H*W,但是输入和输出特征的数目不会变化。 # target output size of 5 m = nn.AdaptiveAvgPool1d(5) input = autograd.Variable(torch.randn(1, 64, 8)) output = m(input) 自适应池化(AdaptiveAvgPool2d): class torch.nn.AdaptiveAvgPool2d(output_size) 对输入信号,提供2维的自适应平均池化操作 对于任何输入大小的输入,可以将输出尺寸指定为H*W,但是输入和输出特征的数目不会变化。 参数: output_size: 输出信号的尺寸,可以用(H,W)表示H*W的输出,也可以使用耽搁数字H表示H*H大小的输出 # target output size of 5x7 m = nn.AdaptiveAvgPool2d((5,7)) input = autograd.Variable(torch.randn(1, 64, 8, 9)) # target output size of 7x7 (square) m = nn.AdaptiveAvgPool2d(7) input = autograd.Variable(torch.randn(1, 64, 10, 9)) output = m(input) 自适应池化的数学解释: 来源于:传送门

Unity 图片的旋转

/// <summary> /// 图片逆时针旋转90度 /// </summary> /// <param name="src">原图片二进制数据</param> /// <param name="srcW">原图片宽度</param> /// <param name="srcH">原图片高度</param> /// <param name="desTexture">输出目标图片</param> public static void RotationLeft90(Color32[] src, int srcW, int srcH, Texture2D desTexture) { if (pixelsLen != src.Length || des == null) { pixelsLen = src.Length; des = new Color32[pixelsLen]; } if (desTexture.width != srcH || desTexture.height != srcW) { desTexture.Resize(srcH, srcW); } for (int i = 0; i < srcW; i++) { for (int j = 0; j < srcH; j++) { des[i * srcH + j] = src[(srcH - 1 - j) * srcW + i]; } } desTexture.

Kubernetes简介及入门

如今单体应用(monolithic application)日渐被认为是一种反模式(antipattern),而云平台则成为了应用部署的香饽饽。这个转变可不仅仅像是在别人的机器上启动一个虚机那么简单。如何能有效地利用云的资源和伸缩性,意味着和要过去的单体应用划清界限,转而拥抱新的架构和开发实践。 微服务正逐渐成为云端应用及服务分发的事实标准。应用被拆分成松耦合的小模块,每个模块都有自己的职责。这种新的架构使得团队能够更加独立地完成自己所负责的功能——而不必依赖于整个公司或组织的大的路线图来进行。除此之外,离散的软件组件使得测试更加简单,还能实现流水化部署。 微服务也带来了新的挑战。在虚机上创建和部署服务只是万里长征第一步,如何维护整个软件的生命周期?容器化便是在此驱动下应运而生的。容器化可以解决微服务架构下的许多问题,比如说: 应有软件和宿主环境解耦,提供比较强的可移植性。容器是轻量且相对透明的,因此更容易扩展。软件及其依赖共同打包发布。 除此之外,容器还是微服务打包部署的非常棒的解决方案。但容器也不是万能的,说白了也还是软件,是软件就涉及到大规模的部署、维护以及管理。开发人员以前只需要监控和维护单个应用,但现在他们有成百上千的服务要管理。这正是Kubernetes所要解决的问题。 Kubernetes是一个开源平台,它可以用来自动化部署、扩展及管理容器化的应用及服务。Google在部署和维护大批量容器时遇到了挑战,于是便有了Kubernetes,之后又把它开源并捐赠给了云原生计算基金会(Cloud Native Computing Foundation,CNCF)。该基金会致力于促进云原生计算生态的发展。Kubernetes是CNCF孵化成功的第一个项目,也成为开源史上发展速度最快的项目。Kubernetes拥有2300个贡献者,被大小公司广泛采用,财富100强企业中有一半都在使用它。 Kubernetes入门 如何开始学习Kubernetes?Kubernetes生态周边出现了大批的支撑项目。整个生态的大图非常复杂,一个很简单的问题可能又把你带到了一片新的未知领域,这很容易让人产生挫败感。所幸的是,入门还是比较简单的,后面再根据你的实际需去了解更多高级概念就好了。本文将会告诉大家如何: 使用Docker和Kubernetes来设置本地开发环境使用Helidon创建一个简单的Java微服务用Docker为微服务构建一个Docker镜像将微服务部署到Kubernetes集群在集群上对微服务进行扩容和缩容 在开始之前,本地需要先安装好这些工具: Docker 18.02或更高版本Kubernetes 1.7.4或更新版本JDK 8或更高版本Maven 3.5或更高版本 可以在MacOS、Linux或Windows平台上安装这些软件的最新版本。 如果还没有安装Docker,可以参考这篇教程,找到对应的平台,按照指令一步步完成。需要熟悉Docker的一些基本知识。 还需要有一个可用的Kubernetes集群,在本文中我们使用的是Minikube。Minikube会在你本地系统的虚拟机内运行一个单节点的Kubernetes集群,这对我们来说就够用了。如果还没有安装过Minikube的话可以看下这篇教程。 装完了Docker、Minikube也能启动本地Kubernetes集群后,我们还缺少一个微服务。之前的文章中有一篇关于Helidon微服务框架的文章,这里我们将参考里面的内容来创建一个微服务。 创建一个基础的微服务 Helidon的Maven原型模板可以帮助我们可以快速地创建一个新工程。下面我们将告诉你如何快速创建并运行一个基础的微服务: $ mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=io.helidon.archetypes \ -DarchetypeArtifactId=helidon-quickstart-se \ -DarchetypeVersion=1.0.1 \ -DgroupId=io.helidon.examples \ -DartifactId=helidon-quickstart-se \ -Dpackage=io.helidon.examples.quickstart.se 进到helidon-quickstart-se目录下去构建服务: $ cd helidon-quickstart-se $ mvn package 现在我们有了一个可以使用的微服务。这个工程还生成了一个应用jar包。我们来运行下看看是否能正常工作: $ java -jar ./target/helidon-quickstart-se.jar [DEBUG] (main) Using Console logging 2019.03.20 12:52:46 INFO io.helidon.webserver.NettyWebServer Thread[nioEventLoopGroup-2-1,10,main]: Channel '@default' started: [id: 0xbdfca94d, L:/0:0:0:0:0:0:0:0:8080] WEB server is up!

SpringBoot多线程下的bean管理——SpringBoot中多线程用Autowired或@Resource注入bean失败报NullPointException

在项目开发过程中,有碰到多线程下用@Autowired或@Resource注入失败,报NullPointException的情况,这就要从Spring对Bean的管理来说明了,这是是因为创建的多线程无法获取到Spring容器中的bean。这体现了熟悉框架原理和底层实现的重要性。 可以有以下解决方法: 1、通过内部类来实现 @Component public class ThreadBean { @Autowired MyService myService; public void execute(){ ExecutorService executorService= Executors.newCachedThreadPool(); executorService.execute(new MyTread()); } private class MyTread implements Runnable{ @Override public void run() { dosomeThing(); } } public void dosomeThing(){ System.out.println("do something"+myService.getTime()); } } 将该类作为Bean组件调用,实现多线程 @Component public class QuartzTask { @Autowired ThreadBean threadBean; @Scheduled(cron = "0/3 * * * * ? ") public void scheduled(){ threadBean.execute(); } } 2、编码通过Spring的上下文对象获取bean public class ApplicationContextProvider implements ApplicationContextAware {

Linux LV扩容时resize2fs: Bad magic number in super-block while trying to open问题解决

linux扩容其中有一步需要使用resize2fs命令重新加载逻辑卷的大小,使用的时候发现异常 resize2fs 1.42.9 (28-Dec-2013) resize2fs: Bad magic number in super-block while trying to open /dev/mapper/centos-root Couldn't find valid filesystem superblock. 经查询资料后得知,不同格式的文件需要使用不同命令。 这个文件是xfs格式的,所以需要使用xfs_growfs命令。 例如: resize2fs /dev/mapper/centos-root 需要修改成 xfs_growfs /dev/mapper/centos-root 重新加载后,再输入df -h即可看到空间已扩展

python将多个文件夹下的内容合并到一个文件夹下

# 原文件夹 old_path = "G:/MP4" # 查看原文件夹下所有的子文件夹 filenames = os.listdir(old_path) # 新文件夹 target_path = "G:/MP5" if not os.path.exists(target_path): os.mkdir(target_path) for file in filenames: # 所有的子文件夹 sonDir = "G:/MP4/" + file # 遍历子文件夹中所有的文件 for root, dirs, files in os.walk(sonDir): # 如果文件夹中有文件 if len(files) > 0: for f in files: newDir = sonDir + '/' + f # 将文件移动到新文件夹中 shutil.move(newDir, target_path) else: print(sonDir + "文件夹是空的") 有个更简单的方法https://blog.csdn.net/qq_42335165/article/details/86218786

vue项目cannot get/的解决办法

启动项目报 cannot get/错误, 一般是项目文件引用路径的问题,或者无意删除了已经被import引入的文件 总之 一般是文件路径的问题。 事实上 当你npm run dev之后,除了看浏览器控制台报什么错,还可以从WebStorm编辑器集成的node控制台查看报错信息。这个控制台一般会报类似这样的错误信息:This relative module was not found:后面会加找不到的文件路径。 搜索一下在哪里引用了这个没找到的文件,基本就能找到问题所在了,有时候修改了问题,可能需要重新npm install一下才生效。

Excel排序

Excel排序 方法一: 1、选择要排序的内容。 2、一定要选自定义排序。 因为单选升序和降序会只对同学中的 ABCD…也就是名单那一行进行升降序,无论你排序选中的区域有多少。 第 1 步: 点击自定义排序后在列(主要关键词)语文,排序依据选数值,次序选降序 这里升序是:从小到大依次排列 例如:123456 这里降序是:从大到小依次排列 例如:654321 我们这里要的单科第一和班级第一,第一名当然是分数越高越好,所以用降序。 点击确定后,会发现语文成绩分数已经是从大到小排列啦!语文成绩第一名是同学 D。 第 2 步:接着我们用刚才教的方法,单击插入列,写上“语文排名” 手动输入 1234567 效果图是这个样子哒! 第 3 步:重复上述步骤对数学、英语进行排名 由上图我们就知道了语文排名第一名是同学 D ;数学排名第一名是同学 E;英语排名第一的是同学 A,那班级排名呢? 想要知道他们的班级排名,就不能看单门成绩啦,要看三门一起,怎么看呢?当然是把单门排名相加呀!看谁的数值越小谁就是第一名呀~ 怎么相加呀?口算吗?当然不用? 第 4 步:这里我们要用到 Excel 一些加减法。 Excel 和 wps 都是自带计算功能的,直接在综合排序同学 A 的单元格输入=号即可,再选择同学 A 语文排名所在的单元+同学 A 数学排名所在的单元格+同学 A 英语排名的所在单元格,相加得出总排名。 这里不需要手动输入,等式出现后,可直接移动光标到对应的单元格,会有颜色出现。接下来,将光标放置到单元格右下角,变成实心的十字架,双击。 第 5 步:重复第三步的操作对综合排序进行排名,注意我们是要第一名,也就数值最小的那个,所以这里要升序。 总结:语文排名第一名是同学 D ;数学排名第一名是同学 E;英语排名第一的是同学 A ,那班级第一是 D 同学哦~你学会了吗? 方法二: 还是这个表格 第一步:用刚才教的插入列的方式,为语文数学和英语综合排序进行排名 刚才的加法你们试过了,是不是非常的简单呢,那有没有什么计算方法可以快速为我们排序呢? 当然有,在使用之前我来介绍一下这个公式: =RANK.EQ(数值,引用,[排位方式]) RANK.EQ:反映某数值在一列数字中相对于其他数值的大小排名;如多个数值的排名相同,则反映该组数值的最佳排名。

pcl 中setCameraPosition的参数说明

开发手册上给出的参数说明如下: void pcl::visualization::PCLVisualizer::setCameraPosition(double pos_x, double pos_y, double pos_z, double view_x, double view_y, double view_z, double up_x, double up_y, double up_z, int viewport = 0 ) Set the camera pose given by position, viewpoint and up vector. Parameters [in]pos_xthe x coordinate of the camera location[in]pos_ythe y coordinate of the camera location[in]pos_zthe z coordinate of the camera location[in]view_xthe x component of the view point of the camera[in]view_ythe y component of the view point of the camera[in]view_zthe z component of the view point of the camera[in]up_xthe x component of the view up direction of the camera[in]up_ythe y component of the view up direction of the camera[in]up_zthe y component of the view up direction of the camera[in]viewportthe viewport to modify camera of (0 modifies all cameras) 但是对于初学者来说,几个方向向量的说明不够清晰,遂对其进一步说明。 该方法参考 vtk Camera中关于vtkCamera::SetPosition()设置方法。

windows10去桌面图标小箭头和恢复小箭头

去小箭头 在桌面新建文本文档,把下面代码复制进去保存,把文件后缀名改为.bat,然后鼠标右键以管理员身份运行就OK了!!! reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f taskkill /f /im explorer.exe attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" del "%userprofile%\AppData\Local\iconcache.db" /f /q start explorer pause 恢复小箭头 操作方法和上面一样 reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /f taskkill /f /im explorer.exe attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" del "%userprofile%\AppData\Local\iconcache.db" /f /q start explorer pause

了解Silverlight应用程序

每个Silverlight应用程序都必须实现Application,说的明白点,就是必须创建一个派生自Application类的应用程序。 我们从最基本的,最初的工作就是找一个入口点。 好比winform应用程序的Main()入口点, 请看下面的一段代码 Code namespace SilverlightPhotos { public partial class App : Application { public App() { this.Startup += this.Application_Startup; this.Exit += this.Application_Exit; this.UnhandledException += this.Application_UnhandledException; InitializeComponent(); } private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new MainPage(); } 上面的程序代码表示SilverlightPhotos命名空间中创建一个名称为App的应用程序,你可以看到这个应用程序派生自Application类。 你可以看到在App()构造方法中,系统为我们添加的三个事件(开始,结束,异常) 。 其中需要注意的是this.Startup += this.Application_Startup;表示处理系统初始启动时要处理的事件,我们可以看到 private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new MainPage();//表示系统启动初始显示的画面 } 这个很有用,因为我们的可以在这里做一些想在系统启动时候的初始化工作。 在我们开发Silverlight应用程序的时候,VS的Silverlight模板会自动为我们创建,其中包括一个App.xaml文件, 一个App.xaml.cs/(xaml.vb)文件.这样我们就可以大量缩减的代码编写量了,请看App.xaml文件 Code <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightPhotos.App" > <Application.Resources>

Visual Studio Code(VSCode)关闭右侧预览功能

如下图所示,当用VSCode打开文本文件时,右侧会出现预览的功能,当内容过多时,容易误操作点击,影响使用,不美观。 关闭方法:点击文件-首选项-设置,搜索"editor.minimap.enabled",默认值为打钩,我们只需要把钩去掉即可;

Oracle sql语句练习

完成如下的SQL语句练习: 每个员工的所有信息 SQL> select * from empscott; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ----------- --------- --------- ------ 7369 SMITH CLERK 7902 1980/12/17 800.00 20 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30 7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30 7566 JONES MANAGER 7839 1981/4/2 2975.00 20 7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30 7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30 7782 CLARK MANAGER 7839 1981/6/9 2450.

1、SQL注入语句之Mysql(1)Basic info

Mysql Basic info version(), @@version, @@global.version -nt-log means window os user(), current_user(), current_user, system_user(), session_user() database(), schema() @@hostname uuid() Last 12digits means mac @@datadir @@tmpdir @@plugin_dir @@version_compile_os @@version_compile_machine select concat(version(),0x7c,user(),0x7c,database()) create database mysqltest; show databases; use mysqltest; create table admin(id int,username varchar(255),password varchar(255)); show tables; insert into admin (id,username,password) values (1,"admin","password"); 列用户 select user,password,host from mysql.user select concat(user,0x7c,password,0x7c,host) from mysql.user version>5.7 password→authentication_string 列库 select schema_name from information_schema.schemata select group_concat(schema_name)from information_schema.

中文词性标注学习笔记(二)---分词

词性标注(二) 分词 词的概念 分词是自然语言处理的基础,分词准确度直接决定了后面的词性标注、句法分析、词向量以及文本分析的质量。英文语句使用空格将单词进行分隔,除了某些特定词,如how many,New York等外,大部分情况下不需要考虑分词问题。但中文不同,天然缺少分隔符,需要读者自行分词和断句。故在做中文自然语言处理时,我们需要先进行分词。 中文分词的三个难点 中文分词不像英文那样,天然有空格作为分隔。而且中文词语组合繁多,分词很容易产生歧义。因此中文分词一直以来都是NLP的一个重点,也是一个难点。难点主要集中在分词标准,切分歧义和未登录词三部分。 1.分词标准 比如人名,有的算法认为姓和名应该分开,有的认为不应该分开。这需要制定一个相对统一的标准。又例如“花草”,有的人认为是一个词,有的人认为应该划分开为两个词“花/草”。某种意义上,中文分词可以说是一个没有明确定义的问题。 2.切分歧义 1.组合型歧义:分词粒度不同导致的不同切分结果。比如“中华人民共和国”,粗粒度的分词结果为“中华人民共和国”,细粒度的分词结果为“中华/人民/共和国”。这种问题需.用场景来选择。 2.交集型歧义:不同切分结果共用相同的字,前后组合的不同导致不同的切分结果。比如“商务处女干事”,可以划分为“商务处/女干事”,也可以划分为“商务/处女/干事”。这也需要通过整句话来区分。 3.真歧义:本身语法或语义没有问题,即使人工切分也会产生歧义。比如“下雨天留客天天留人不留”,可以划分为“下雨天/留客天/天留/人不留”,也可以划分为“下雨天/留客天/天留人不/留”。此时通过整句话还没法切分,只能通过上下文语境来进行切分。如果是不想留客,则切分为前一个。否则切分为后一个。 3.未登录词 也叫新词发现,或者生词,未被词典收录的词。 中文分词算法 当前的分词算法主要分为两类,基于词典的规则匹配方法,和基于统计的机器学习方法。 基于词典的分词算法 基于词典的分词算法,本质上就是字符串匹配。将待匹配的字符串基于一定的算法策略,和一个足够大的词典进行字符串匹配,如果匹配命中,则可以分词。根据不同的匹配策略,又分为正向最大匹配法,逆向最大匹配法,双向匹配分词,全切分路径选择等。 基于统计的分词算法 本质上是一个序列标注问题。我们将语句中的字,按照他们在词中的位置进行标注。标注主要有:B(词开始的一个字),E(词最后一个字),M(词中间的字,可能多个),S(一个字表示的词)。例如“网商银行是蚂蚁金服微贷事业部的最重要产品”,标注后结果为“BMMESBMMEBMMMESBMEBE”,对应的分词结果为“网商银行/是/蚂蚁金服/微贷事业部/的/最重要/产品”。 这类算法基于机器学习或者现在火热的深度学习,主要有HMM,CRF,SVM,以及深度学习等。 总结 中文分词是中文自然语言处理中的一个重要环节,为后面的词向量编码,词性标注,句法分析以及文本分析打下了坚实的基础。同时,由于中文缺少空格等分隔符,并且汉字间的组合特别多,很容易产生歧义,这些都加大了中文分词的难度。基于词典的字符串匹配算法和基于统计的分词算法,二者各有优缺点,我们可以考虑结合使用。 相关学习连接 http://ssvideo.superlib.com/cxvideo/play/page?sid=1586&vid=28434&d=77edee6d216507e5ece667cef95799ea&cid=236 https://blog.csdn.net/u013510838/article/details/81673016

云原生微服务框架——Helidon

在互联网早期的相当长一段时间内,WEB应用都是”单体应用(monolithic)“。也就是说所有的API和前端展示层代码都被封装在一个独立的、自给自足的应用当中。业务逻辑,校验,数据获取及计算,持久化,安全,UI都封装成一个大的包,部署在应用服务器或者web服务器上,比如说Tomcat, Apache或者Microsoft IIS。这个方法过去有效,未来也仍将有效,只不过当你的应用到达一定规模之后,就会面临诸多挑战: 部署:对于单体应用来说,checkout源代码,编译,测试,打包和部署这些都需要花费相当长的时间。依赖关系,框架及开发语言:整个应用都和具体的选型和版本强绑定,一旦这些基础框架发布了新的版本,升级会非常困难。单点故障:单体应用非常脆弱,如果web服务器挂了,整个应用也就挂了。扩展性:哪怕只是应用程序其中的某一部分引发的负载升高,也必须对整个应用来进行扩容。 当然还会碰到其它问题,但这些就已经够让开发人员、项目经理、运维人员头疼的了。长久以来,大家不得不去处理这些事情。 部署:每个服务都可以单独地测试、编译及部署。依赖关系、框架及开发语言:每个服务都可以使用自己所需要的开发语言、框架、依赖及不同的版本。单点故障:每个服务都部署在容器里并使用编排工具来管理,单点宕机会被隔离掉,不会影响到整个应用。扩展性:服务可以独立进行扩展,高负载的服务扩容,低负载的服务缩容。 微服务并不是万能的,但在许多场景下还是非常有用的。我们已经介绍了“为什么”需要微服务,现在来介绍下”如何“实现微服务。 目前市面上已经有不少微服务框架了,再造一个新的似乎没这个必要,不过Oracle还真就这么做了,这个项目便是Helidon。光看项目名字你可能就知道Oracle为什么要创建这个项目了:Helidon在希腊语中是燕子的意思——一种小巧、灵活的鸟类,它们天然就适合在云端翱翔。因此,这个项目的发起人应该是想开发出一款无需应用服务器且能被用于Java SE应用的轻量级框架。 Helidon有两种版本:SE和MP。Helidon SE算是一个微框架(microframework),比较简单、轻量,采用了函数式编程、响应式编程的思想,运行在自带的Netty web服务器上。它比较类似于Javalin、Micronaut或者Spark Java这样的框架。而Helidon MP实现了MicroProfile的规范,采用了Java EE/Jakarta EE开发人员所熟知的注解和组件的技术,比如说JAX-RS/Jersey, JSON-P以及CDI。它和Open Liberty, Payara还有Thorntail (正式名称是 WildFly Swarm)的定位差不多。我们先从Helidon SE开始,来了解一下这个框架。 Helidon SE入门 新工具的学习就是在摸着石头过河,不过Helidon不存在这个问题。只需要安装一些必要的依赖软件(JDK 8+,Maven 3.5+)就可以开始使用了。使用Docker或者Kubernetes的话,能让容器的创建和部署更加容易。那还需要安装Docker 18.02或更新的版本,以及Kubernetes 1.7.4+。(可以使用Minikube或Docket Desktop在桌面操作系统上运行你的Kubernetes集群)。 确认下软件的版本: $ java --version $ mvn --version $ docker --version $ kubectl version --short 一旦安装完成,便能够通过Helidon提供的Maven项目模板(原型,Archetype)来快速生成一个工程。可能你对Maven Archetype还不太了解,它其实就是一些项目模板,可以用来搭建某个框架的启动工程以便快速使用。Oracle提供了两套项目模板:Helidon SE和Helidon MP各一个。 mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=io.helidon.archetypes \ -DarchetypeArtifactId=helidon-quickstart-se \ -DarchetypeVersion=0.10.2 \ -DgroupId=[io.helidon.examples] \ -DartifactId=[quickstart-se] \ -Dpackage=[io.helidon.examples.quickstart.se] 项目模板在Maven的中央仓库中,在这里你可以找到最新发布的版本。前面方括号内的值是和具体项目相关的,可以根据你的需要来进行编辑。本文中的示例将使用下面的命令来创建完成: $ mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=io.

Redis服务器的请求处理流程

Redis一般是单进程单线程与多个客户端进行连接的。 会有一个Client表(是一个链表),保存与其连接的客户端的 1. 套接字描述符 2. 名字 3 正在使用的数据库指针、号码 4 当前执行的命令 5 当前事务状态 6 输入缓存区与输出缓存区 7 执行时所需要的各种数据结构 当一个命令传入Redis,将会有: 1 客户端发送请求,转移成协议格式。 2 放入输入缓冲区,调用命令执行器。 3 查找命令并执行,进行后续工作(慢查询、AOF) 4 回送客户端并打印请求

Git:移除文件----git rm命令的使用

文章目录 一、git rm 命令使用1.1 rm 命令1.2 git rm 命令1.3 git rm -f 命令1.4 git rm --cached 命令 一、git rm 命令使用 Git 本地数据管理,大概可以分为三个区: 工作区(Working Directory):是可以直接编辑的地方。暂存区(Stage/Index):数据暂时存放的区域。版本库(commit History):存放已经提交的数据。 工作区的文件 git add 后到暂存区,暂存区的文件 git commit 后到版本库。 1.1 rm 命令 1. 作用: 删除工作区的文件。 执行删除命令: $ rm test.txt 查看状态(成功删除工作区文件): $ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: test.

俄罗斯 搜索引擎 邮箱创建

https://yandex.com/https://mail.yandex.com/ 邮箱不需要绑定手机号,未被屏蔽 邮箱注册可以不填写手机号码,验证码刷新一个简单的从左到右填

远程开发利器:Pycharm中使用远程Jupyter Notebook:

在远程服务器上做开发时,如本人在远程gpu服务器进行深度学习,如果在本地开发环境下开发可能会存在问题,需要保证本地开发环境与远程服务器一致。本地编辑好的程序也要拷贝到服务器。可以通过以下的几种方式直接在远程服务器环境下做开发。 1、pycham远程配置 主要需要配置以下两个 本地文件与远程文件关联,也就是实现与远程服务器互联,在本地开发完成的文件可以一键传到远程服务器,远程服务器的文件也可一键拉过来。或者设置自动实时同步也是可以的本地pycharm使用远程服务器的Python Interpreter 具体配置过程参照此博客,网上很多教程这里不多说了,注意只有专业版才有远程的功能。 2、远程Jupyter Notebook Jupyter Notebook默认只能在本地调用,远程调用需要修改其配置文件, 1)为避免不必要的报错,在配置前最好使用以下命令把远程服务器的Jupyter Notebook升到最新版。 pip install -U jupyter 2)生成配置文件, jupyter notebook --generate-config root用户下需要加参数--allow-root 执行上面的命令 jupyter notebook --generate-config --allow-root 3)设置远程登陆Jupyter Notebook的密码 执行以下命令输入密码即可 jupyter notebook password 补充: 后续使用中 发现使用命令行生成密码总是报错,也可以不使用命令行,直接修改配置文件也可以设置密码。 将下面行改为你的密码即可。 #c.NotebookApp.token = '<generated>' 如密码设置为QQQ,注意记得去掉注释#号。 c.NotebookApp.token = 'QQQ' 4)修改配置文件 编辑Jupyter Notebook的配置文件 vim ~/.jupyter/jupyter_notebook_config.py 取消掉以下行的注释,并修改成以下内容 c.NotebookApp.ip = '*' c.NotebookApp.port = '8888' c.NotebookApp.open_brower = False 至此,远程Jupyter Notebook配置完成,其他电脑浏览器打开输入密码即可使用 3、在pycharm中使用远程的Jupyter Notebook Jupyter Notebook优点很多,但之前一直不用的原因在于jupyter没有代码提示,错误提示。对于新人不友好,并且颜值不高。 可以在Pycharm中使用远程的Jupyter Notebook。享受Jupyter Notebook优点的同时,还能享受Pycharm自动补全等等的功能。 在说配置过程之前,先说配置过程踩过的坑。供大家参考 在pycharm中新建Jupyter Notebook文件,点击run cell时,会提示让你配置server。也就是让你填写http://x.

async 与 await 的用法详解

文章出自个人博客https://knightyun.github.io/2019/08/02/js-async-await,转载请申明 async 概念 用于声明异步函数,返回值为一个 Promise 对象,它以类似 同步 的方式来写异步方法,语法与声明函数类似,例如: async function fn() { console.log('Hello world!'); } console.log(fn().constructor); // Promise() // 这里证明其返回值为一个 Promise 对象; 返回值 也许这里会有疑问,返回值是 Promise 对象,那么函数本身定义的返回值跑到哪里去了呢?其实,熟悉 Promise 的就知道其异步结果是通过 .then() 或者 .catch() 方法来获取并进行进一步处理的,这样一个道理,定义的异步函数中的返回值会当成 resolve 状态来处理,一般用 .then() 方法处理,而如果定义的异步函数抛出错误,例如变量未定义,则会被当做 reject 状态来处理,一般使用 .catch() 方法来处理; 举例: // 使用 .then() 的情况 async function fn1() { return 'Hello world!'; } fn1().then(function(res) { console.log(res); }); // Hello world! // 使用 .catch() 的情况 async function fn2() { console.log(aaa); // 这里的变量 aaa 未定义,为了制造错误 } fn2().

tar中的参数 cvf,xvf,cvzf,zxvf的区别

tar cvf etcbak.tar etc/ 打包一个tar tar xvf etcbak.tar 解开一个tar tar cvzf etcbak.tar.gz etc/ 打包压缩一个 tar tar zxvf etcbak.tar.gz 解压一个tar z:代表的是压缩 c:代表的是打包 x:代表的是解压 v:代表的是过程 f:代表的是指定文件名 因此zcvf : 打包压缩 例如: (tar -zcvf xxx.tar.gz aaa.txt bbb.txt ccc.txt) 把aaa.txt bbb.txt ccc.txt打包压缩为一个名叫xxx.tar.gz 压缩包 xvf: 解压缩 例如(tar -xvf xxx.tar.gz -C/usr) -C代表解压的位置 把xxx.tar.gz解压缩到根目录下的usr目录 转载于:https://www.cnblogs.com/clemente/p/11288966.html

nginx——实现https加密以及重定向

一.实现https加密 我们知道现在到了 https 的时代了,每个优秀的网站几乎都已经开启 https。开启了 https 加密访问之后,登录你的网站,浏览器地址栏就会出现一把绿色的锁,这就是使用了超文本传输安全协议(HTTPS),是以安全为目标的HTTP通道,简单来说就是HTTP安全版。 https由两个部分组成:HTTP+SSL/TLS,在http基础上加上了一层加密信息模块,服务端和客户端的信息插损胡都会通过TLS进行加密,传输的数据都是加密后的数据 为了解决HTTP协议的这些缺陷,需要使用另一种协议:HTTPS。为了数据传输的安全性,HTTPS在http的基础上加了SSL协议,SSL依靠证书验证身份,并为浏览器和服务器之间通信加密; SSL证书是一种数字证书,使用Secure Socket Layer协议在浏览器和web服务器之间建立一条安全通道,从而实现数据信息在客户端和服务器之间的加密传输,保证双方传递信息的安全性,不可被第三方窃听,而且用户可以通过服务器证书验证所访问网站是否真实可靠; 加密的HTTPS和HTTP的区别: 超文本传输协议HTTP协议被用于在web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的加密数据,如果攻击者截取了web浏览器和网站服务器之间的传输报文,就可以直接读取其中信息,因此,http协议不适合传输一些敏感信息; 实验如下所示: 第一步:1.关闭nginx服务,并重新编译(主要是为了添加ssl模块) [root@nodel1 conf]# systemctl stop nginx [root@nodel1 conf]# cd /mnt [root@nodel1 mnt]# ls [root@nodel1 mnt]# cd nginx-1.17.1/ [root@nodel1 nginx-1.17.1]# make clean [root@nodel1 nginx-1.17.1]# yum install openssl-devel -y #编译过程使用加密的时候,需要安装这个 [root@nodel1 nginx-1.17.1]# ./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_image_filter_module=dynamic --with-http_ssl_module [root@nodel1 nginx-1.17.1]# make 替代之前的二进制文件并再次将图像模块放入modules目录下 [root@nodel1 nginx-1.17.1]# cd objs/ [root@nodel1 objs]# cp nginx -f /usr/local/nginx/sbin/nginx [root@nodel1 objs]# ls [root@nodel1 objs]# cp ngx_http_image_filter_module.

Mysql安装与操作

一、安装mysql 1、CentOS系统 1.)安装mysql 下载并安装mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm $ sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm 安装mysql $ sudo yum install -y mysql-server 2.)启动/重启/关闭服务 service mysqld start | restart | stop 2、alpine系统 alpine系统中安装mysql实际是开源的MariaDB,MariaDB数据库是MySQL的一个分支/衍生版,完全兼容MySQL,并在扩展功能、存储引擎以及一些新的功能改进方面都强过MySQL,安装参考 $ apk update 安装数据库及客户端 $ apk add mysql mysql-client 初始化数据库 $ mysql_install_db --user=mysql --datadir=/var/lib/mysql 启动服务 $ rc-service mariadb start # 若没有rc,安装:apk add openrc 修改密码 $ mysqladmin -u root password “新root密码” 加入开机启动 $ rc-update add mariadb default 二、操作mysql 1、登录数据库 默认初始化直接登录 $ mysql

数据分析基础——R语言(处理缺失值)

进行简单的数据处理时,我们处理的基本都是完整的数据集,但是实际问题中我们经常会遇到带有缺失值的数据,处理此类数据也就显得尤为重要。 处理缺失值的一般步骤 首先我们列出处理缺失值的一般步骤,对整个流程有一个大致的了解。 识别缺失数据;检查导致数据缺失的原因;删除包含缺失值的实例或用合理的数值插补缺失值。 数据缺失的种类 完全随机缺失(MCAR)随机缺失(MAR)非随机缺失(NMAR) 完全随机缺失:若某变量的缺失数据与其他任何观测和未观测变量都不相关,则数据为完全随机缺失。 随机缺失:若某变量上的缺失数据与其他观测变量相关,与他自己的未观测值不相关,则数据为随机缺失。 非随机缺失:若缺失数据不属于上两种则是非随机缺失。 识别缺失值 要想处理缺失值,首先我们就要去识别出来哪些数据是缺失值,R语言中,NA代表缺失值,NaN代表不可能的值,Inf和-Inf代表的是正无穷和负无穷。有对应的函数is.na()、is.nan()、is.infinite()可以分别用来识别缺失值,不可能值以及无穷值,返回的结果是TRUE/FALSE。 要想统计缺失值的个数,我们可以直接通过sum()函数来对TRUE/FALSE进行统计,其中TRUE的逻辑值是1,FALSE的逻辑值为0,同样不可能的值以及无穷值也可以用此方法进行判断。 探究缺失值 对于缺失值,我们只统计他的个数是不可取的,本节中给出探究缺失值的几种方法。 一、图表显示缺失值 我们可以用一个图标的形式去展示缺失值,在R语言中mice包中的md.pttern()函数提供了一个可以生成矩阵来显示缺失值的表格,示例如下: library(lattice) library(mice) data(sleep,package="VIM") md.pattern(sleep) 得到的图表结果以及图形结果如下: 二、图形展示缺失值 md.pattren()函数已经给我们清晰的列出了每一项的缺失值,但是图形时一种更能够清晰的表达缺失值的一种方法,VIM包中提供了大量的可视化函数,我们来学习一下其中的一些函数。 aggr()函数 library(VIM) aggr(sleep,prop=FALSE,numbers=TRUE) matrixplot()函数 matrixplot() marginplot()函数 marginplot(sleep[c("Gest","Dream")],pch=c(20),col=c("darkgray","red","blue")) 缺失值的处理 一、删除 对于缺失值的处理首先我们先采用第一种最简单的方法——删除缺失值所在的行,R语言中提供了两种删除缺失值的函数,分别是complete.cases()函数和na.omit()函数。 对于删除的处理直接对数据进行使用即可,这里不做演示。 二、多重插补法 多重插补(MI)是一种基于重复模拟的处理缺失值的方法,在面对复杂的缺失值问题时,MI是常选用的方法,它将从一个包含缺失值的数据集中生成一组完整的数据集。本节中我们将使用R中的mice包对数据集进行插补。 mice包中多重插补法的工作流程如下: 基于mice包的分析通常要符合以下的过程: library(mice) imp <- mice(mydata,m) fit <- with(imp, analysis) pooled <- pool(fit) summary(pooled) 过程说明: mydata是一个包含缺失值的矩阵或数据框imp是一个包含m个插补数据集的列表对象,同时还含有完成插补过程的信息。默认的m的值为5。analysis是一个表达式对象,用来设定应用于m个插补数据集的统计分析方法。fit是一个包含m个单独统计分析结果的列表对象。pooled是一个包含这m个统计平均分析结果的列表对象。 三、简单插补法 简单插补法,即用某个值(如均值、中位数、众数)来替换变量中的缺失值。注意的一点是,这些替换是随机的,这也就意味着不会引入随机误差。 四、处理缺失值的其他方法 R语言支持其他一些缺失值的处理方法。 软件包描述Hmisc包含多种函数,支持简单插补、多重插补和典型变量插补。mvnmle对多元正太分布数据中缺失值的最大似然估计。cat对线性模型中多元类别型变量的多重插补。arrayInpute、Seqknn处理微阵列缺失数据的实时函数。longitudinalData相关的函数列表,比如对时间序列缺失值进行插补的一系列函数。kmi处理生存分析缺失值的Kaplan-Meier多重插补。mix一般位置模型中混合类别型和连续型数据的多重插补。pan多元面板数据或聚类数据的多重插补。

ajax方法参数详解

jquery中的ajax方法参数总是记不住,这里记录一下。 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。 2.type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。 3.timeout: 要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。 4.async: 要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。 5.cache: 要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。 6.data: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。 7.dataType: 要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下: xml:返回XML文档,可用JQuery处理。 html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。 script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。 json:返回JSON数据。 jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。 text:返回纯文本字符串。 8.beforeSend: 要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。 function(XMLHttpRequest){ this; //调用本次ajax请求时传递的options参数 } 9.complete: 要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。 function(XMLHttpRequest, textStatus){ this; //调用本次ajax请求时传递的options参数 } 10.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。 (1)由服务器返回,并根据dataType参数进行处理后的数据。 (2)描述状态的字符串。 function(data, textStatus){ //data可能是xmlDoc、jsonObj、html、text等等 this; //调用本次ajax请求时传递的options参数 } 11.error: 要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下: function(XMLHttpRequest, textStatus, errorThrown){ //通常情况下textStatus和errorThrown只有其中一个包含信息 this; //调用本次ajax请求时传递的options参数 } 12.contentType: 要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。 13.dataFilter: 要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。 function(data, type){ //返回处理后的数据 return data; } 14.dataFilter: 要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。 function(data, type){ //返回处理后的数据 return data;

Git:远程分支----git fetch命令的使用

git fetch 命令的使用 从远程主机克隆 Git 的 clone 命令会为你自动将远程主机命名为 origin,拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master。同时Git 也会给你一个与 origin 的master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础。 本地有提交,远程也有别人的推送 远程库有人推送,提交了C0和C1: 本地提交了D0和D1: 只要你不与 origin 服务器连接,你的 origin/master 指针就不会移动。 同步 如果要同步远程库到你的工作,运行 git fetch origin 命令。 $ git fetch origin 这个命令查找 “origin” 是哪一个服务器,从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master 指针指向新的、更新后的位置。 要特别注意的一点是 fetch 抓取到新的远程跟踪分支时,本地的工作区(workspace)不会自动生成一份可编辑的副本,抓取结果是直接送到版本库(Repository)中。如下图: 打个比方,在远程库 origin 新建了一个分支 dev,git fetch 后本地不会生成一个新的分支 dev(可用 git branch 查看),只有一个不可以修改的 origin/dev 指针。 在 origin/master 后继续工作 如果想要在 origin/master 分支上工作,可以新建分支 test 并将其建立在远程跟踪分支之上: $ git checkout -b test origin/master 这会给你新建一个用于工作的本地分支 test,并且起点位于 origin/master。

vue 路由跳转返回上一级

两种方案: 1、 this.$router.go(-1) 2、this.$router.push('/xxx') 最常用 或者this.$router.push({name:'xxx'})对象的方法 分析两种方案,方案一,返回的是上一级,从哪来回哪去;方案二则是可以指定路由,个人经验,谨慎用方案一

MT7628移植移远EC20驱动实现4G上网功能(绝大多数使用openwrt的设备通用)

我的上一篇文章中完成对MT7628固件的编译,本文是在固件编译通过的基础上移植EC20驱动的,固件编译问题请参考上文。 在讲解之前先介绍移远的EC20模块,该模块是目前较为成熟的4G模块,可向安装了Windows、Linux等设备的机器提供4G上网服务,移远同类产品中还有AG35模块,这个模块我之前在AM4378上移植过,当时花费了好多时间才移植成功,其实移远产品做得也不错,同类的模块移植方法基本是一样的。 废话不多说,下面开始讲述EC20驱动在MT7628上的移植过程。 第一步: 修改源码(注意:固件必须要先编译过一轮,否则没有build_dir目录)。此步骤必须细心修改,并认真核对。以下路径中的源文件均需要修改才能使用: /home/user/openwrt-sdk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/usb/serial/option.c //大概在532行,添加如下代码 ...... static const struct usb_device_id option_ids[] = { #if 1 //Added by Quectel { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */ #endif { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, .