平衡各方利益的模型才是最好模型
—Toby!2022 07 07
各位朋友大家好,我是Toby老师。之前有很多风控朋友咨询如何搭建风控模型。今天我抛砖引玉为大家讲述金融风控模型开发SOP(标准操作流程),供大家参考。
一.SOP标准操作流程
SOP,是 Standard Operating Procedure三个单词中首字母的大写 ,即标准作业程序,指将某一事件的标准操作步骤和要求以统一的格式描述出来,用于指导和规范日常的工作。SOP的精髓是将细节进行量化,通俗来讲,SOP就是对某一程序中的关键控制点进行细化和量化。实际执行过程中sop核心是符合本企业并可执行,不流于形式。
模型开发SOP
模型开发sop即指“模型开发标准操作程序”,将开发过程统一为标准操作步骤和要求,用来指引模型开发日常的工作。
模型开发并非易事,需要平衡业务方,模型开发方,验证方,领导层等多方面需求。不同部门需求有可能发生冲突,因此模型开发需要照顾各方利益,平衡取舍。模型开发并非完全尊从教科书理论,真实大数据是不干净的,无法完美满足教科书上各条理论。
模型开发尽可能做到模型较高准确性,较高区分能力,分数稳定,合理、维度合适。
模型开发SOP重要性
(1)标准化,流程化重复工作,提高建模效率和质量
(2)便于模型验证和维护
二.模型开发立项需求
业务方或策略方(政策部)发起需求,确定模型开发方原因,使用场景,模型性能要求。
比如,A卡贷前审批模型主要是为了评估贷前用户的违约概率;B卡用于预测用户贷后违约概率;C卡用于催收。反欺诈模型预测黑产,灰产用户骗贷、薅羊毛行为;资本计量模型主要适用于 Basel 体系确定最低资本要求和进行压力测试。
模型立项可以通过邮件和会议形式确立,必要时做好会议纪要。
三.模型开发具体环节
是建模工作的主要过程,包括SQL取数、数据清洗、数据探索,变量筛选、模型建立、模型选择,模型验证,模型部署,线上验证,模型监控和模型迭代。)
1.SQL取数:
SQL取数是根据业务方需求,关联若干表单,提取模型需要数据。公司数据量越大,基层表单越混乱,此步骤会越耗时,SQL语句可能从几十行到几千行不等,需要熟悉公司数据库和表单逻辑。新手写的SQL语句还容易产生跑数据耗时,卡死服务器等问题。大多数金融公司数据分析师和模型开发人员职责是重合的,这样建模效率并不高。模型质量难以提升。理想状态是一个模型开发人员搭配一个数据分析师。数据分析师负责取数和提供描述性统计。模型开发人员精力集中在提升模型性能和控制模型维度。
2.数据清洗:
数据清洗主要是对不能直接入模的数据做清洗处理,比如类型不对数据,不合理异常值,缺失值,怪异字符串等等。入模数据必须是结构化数据,否则训练模型时会报错。对于类别变量,可以用one-hot编码。但one-hot编码消耗内存,产生高维度变量。逻辑回归建模时推荐WOE编码方法。对于新一代集成树算法catboost,可以直接申明类别变量,然后自动处理。
3.数据探索
EDA探索性数据分析和描述性统计,包括统计总体数据量大小,好坏客户占比,数据类型有哪些,变量缺失率,变量频率分析直方图可视化,箱形图可视化,变量相关性可视化等。
4.变量筛选:
从原始数据中筛选出重要变量,踢除噪音变量,相关性高变量。
常见的特征选择方法:
IV information value(信息价值),常用于逻辑回归模型Information gain(信息增益),常用于决策树模型Correlation coefficient scores(相关系数),通用所有模型missing value (缺失率),删除缺失率接近1的变量unique value(唯一值),删除唯一值占比接近1的变量shap value,删除shap值接近0的变量 5.模型建立:
模型建立就是用清洗后数据,通过机器学习算法建立模型。给模型喂养数据,训练数据,最终让模型生成预测能力,批量预测客户违约率。
6.模型选择:
根据业务方需求,通过多算法比较,择优选择综合性能最佳模型。
一般而言,金融风控领域模型看重AUC,ks,accuracy,psi等指标,混淆矩阵等其他指标也要附带参考。不同模型指标代表不同意义。
7.模型验证:
模型开发过程不可或缺的一部分。它有助于发现表达数据的最佳模型和所选模型将来工作的性能如何。
模型验证分为三个环节,模型开发部门首先内部评估模型质量是否合格,如果没问题会发生第三方模型验证团队。第三方模型验证团队必须保证独立性,验证过程不受模型开发团队干扰,避免既当裁判又当球员的作弊行为。第三方模型验证团队可以是外包公司,也可以是公司内部团队。如果担心数据泄露,优先推荐公司内部团队独立验证。最后模型验证报告会提交给各个团队领导审批。如果领导认为模型质量有问题,会邮件批注或驳回模型。
模型评估的常见的五个⽅法:
混淆矩阵lift提升图&洛伦兹图基尼系数ks曲线roc曲线psi模型稳定性 由于人员编制不稳定,部分项目相关同事会离职。因此模型验证完后需要存档,包括模型资料保存。存档中要完整记录验证人员,开发人员,业务方人员,开发时间,模型性能,模型缺陷等内容,以便后续人员查阅和维护。
8.模型部署
通过模型验证后,配置好模型的包,文档说明,变量表,准备线上部署。
9、线上线下验证
完成模型线上部署后,进行模型的线上线下部署验证。主要测试线上模型分和线下模型分是否一致。如果线上线下模型分不一致需要找出原因。一般情况下维度高的模型容易发生线上线下分数不一致,因此保留合适模型维度有利于模型上线后维护。常见引起线上线下分数不一致原因有模型包材料有问题,变量漏写,变量多写,硬盘传输速度慢造成丢包等等。
10、模型监控
完成模型的部署和线上验证后,对模型进行各维度的监控,确定是否迭代,形成模型工作闭环。
模型监控需要每日生成报表,邮件发送相关同事查阅。对于数据量大的金融公司,需要整合大量表,模型监控并不是容易的事。
11.模型迭代
如果监控模型ks,AUC,psi等指标变化太大,需要重新迭代模型
备注:上述模型开发sop只是为大家提供一个参考模板,由于各条业务方差异,不能满足所有场景。希望大家因地制宜,建好最适合自己公司的模型开发sop。
如果大家对金融风控建模感兴趣,可了解《python金融风控评分卡模型和数据分析(加强版)》
如果有论文作业一对一辅导的,还可以与作者联系。
版权声明:文章来自公众号(python风控模型),未经许可,不得抄袭。遵循CC 4.
eFuse是熔丝性的一种器件,而OTP是反熔丝的一种器件。就是说,当OTP存储单元未击穿时,它的逻辑状态为0;当击穿时,它的逻辑状态为1。
它的物理状态和逻辑状态正好和eFuse是反着的。简单来讲,就是初始它物理上是断路,没有电流通路的;而烧写后,它才变成了通路,有一个电流通路。
OTP真值表
OTP的应用场景和eFuse基本上一致,都用来存储TRIM值或者Root Key或者特定ID等关键信息。
但是有两点需要说明:
1、从成本上讲,eFuse器件基本上是各个Foundry厂自己提供,因此通常意味着免费或者很少的费用,而OTP器件则通常是第三方IP厂家提供,这就要收费。
2、从器件面积上讲,eFuse的cell的面积更大,所以仅仅有小容量的器件可以考虑。当然如果需要大容量的,也可以多个eFuse Macro拼接,但是这意味着芯片面积的增加,成本也会增加;OTP的cell面积很小,所有相对来讲,可以提供更大容量的Macro可供使用。
另外:OTP 比 eFuse 安全性更好,eFuse的编程位可以通过电子显微镜看到,因此其存储的内容可以被轻易破解,但OTP在显微镜下无法区分编程位和未编程位,因此无法读取数据。eFuse默认导通,存储的是"1",而OTP默认是断开,存储的是"0",因此OTP的功耗也较eFuse小,面积也较eFuse小。
参考:All is About SOC - SOC中的非易失性NVM器件(五)之OTP (baidu.com)
NVM, PROM, OTP, eFuse傻傻分不清楚_magicse7en的博客-CSDN博客_nvm和eeprom的区别
目的:node express上使用canvas进行图像处理并返回的接口,部署宝塔使用
环境&版本:
"canvas": "^2.9.3", CentOS 7.9 宝塔Linux面板-qP7W node v16.16.0 下载的是canvas-v2.9.3-node-v93-linux-glibc-x64.tar.gz node-canvas git地址GitHub - Automattic/node-canvas: Node canvas is a Cairo backed Canvas implementation for NodeJS.
事情是这样的:
在win调试的canvas库是可以运行的,但是在centos上运行出现canvas.node: invalid ELF header的错误,看依赖文件可知本地调试的库只支持win系统
node_modules/canvas/build/Release/canvas.node: invalid ELF header · Issue #1000 · Automattic/node-canvas · GitHub
按道理讲在linux上npm i会下载对应环境的依赖包,但是该包本身npm完全连接不上,使用cnpm才行,但是问题是宝塔面板上安装cnpm失败,于是只能看别的想法
阅读官方文档发现本身包是支持不同环境编译的,但是也遇到了很多问题这里不细说,参考了以下文章,node-canvas模块安装使用过程中报错的解决方法_星哥如是说的博客-CSDN博客_canvas模块
正文 报错1canvas.node: invalid ELF header 报错是依赖包是win或者别的,在linux上不能用
为了在不同平台上使用canvas,官方文档本身提供不同平台的构建方法但是复杂,这里可以直接使用解析好的包进行替换(最便捷的办法了,别的都一堆问题)
下载如下的canvas-v2.9.3-node-v93-linux-glibc-x64.tar.gz
全版本在里面找qqReleases · Automattic/node-canvas · GitHub
先cnpm在本地安装依赖,找到对应版本的linux包替换canvas依赖中node_modules\canvas\build\Release文件
ps:按道理讲这里版本和库的依赖环境对了就没有问题了,以下是我遇到的问题和解决办法而且不知其所以然,出现的问题仅供参考
此时的依赖包是没问题的,上传服务器发现还是有如下报错
报错2/lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /home/username/server/node_modules/canvas/build/Release/canvas.node) git上问题讨论为https://github.com/Automattic/node-canvas/issues/1796
天气实战 第一步 第一步,注册和风天气控制台 | 和风天气,申请key
08f828b5a3ec4905a29156bf5f29136f
查看郭林的后台天气pai接口
http://guolin.tech/api/china
第二步,建立省市县实体类 /** * Description * <p> * id是每个实体该有的字段 * provinceName记录省的名字 * provinceCode记录省的代号 * @author qricis on 2020/9/3 14:47 * @version 1.0.0 */ public class Province extends DataSupport { private int id; private String provinceName; private int provinceCode; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getProvinceName() { return provinceName; } public void setProvinceName(String provinceName) { this.
一、
创建文件夹
#切换到文件夹 [root@localhost /]# cd /usr/local/ #创建文件夹 [root@localhost local]# mkdir elasticsearch #显示文件 [root@localhost local]# ls #进入文件夹 [root@localhost local]# cd elasticsearch/ #下载文件 [root@localhost elasticsearch]# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.3.1-linux-x86_64.tar.gz #解压文件 [root@localhost elasticsearch]# tar -zxvf elasticsearch-8.3.1-linux-x86_64.tar.gz #显示文件 [root@localhost elasticsearch]# ls elasticsearch-8.3.1 elasticsearch-8.3.1-linux-x86_64.tar.gz [root@localhost elasticsearch]# cd elasticsearch-8.3.1/ [root@localhost elasticsearch-8.3.1]# ls bin config jdk lib LICENSE.txt logs modules NOTICE.txt plugins README.asciidoc [root@localhost elasticsearch-8.3.1]# cd bin / #启动 [root@localhost bin]# ./elasticsearch -d elaticsearch默认不能用root用户启动,所以会报java.lang.RuntimeException: can not run elasticsearch as root异常。
Hadoop云盘项目总结 0. 项目介绍 介绍视频:
基于Hadoop搭建HA高可用网盘系统
视频地址: B站 搭建过程: 我的搭建过程 小组成员的搭建过程 项目地址待完善后会发出来 技术栈:HDFS、Sqoop、Flume、Ganglia、Azkaban、Zookeeper、Redis、Nginx、Docker、Vue-Cli **实现功能:**使用 Hadoop 搭建 HA 集群实现网盘系统,前端采用 vue-cli,后端采用 SpringBoot。实现的功能有:用户上 传下载文件;通过 MapReduce 清洗、挖掘、分析用户数据并生成报表;通过 Ganglia 监控集群状态;使用 Azkaban 进行定时调度;使用 Java ForkJoin 框架搭建 RSS 高性能爬虫,通过布隆过滤器过滤重复信息
项目难点:
由于项目在公网上搭建,项目前期对 Hadoop 集群各种通信端口不够熟悉,导致集群通信失败用户上传相同文件时会出现重复上传现象。通过布隆过滤器过滤相同文件,通过构建用户文档树映射用户路径 和真实路径,将相同文件移至共享文件区,用户上传和删除行为仅做逻辑实现,不做业务实现集群中数据清洗、挖掘、分析的 MR 任务过多,难以控制。通过引入 Azkaban 统一管理集群中的 Flume、Sqoop 和 MR 任务,并进行定时调度 贴一张集群拓扑图:
在线地址(租用的四台云服务器,已经退了,不用访问了):
https://kdocs.cn/l/cod7zXmDPz98
1. 循环引用导致无意识的递归(java.lang.StackOverflowError)问题 问题描述:在构建用户文档树的时候,采取链表双向指针的方式,分别指向上一个和下一个结点,导致无意识的循环引用,然后报StackOverflowError
问题产生原因:在Java中的每个类从根本上都是继承自Object,标准容器类自然也不例外,因此容器类都有toString()方法,并且重写了该方法,使得它生成的String结果能够表达容器本身,以及容器所包含的对象.例如ArrayList.toString(),它会遍历ArrayList中包含的所有对象,调用没个元素的toString()方法。而我的集合类本身会循环引用,最终导致无限递归
**解决方法:**将集合类由继承改为组合,内部维护一个List;修改双向引用为单向,仅指向下一个结点,将根结点保存在用户的属性中,结点的遍历从根结点开始;重写集合类的toString、equals、hashCode方法,不让其遍历整个集合
测试结果:经测试,自定义的文档树,有良好的程序健壮性和可拓展性,使用黑白测试均通过,文档树构建(showTree方法)如下
├─dir ├─dir2 ├─dir3 │ ├─xx.java │ ├─dir2 │ │ ├─dir3 │ │ ├─dir4 │ │ ├─dir5 │ │ ├─dir6 │ │ │ ├─xx2.
使用码上登录中转微信扫码登录 使用之前最好有一个公网服务器,能够公网访问的 redis 和 mysql 数据库,并且能够部署公网访问的服务
码上登录是一个小程序,对个体开发者提供了免费的微信扫一扫登录入口:官网 http://login.vicy.cn/
针对微信扫码登录需要进行企业认证,个人开发者无法使用的问题,我们可以使用码上登录进行桥接,将微信扫码登录的信息转发给我们的程序
在开发之前,我们需要有一个能被公网访问的地址,用来接收码上登录回调给我们的用户数据
更多信息参考码上登录 Api 文档:http://login.vicy.cn/apiWord.html
使用步骤 进入码上登录官网创建我们的应用:http://login.vicy.cn/ 微信扫码登录,进入首页,点击 马上创建应用
点击创建应用,输入网站名称和回调 URL ,填写完成后创建回得到 secretKey
网站名称就是用户扫码后看到的你的网站名称
回调 URL 就是用户确认登录后,接收用户信息的 controller ,可以先随便写,再后期修改
创建后台应用 先创建一个 web 模块 service-ucenter 用于编写代码,需要整合 mybatis 和 redis ,我使用 SpringBoot 的 web 项目
导入 commons 和对应的数据库依赖,该依赖的作用是让我们发送 HTTP 请求,获取二维码信息
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <!--http相关依赖--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.
一、概述 openFeign是要声明式的web服务客户端,或叫做声明式REST客户端,它让编写web服务客户端变得简单。
使用它的步骤:创建一个接口并注解它。它支持spring MVC的注解,spring cloud openFeign整合了hystrix,同时,可以和Eureka和ribbon配合使用,可以实现负载均衡的http客户端。
可以理解为是请求转发(RPC调度)的入口。本章讲述的是2.2.10.RELEASE版本。
二、使用步骤 1、引入spring-cloud-starter-openfeign 依赖。
2、启动类上加上@EnableFeignClients开启Feign的客户端服务
3、定义一个接口,并加上@FeignClient注解,同时,使用REST风格的接口请求服务。
例如:
@FeignClient(value = "provider") public interface OpenFeignService { @RequestMapping("/open") public String getName(); @FeignClient(“provider”)中的value值表示的是这个Feign客户端需要请求的微服务名称。这个名称代表了一个微服务或一个微服务组,其实就是spring.application.name的值。Feign客户端通过这个别名去EurekaServer服务端去找到这个别名对应的微服务。
如果你在项目中还使用了ribbon做负载均衡且结合了Eureka,那么,ribbon将去Eureka的服务注册中心拉取注册表,并缓存到本地,并结合负载均衡算法,选取一个物理主机作为服务端。
三、openFeign的使用 1、如果你不喜欢Feign默认的配置,可以使用FeignClientsConfiguration ,这个类能够让我们全面的控制Feign客户端。步骤如下:
a、定义一个类,继承FeignClientsConfiguration 。
b、重写方法。
c、在@FeignClient 中通过configuration属性引入自定义类。
注意:这个配置类不能注册进spring容器,即不需要使用@Component注解。当然,如果重写Feign的配置不想用自定义类,也可以使用配置文件。如果你既使用了配置类,又使用了配置文件,则配置文件生效。
2、如果你想定义多个Feign客户端,想区分他们,可以使用contextId属性。
@FeignClient(name = 'provider',contextId = "AClient",configuration = "FeignConfig.class") 3、熔断机制
OpenFeign 整合了hystrix做熔断处理,包括超时和异常熔断。其中对于超时,OpenFeign提供了两个参数:connectTimeout和readTimeout
connectTimeout:防止由于服务器处理时间过长而阻塞调用者
readTimeout:从建立连接时开始应用,并在返回响应时间过长时触发。
处理方式为:返回错误信息或fallback 其实就是hystrix的那一套机制。
实现步骤:
a、设置开启feign的熔断:feign.hystrix.enable=true
b、创建一个实现feign客户端类的fallback类,并重写方法,重写的方法其实就是针对这个方法的一个fallback处理。
c、在feign客户端类上的@FeignClient注解中用fallback属性引用
上面步骤仅仅针对学习或项目比较小,如果项目比较大,单独为每个feign客户端配置一个fallback类不合理,我们可以将微服务调用方法集中进行统一的fallback控制,这就涉及到工厂模式,使用工厂类。步骤如下:
a、创建工厂类,需要实现FallbackFactory
b、在feign客户端类上的@FeignClient注解中用fallbackFactory属性引用
4、创建客户端
创建客户端,有两种方式:注解和编码
通常我们一般使用注解的方式,即@FeignClient。我们也可以使用编码的方式手动创建Feign的客户端。这涉及到Feign的builder的使用,属于建造者模式。例如:
@Import(FeignClientsConfiguration.class) class FooController { private FooClient fooClient; private FooClient adminClient; @Autowired public FooController(Client client, Encoder encoder, Decoder decoder, Contract contract, MicrometerCapability micrometerCapability) { this.
CF804 E- Three Days Grace Problem Statement T T T组询问, 每组询问给一个数组 A i A_i Ai和两个整数长度 N N N及其值域 [ 1 , M ] [1,M] [1,M].
你可以进行如下操作
选择一个数 A i A_i Ai若满足 A i = p ⋅ q ( p , q ≠ 1 ) A_i=p\cdot q(p,q\neq 1) Ai=p⋅q(p,q=1)则可以删去 A i A_i Ai把 p , q p,q p,q加入数组.你可以无数次地进行上述操作 问数组中的极差最小是多少, 即 max ( A i ) − min ( A i ) \max(A_i)-\min(A_i) max(Ai)−min(Ai)在若干次操作后的最小值.
1.首先安照网上说的更改,但是没有效果
vim /var/lib/jenkins/hudson.model.UpdateCenter.xml //地址修改为 <url>https://mirror.xmission.com/jenkins/updates/update-center.json</url> 2.最终有作用:
vim /root/.jenkins/hudson.model.UpdateCenter.xml //地址修改为 <url>https://mirror.xmission.com/jenkins/updates/update-center.json</url> 3.然后重启
最近开发中遇到需要使用Python语言编写Maya脚本。要求使用脚本选择某一磁盘路径,脚本根据路径自动导入路径与子目录下的所有OBJ文件,并重命名它们。
在Maya中,有自带的脚本编辑器供我们使用,这使得我们编写代码非常轻松。
打开脚本编辑器,我们开始第一步,编写Maya脚本插件的UI:
import maya.cmds as mc #绘制窗体 mc.window(title =('磁盘路径').decode('gbk'), height=600) #列式布局 mc.columnLayout() #添加目录下拉菜单 op = mc.optionMenu( label=('目录').decode('gbk'), cc = "change_desk()") #添加显示当前选择路径的标签 pathText = mc.text( label = 'CurrentPath: C:/') #初始化获取C盘所有文件及文件夹,将它们写入列表,并为绑定双击事件函数 dirList = mc.textScrollList(numberOfRows = 35, append = os.listdir("C:/"), dcc = 'add_path()') #定义流式布局 mc.flowLayout( columnSpacing=10 ,width=200) #添加点击按钮 mc.button( label = ('导入所有OBJ').decode('gbk') , c = 'import_obj_re()') mc.button( label = ('导入当前路径OBJ').decode('gbk') , c = 'import_obj_single()') #搜索本地磁盘并初始化菜单 get_location_desk_list() #显示窗口 mc.showWindow() 有了UI,我们希望初始化本地的磁盘列表,所以编写咱们的get_location_desk_list()函数:
#获取本地磁盘 def get_location_desk_list(): disk_list = [] for d in string.
ADC转换就是输入模拟的信号量,单片机转换成数字量。读取数字量必须等转换完成后,完成一个通道的读取叫做采样周期。 采样周期一般来说=转换时间+读取时间。 而转换时间=采样时间+12.5个时钟周期。 采样时间是你通过寄存器告诉stm32采样模拟量的时间,设置越长越精确 公式:采样频率 = 1/采样周期 采样率指ADC每秒钟会进行多少次的模拟量转数字量的操作,如10K/s就是说ADC每秒钟,就采集了10K个模拟量,并将模拟量转换为数字量。 当采样声时,一般的采样率是44Kbps/s,当采样温度时,几K/s的采样率就够了。
ADC的时钟,是通过系统时钟 分频得来的 ++
ADC10每次采样转换的总时间是:采样时间+转换时间
Java编程入门 回顾 什么是Java语言 一种面向对象的语言 编写程序的开始就是编写类的开始 class 用于定义类 一种平台无关的语言,必须程序运行的解释环境 真正的运行步骤为 javac编译–java解释执行 一种健壮【鲁棒性】的语言,吸收了C/C++语言的优点,但是去掉了影响程序健壮性的部分,例如指针、内存的申请与释放等。
典型的应用场景:互联网环境 常见错误 1、使用临时变量,Java要求必须是先定义后使用,必须是先赋初值后使用
int k; Systm.out.println(k); 2、目前的要求:将所有的程序都必须写在方法内部,不能写在方法外
public class ForTest{ int res=0; for(int k=1;k<101;k++){ res+=k; } System.out.println("1+2+3+...+100="+res); } Java的三种核心机制 Java语言包含三种核心机制:Java 虚拟机、垃圾收集机制和代码安全检测。 Java虚拟机 JVM Java虚拟机可以理解成一个以字节码为机器指令的CPU对于不同的运行平台,有不同的虚拟机Java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”
垃圾收集机制 gc 不再使用内存空间回收——垃圾回收在C/C++等语言中,由程序员负责回收无用内存 Java语消除了程序员回收无用内存空间的责任,它提供了一种系统级线程跟踪存储空间的分配情况,并在JVM的空闲时检查并释放哪些可被释放的存储空间 垃圾收集在Java程序原型过程中自动运行,程序员无法精确控制和干预 代码安全性检查 Java代码的目标运行环境在于网络,Java以牺牲执行性能为代价换取了高安全性
首先由类加载器classLoader负责将类文件.class加载到Java虚拟机中。通过区分本地文件系统的类和网络系统导入的类增加安全性,可以限制任何木马程序,因为本机类总是有限被加载,一旦所有的类都被加载完毕,直线文件的内存就固定了。其次字节码校验器进行校验。字节码校验器不检查那些可信任的编译器生成的类文件,而是对违背 命名空间规定和java语言规则的类进行检查,并且关闭具有安全性漏洞的类文件最后字节码校验通过后,才由Java解释器负责将类文件解释成为机器码进行执行 Java中标识符 字母(Unicode编码字符集)、数字、下划线和$符构成,不允许数字打头严格区分大小写ISO8859-1GB2312和GBK【GB8030】Unicode统一编码字符集 由于_和$有特殊含义,一般不建议用户直接使用不建议使用中文命名 不允许使用保留字(goto const)和关键字(public class static…)长度没有限制 public class ForTest{ int res=0; for(int k=1;k<101;k++){ res+=k; } System.out.println("1+2+3+...+100="+res); } 编码规范 类名首字母大写,大写字母分词 建议名词。例如UserName或者MingZi方法名称首字母小写,大写字母分词变量名称首字母小写,大写字母分词包名称全小写,使用域名反转的方式定义
平常练习中遵循SUN的基础规范;项目开发中要求遵循ali发布的规范。进入公司首先考察公司的编码规
范 Java是一种先编译后解释执行型语言 javac Hello.
JeecgBoot 是一款基于代码生成器的低代码平台!我在一个项目中用JeecgBoot 3.0时,有一个需求是需要用到多reids数据源,JeecgBoot官方只有使用微服务时才能用Redis集群搭建,所以百度了一下,并没有相应的文章。由于JeecgBoot是基于SpringBoot开发的,就百度了SpringBoot 的redis多数据源,但是,一直没有一个合适的!那就自己动手改了代码,经过了多次测试,终于可以使用了,特此记录一下!
首先在配置文件里application-dev.yml,的#redis 配置 下面,添加新的redis源,例如:
redis2: database: 0 host: 127.0.0.1 lettuce: pool: max-active: 8 #最大连接数据库连接数,设 -1 为没有限制 max-idle: 8 #最大等待连接中的数量,设 0 为没有限制 max-wait: -1 #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 shutdown-timeout: 100 password: '' port: 6370 然后在 jeecg-boot-base/jeecg-boot-base-tools/src/main/java/org/jeect/common/modules/redis/config中修改RedisConfig.java
package org.jeecg.common.modules.redis.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.GlobalConstants; import org.jeecg.common.modules.redis.receiver.RedisReceiver; import org.jeecg.common.modules.redis.writer.JeecgRedisCacheWriter; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.
[论文地址] [代码] [MICCAI 21]
Abstract 总目标体积(Gross Target Volume, GTV)分割在鼻咽癌(NasoPharyngeal Carcinoma, NPC)的放疗计划中起着不可替代的作用。尽管卷积神经网络(CNN)在这一任务中取得了良好的性能,但它们依赖于大量的标记图像进行训练,而这些图像的获取是昂贵和耗时的。在本文中,我们提出了一个新颖的框架,采用不确定修正金字塔一致性(URPC)正则化,用于半监督的NPC GTV分割。具体来说,我们扩展了一个骨干分割网络来产生不同尺度的金字塔预测。金字塔预测网络(PPNet)由已标记图像的基础真值和未标记图像的多尺度一致性损失监督,其动机是对同一输入的不同尺度的预测应该是相似和一致的。然而,由于这些预测的分辨率不同,鼓励它们直接在每个像素上保持一致,其鲁棒性较低,可能会失去一些细微的细节。为了解决这个问题,我们进一步设计了一个新颖的不确定性矫正模块,使框架能够逐渐从不同尺度上有意义的、可靠的一致区域中学习。在一个有258张NPC MR图像的数据集上的实验结果表明,在只有10%或20%的图像被标记的情况下,我们的方法通过利用未标记的图像在很大程度上提高了分割性能,而且它也优于五个最先进的半监督分割方法。此外,当只有50%的标记图像时,URPC取得了82.74%的平均Dice分数,接近于完全监督学习。
Method 本文提出了一个使用半监督进行鼻咽癌分割的框架,如下所示:
主要亮点在于不确定性(uncertainty)的计算方式。传统方法诸如MC-Dropout依赖于对同一张图像进行多次推理,从而较为耗时。本文受分割任务中常用的deep supervision的启发,提出了一种"Multi-Scale Consistency",即各级decoder输出的内容应该是一致的: D s ≈ ∑ j = 0 C p s j ⋅ log p s j p c j \mathcal{D}_{s} \approx \sum_{j=0}^{C} p_{s}^{j} \cdot \log \frac{p_{s}^{j}}{p_{c}^{j}} Ds≈j=0∑Cpsj⋅logpcjpsj 使用的是KL散度。 p s p_s ps为各级decoder的预测结果, p c p_c pc为各级decoder的预测结果的平均。这一不确定性有两种作用,直接看最终的无监督损失: L unsup = 1 S ∑ s = 0 S − 1 ∑ v ( p s v − p c v ) 2 ⋅ w s v ∑ s = 0 S − 1 ∑ v w s v + 1 S ∑ s = 0 S − 1 ∥ D s ∥ 2 \mathcal{L}_{\text {unsup }}=\frac{1}{S} \frac{\sum_{s=0}^{S-1} \sum_{v}\left(p_{s}^{v}-p_{c}^{v}\right)^{2} \cdot w_{s}^{v}}{\sum_{s=0}^{S-1} \sum_{v} w_{s}^{v}}+\frac{1}{S} \sum_{s=0}^{S-1}\left\|\mathcal{D}_{s}\right\|_{2} Lunsup =S1∑s=0S−1∑vwsv∑s=0S−1∑v(psv−pcv)2⋅wsv+S1s=0∑S−1∥Ds∥2 包含两部分。右边这个 1 S ∑ s = 0 S − 1 ∥ D s ∥ 2 \frac{1}{S} \sum_{s=0}^{S-1}\left\|\mathcal{D}_{s}\right\|_{2} S1∑s=0S−1∥Ds∥2指的就是直接约束各级输出结果应尽可能一致,而左边这个相当于额外利用这个uncertainty做了一个attention,即选择"
补码一位乘法 为什么要使用补码乘法? 在计算机中,使用一般乘法的话,对符号位还要重新进行异或操作,这样会大大降低运算速度,而使用补码乘法运算,就可以找到一种通用的解法来解决符号位的重复计算,而将符号位作为数字一起带入运算器进行计算
补码一位乘法规则 首先说明一下,为了便于证明,下面的证明都是在小数的基础上进行的,小数证明以后便可以直接推广整数
假设被乘数为 [ x ] 补 [x]_补 [x]补
[ x ] 补 = x 0 x 1 x 2 x 3 . . . x n [x]_补=x_0x_1x_2x_3...x_n [x]补=x0x1x2x3...xn
乘数为 [ y ] 补 [y]_补 [y]补
[ y ] 补 = y 0 y 1 y 2 y 3 . . . y n [y]_补=y_0y_1y_2y_3...y_n [y]补=y0y1y2y3...yn
两者均为任意的符号位,则有补码乘法公式:
[ x ∗ y ] 补 = [ x ] 补 ∗ y [x*y]_补=[x]_补*y\\ [x∗y]补=[x]补∗y
我们首先创建一张user表,id为主键 CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT, `money` int DEFAULT NULL, `version` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 第一类丢失更新(回滚丢失) A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来:
时间
取款事务A
转账事务B
T1
begin; 开始事务
T2
begin; 开始事务 T3
select money from user where id = 1; 查询账户余额为1000元 T4
select money from user where id = 1;
查询账户余额为1000元
T5
money = 1000 + 100;
update user set money=1100 where id = 1;
https://zhuanlan.zhihu.com/p/354651458 import pandas as pd import numpy as np from tqdm import tqdm import statsmodels.api as sm import statsmodels.formula.api as smf pd.set_option('display.max_columns', None) #显示所有行 pd.set_option('display.max_rows', None) #混合中介 data_new['数字经济'].astype(float) #模型一 result = smf.ols('Score ~ 数字经济',data = data_new).fit() #ols最小二乘回归 print(result.summary(),'模型一') #模型二 for i in data_new.columns[-17:-3]: print(i) result = smf.ols('{0} ~ 数字经济'.format(i),data = data_new).fit() #ols最小二乘回归,模型二 print(result.summary(),i,'模型二') #模型三: i = ' + '.join(data_new.columns[-17:-3]) print(i) result = smf.ols('Score ~ 数字经济 + {0}'.format(i),data = data_new).fit() #ols最小二乘回归,模型三 print(result.
解析token的网址:
https://jwt.io/
但是如果token中有超过17位的数字,js前端会直接变成000,后3位进位了
需要使用新的地址
http://jwt.calebb.net/
首先,清除所有预设置
iptables -F#清除预设表filter中的所有规则链的规则 iptables -X#清除预设表filter中使用者自定链中的规则
1.
其次,设置只允许指定ip地址访问指定端口
iptables -A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -d xxx.xxx.xxx.xxx -p tcp --sport 22 -j ACCEPT iptables -A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 3306 -j ACCEPT iptables -A OUTPUT -d xxx.xxx.xxx.xxx -p tcp --sport 3306 -j ACCEPT
1.
上面这两条,请注意–dport为目标端口,当数据从外部进入服务器为目标端口;反之,数据从服务器出去则为数据源端口,使用 --sport
同理,-s是指定源地址,-d是指定目标地址。
然后,关闭所有的端口
iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP
1.
3221225477 (0xC0000005): 访问越界,一般是读或写了野指针指向的内存。
3221225725 (0xC00000FD): 堆栈溢出,一般是无穷递归造成的。
3221225620 (0xC0000094): 除0错误,一般发生在整型数据除了0的时候。
node.js简介 Node.js能够让javascript在服务端运行
1、node的特性 异步I/O
说到异步I/O,就不得不说一下I/O,他们分别是input和output的缩写,也就是输入、输出。它是人类用来和计算机进行通信的外部硬件。输入/输出设备能够向计算机发送数据(输出)并从计算机接收数据(输入)。
I/O分为同步和异步,其中同步又有阻塞和非阻塞之分。异步没有,异步一定是非阻塞的。
同步过程中进程,触发IO操作并等待(也就是我们说的阻塞)或者轮询的去查看IO操作(也就是我们说的非阻塞)是否完成。
异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。
事件驱动
单线程
跨平台
2、node的应用场景 I/O密集型是否擅长CPU密集型?分布式应用 3、node和浏览器 除了HTML、WebKit还有显卡这些UI技术node没有支持以外,node和谷歌浏览器非常相似,他们都是基于事件驱动的异步架构,浏览器通过事件驱动来服务页面上的交互,node通过事件驱动来服务I/O。
node不处理UI,但是node和浏览器有相同的机制和运行原理。node打破了JS只能在浏览器运行的局面,使前后端编程环境统一,可以大大降低前后端转化所需要的交换代价
模块化 commonJS 1、模块规范 在node中一个模块就是一个文件,每一个模块都有自己的作用域
对模块的定义非常简单,分为模块引用、模块标识、模块定义。
模块引用:通过require方法,接受模块标识为参数,进行引入
模块标识:必须是小驼峰命名的字符串,或者是文件相对或者绝对路径。
模块定义:也就是导出,提供了exports对象用于导出当前模块的方法或者是变量(或者是module.exports)
使用案例:
// export.js const testVar = 1; function test() { console.log(this.testVar) }; module.exports.testVar = testVar; module.exports.fn = test; // requare.js const val = require('./export'); console.log(val.testVar); // 1 val.fn(); // 2 2、模块实现 在node中,模块可以被分为两类:
一类是node提供的内置模块,称为核心模块。在源代码的编译过程中,编译进了二进制执行文件,在node启动的时候,部分的内置模块就会被直接加载进内存中,所以当我们引入这些模块的时候,文件定位和编译执行就可以直接省略掉,并且在路径分析中会优先判断,核心模块的加载速度是最快的。另一类是用户编写的模块(第三方库也是文件模块),称为文件模块,文件模块在运行的时候动态加载的,需要完整的路径分析,文件定位和编译执行过程,速度会比核心模块的速度慢。 在node引入模块,需要经历三个步骤,
路径分析文件定位编译执行。 2.1、优先缓存加载 与前段浏览器会缓存静态资源脚步一样,node也会对引入的模块进行缓存,以减少二次引入时的开销。但不同的是,浏览器仅仅缓存文件,node缓存的是编译和执行之后的对象。
不论是任何模块,require对于相同模块的二次引入都是采用缓存优先的方式。
2.2、路径分析 标识符有以下几种形式,所以对于不同的标识符,模块查找和定位在一定程度上也有不同。
核心模块,也就是node内置模块,直接通过内置模块名引入.或者…开始的相对路径文件模块/开头的绝对路径的文件模块非路径形式的文件模块,比如自定义三方库名等,直接通过第三方库名引入,但注意不要和内置模块重名。 核心模块
对于核心模块,直接通过内置模块名引入,其加载速度是最快的,但注意,要加载一个和核心模块相同标识符的自定义模块,是无法成功的,因为会优先查找核心模块。
路径形式的文件模块
在分析文件模块的时候,require会将路径转化为真实路径,并以真实路径作为索引,将编译执行后的结果放入缓存中,以便于二次加载。其加载速度仅次于核心模块。
图论—欧拉路径
如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。
如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。 [1]
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的图称为半欧拉图。
以下判断基于此图的基图连通。
无向图存在欧拉回路的充要条件
一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。
有向图存在欧拉回路的充要条件
一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。
来源:王家廞.离散数学结构.北京:清华大学出版社,2004
一、理解this绑定 函数在调用时,JavaScript会默认给函数绑定一个thisthis的绑定和定义的位置(编写的位置)无关this的绑定和调用方式以及调用的位置有关this是在运行时绑定的优先级:new > bind > apply/call > 隐式绑定 > 默认绑定 二、this的绑定规则 默认绑定 // 具名函数调用 fucniton foo(){ console.log('foo',this) } foo() // this指向window // 匿名函数调用 // const foo = function(){ // console.log('foo', this) // } // foo() // this指向window 隐式绑定 // 隐式绑定 const info = { name: '张三', age: 24, sayName() { console.log('this指向', this) } } info.sayName() // this指向 {name: '张三', age: 24, sayName: ƒ} 显示绑定 function foo(name,age) { console.log('参数', name, age) console.
写在开篇 kubeadm工具快速部署k8s集群实现故障自动发现、转移及修复,集群中部署prometheus+grafan可实现自动收集集群的各项新性能指标数据,可视化界面提升客户对各项性能指标的直观感知,实现高效快速故障排查及解决。
一、kubeadm搭建k8s集群 1、Kubeadm简介: (1)什么是kebeadm? 作为Kubernetes官方提供的集群部署管理工具,采用“一键式”指令进行集群的快速初始化和安装,极大地简化了部署过程,消除了集群安装的痛点。可以快速部署一套k8s集群。
(2)Kubeadm基本原理: 在启动的过程可以查看到拉取组件镜像的过程。之所以kubeadm能成为最快搭建k8s集群的工具就在于它将组件都容器化部署。
使用两条命令可以快捷部署一套k8s集群:
kubeadm init:初始化集群并启动master相关组件,在计划用做master的节点上执行。
kubeadm join:将节点加入上述集群,在计划用做node的节点上执行。
(3)K8s集群角色中包含的组件: K8s-master:
kube-apiserver
controller-manager
Scheduler
Etcd
K8s-node:
Kubelet
Kube-proxy
Docker
1.1 项目实验环境要求 可根据实际生产环境的需求配备适配的基础环境,本次项目仅作为实验参考
集群角色机器数量操作系统硬件配置iP地址网络策略备注K8s-master1台CentOS7.x-86_x642个cpu2GB内存40GB硬盘192.168.1.15配置弹性公网;集群间网络可互访禁止swap分区K8s-node11台CentOS7.x-86_x642个cpu2GB内存40GB硬盘192.168.1.16配置弹性公网;集群间网络可互访禁止swap分区K8s-node21台CentOS7.x-86_x642个cpu2GB内存40GB硬盘192.168.1.17配置弹性公网;集群间网络可互访禁止swap分区 1.2 实操步骤 1.2.1 环境准备 ###三台机器均执行以下操作 ###关闭防火墙: systemctl stop firewalld systemctl disable firewalld ###关闭selinux: sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 setenforce 0 # 临时操作 ###关闭swap: swapoff -a # 临时操作 vim /etc/fstab # 永久操作 ###关闭swap: swapoff -a # 临时 vim /etc/fstab # 永久 ###设置主机名: hostnamectl set-hostname k8s-master hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2 ###将桥接的ipv4流量传递到iptables的链: cat > /etc/sysctl.
tkinter简介 tkinter是Python自带的一个GUI包。优缺点非常明显:
优点:简单、快速、无需安装
缺点:界面复古,缺少对一些复杂功能的支持
(注意,Python2的tkinter名称为Tkinter,我们不讨论它)
启动tkinter 在命令行输入
python -m tkinter
就会弹出一个tkinter窗口:
最上面首先是版本是8.6,点击click me!貌似什么都不会发生,点击QUIT就可以退出。
下面介绍tkinter的简单用法,更多的可以去GUI是什么 (biancheng.net)或
Python GUI 编程(Tkinter) | 菜鸟教程 (runoob.com) 或Tkinter 8.5 reference: a GUI for Python (tkdocs.com)学习。
tkinter HelloWorld 使用tkinter创建一个窗口,标题名称为Hello,world。
# -*- coding:utf-8 -*- import tkinter as tk # 调用Tk()创建主窗口 root_window =tk.Tk() # 给主窗口起一个名字,也就是窗口的名字 root_window.title('Hello,world') #设置窗口大小 450x300 root_window.geometry('450x300') #开启主循环,让窗口处于显示状态 root_window.mainloop() 导入:tkinter
创建主窗口: root_window =tk.Tk()
设置窗口属性(标题、大小):
root_window.title(‘Hello,world’)
root_window.geometry(‘450x300’)
开启主循环
root_window.mainloop() tkiner 身高计算器 现在我们来做一个有功能的tkinter程序。
最终效果如下:我们输入身高,点击计算。然后程序通过计算,得到我们的身高并显示出来。
那么我们在上面Helloworld程序的基础上开始制作。首先,我们把窗口名改成“身高计算器”。
root_window.title('身高计算器')
然后我们要把按钮,提示信息放上去。
# root_window.
领导说代码上库是作为每月人力工时投入的考核标准。对于划水人来说,这太容易糊弄了,下个代码升级基线,不就有200多条上库记录了么。
一 下载高通私有代码 比如基线版本:qcm6125-la-2-0_amss_standard_oem_FC 0.0.011.2.463079.2
二 同步高通开源代码 mkdir LA.UM.9.11.1.r1cd LA.UM.9.11.1.r1repo init -u http://source.codeaurora.org/quic/la/la/vendor/manifest -b release -m LA.UM.9.11.1.r1-00700-QCM6125.0.xmlrepo sync –j8 mkdir LA.QSSI.11.0.r1cd LA.QSSI.11.0.r1repo init -u http://source.codeaurora.org/quic/la/la/system/manifest -b release -m LA.QSSI.11.0.r1-13600-qssi.0.xmlrepo sync –j8 repo sync可能中途同步失败,需要多次repo sync
三 合并代码 1、合并 LA.UM.9.11.1.r1和 LA.QSSI.11.0.r1
cp -rf LA.UM.9.11.1.r1/* LA.QSSI.11.0.r1/ 2、合并私有代码proprietary部分到LA.QSSI.11.0.r1
cp -r qcm6125-la-2-0_amss_standard_oem.git/LINUX/android/vendor/qcom/proprietary LA.QSSI.11.0.r1/vendor/qcomcp -r qcm6125-la-2-0_amss_standard_oem.git/LA.QSSI/LINUX/android/vendor/qcom/proprietary LA.QSSI.11.0.r1/vendor/qcom 四 编译 source build/envsetup.shlunch trinket-userdebugchmod +x build.sh./build.sh -j8 dist
1.docker 安装rocketmq #拉取镜像 docker pull foxiswho/rocketmq:server-4.7.0 docker pull foxiswho/rocketmq:broker-4.7.0 2.创建server和broker目录,并创建broker.conf #创建目录 mkdir /opt/rocketmq-server mkdir /opt/rocketmq-broker/conf -p [root@localhost opt]# cat /opt/rocketmq-broker/conf/broker.conf namesrvAddr=192.168.1.200:9876 brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 brokerRole = ASYNC_MASTER flushDiskType = ASYNC_FLUSH brokerIP1 = 192.168.1.200 listenPort=10911 3.启动容器 #启动rocketmq-server docker run -d \ --restart=always \ --name rmqnamesrv \ -p 9876:9876 \ -v /opt/rocketmq-server/logs:/root/logs \ -v /opt/rocketmq-server/store:/root/store \ -e "MAX_POSSIBLE_HEAP=100000000" \ foxiswho/rocketmq:4.
转自:微点阅读 https://www.weidianyuedu.com
一、启动和关闭Oracle数据库
1. 数据库启动以SYSDBA身份登录数据库启动命令:STARTUP 【启动选项】
数据库启动三个阶段:
启动Oracle实例(非安装阶段)
由实例安装数据库(安装阶段)
打开数据库(打开阶段)
2. 数据库的关闭
以SYSDBA身份登录 数据库关闭命令:SHUTDOWN 【启动选项】 数据库关闭三个阶段:
关闭数据库
卸载数据库
关闭Oravle实例
▎二、启动、关闭Oracle监听进程
监听器lsnrctl:提供数据库访问,默认端口1521
为了使客户端用户能连接到Oracle实例,要启动监听
1.启动监听启动(START)监听是Oracle用户在操作系统下执行的命令,可以直接在LSNRCTL后加参数,也可以在该命令提示符后在进行操作。
2.关闭监听
注意:先启动监听,后启动数据库。 ▎三、表空间
1. 创建表空间
参数解释:tablespacename:表空间名称DATAFILE:指定组成表空间的一个或多个数据文件,当有多个数据文件时使用逗号分隔filename:表空间中数据文件的路径和名称SIZE:指定文件的大小,用K指定千字节大小,用M指定兆字节大小AUTOEXTEND:用来启用或禁用数据文件的自动扩展
举例:
2. 表空间的管理(1)调整表空间的大小。当表空间已满的情况下,可以通过ALTER语句来调整表空间的大小。 方法一:更改数据文件的大小,并指明数据文件的存放路径,通过使用RESIZE关键字,用于指定调整后的表空间的大小
方法二:向表空间内添加数据文件。为表空间添加一个新的数据文件 (2)改变表空间的读写状态。
ALTER TABLESPACE 表空间名 READ WRITE ; --使表空间可读写ALTER TABLESPACE 表空间名 READ ONLY ; --使表空间只读
(3)删除表空间,可以通过DROP语句来删除表空间,再加上表空间的名字即可。 DROP TABLESPACE 表空间名 [INCLUDING CONTENTS] ;其中INCLUDING CONTENTS是可选项。如果删除仍包含数据的表空间,需要加上该选项。
▎四、用户管理1. 创建用户
举例:
2. 修改用户的密码ALTER USER 用户名 IDENTIFIED BY 密码 ;
3. 删除用户。使用DROP USER命令可以删除用户,当用户拥有模式对象时则无法删除用户,而必须使用CASCADE选项以删除用户及用户模式对象。
英文辅音字母是除A、E、I、O、U以外的字母。本题要求编写程序,统计给定字符串中大写辅音字母的个数。
输入格式: 输入在一行中给出一个不超过80个字符、并以回车结束的字符串。
输出格式: 输出在一行中给出字符串中大写辅音字母的个数。
输入样例: HELLO World! 输出样例: 4 这道题和判断字符一样,只不过要查找个字符变啦,这次查找辅音字母以外的字母
代码如下:
#include<stdio.h> int main(){ char ch; int i=0; while((ch=getchar())!='\n'){ //给出一个输入并以回车符结束 if(ch>='A' && ch<='Z') //首先判断是否是字母,然后在判断是否是辅音字母之外 if(ch!='A' && ch!='E' &&ch!='I' &&ch!='O' &&ch!='U') i++; } printf("%d",i); return 0; }
问题描述:
用mstsc登录Windows服务器,发现登录后,窗口无法最大化,切换右上角的最大化按钮也不行。
解决办法:
1. Win+R,输入mstsc
2. 显示选项 --- 显示 --- 在显示配置块里面将按钮拖动到右边最大位置,再重新登录服务器即可
小程序引入jsencrypt实现RSA加密 RSA加密是什么 什么是RSA加密,详情可以百度。
简单来说 RSA加密算法是一种非对称加密算法。
是一种通过公钥加密,私钥解密的非对称加密方法。
一般公钥对外暴露,私钥私密保存,只有正确的私钥可以解密出正确的内容。
jsencrypt 是一个基于rsa加解密的js库
如何引入到小程序使用 1.官网下载 jsencrypt.js ,require引入到小程序使用。
使用的版本 /*! JSEncrypt v2.3.1 | https://cdn.jsdelivr.net/npm/jsencrypt@2.3.1/bin/jsencrypt.js */
2.跑起来,看看有哪些错误
看不懂,求助谷歌,原来是 jsencrypt.js 是不兼容小程序的,因为小程序没有 window 对象。
如果需要在小程序中使用需要修改源码,进行适配
在小程序中引入 jsencrypt 需要对源码就行修改适配。因为小程序没有 window 对象。
搜到一篇微信开饭社区文档:https://developers.weixin.qq.com/community/develop/doc/000068b497cfc00619b7bcfdc51004
修改后并没有加密成功,开饭社区还是不怎么靠谱啊
搜到一篇评论挺多人说有用的文章:https://blog.csdn.net/qq_34672907/article/details/89605498
该文章的修改思路是直接替换 window 对象和 navigator 对象。思路有了
照猫画虎,修改,navigator 我做了 ?. 链式调用处理不需要修改,直接添加一个 window 对象
改完 window,其他遇到报错,也按同样的思路处理适配,代码终于没有明显的输出报错了。
![]](https://img-blog.csdnimg.cn/a057c7c7de924616a365b80a67a747b1.png)
最后正常按照 h5 d 使用方式使用接口。
期间遇到问题,需要一步步调试。
下面讲讲调试的过程。
遇到问题的调试过程 如果加密的数据没有解密成功,要查看源码的 encrypt 方法是否加密成功,一步步调试。
注意加密如果失败,这里会返回 false 需要打印才能看到
发现加密失败,断点调试找到对应的方法
回溯调用栈找到最开始出现错误的地方
this.n 是 null 这里我不确定为什么是 null 全局搜索一下 this.
最近做一个excel三级联动
参考:https://www.wps.cn/learning/question/detail/id/2444.html
步骤如下:
1.准备需要联动的数据
2.选中联动数据Ctrl+G 勾选常量,选择定位,选择菜单-公式-指定-勾选首行-选择确定。步骤目的是生成对应的名称管理器
3.准备联动表
4.选中城市列,选择菜单数据-有效性-有效条件(允许)选择序列,数据来源选中需要下拉的城市,点击确认。此时生成城市下拉列
5.城市下拉选择一个城市,然后选择辖区列-选择菜单-数据-有效性,条件选择序列,数据来源填写=INDIRECT(B2)点击确定,此时生成单行的二级联动。**此时复制该行的格式下拉(达成所有行都有下拉联动的关键)具体操作参考[链接]里面选择辖区列步骤gif图后半部分操作。
6.生成区乡村联动:根据步骤2生成名称管理器。即可以。不需要使用数据有效性。
备注:关于四级联动没有操作过。生成联动关键点在于数据有效性和名称管理器。网上有很多方法。有结合下拉列表的。有一个个填充的。但是最后的关键点复制行格式。并没有点明。有不明白的地方参考链接
目录
1.顺序表的定义
2.define和typedef
3.以下所有用到函数的声明
4.建表,为表开放空间
5.建表,并且输入表内的值
6.在L中第i个位置之前查人新的数据元素e,L的长度加1
7.删除L的第i个数据元素,并用e返回其值,L的长度减一
8.用e返回第i个元素的值(因为i对应着第i-1个位置)
9.打印表的内容
10.判断是否为空表(L.length是顺序表的长度,当表长等于0时,空表;不为0时,不空)
11.按值查找函数(顺序查找)
12.求第i个元素的直接后继
13.求第i个元素的直接前驱
14.switch选择函数
15.输出表长
16.摧毁表操作
17.//清空这个表
18.在清空表以后输入表的内容
19.功能函数
代码全部:
运行结果:
在数据结构课程中,顺序表有着很重要的作用,虽然说顺序表和数组类似,所以操作较为简单。
主要依据严蔚敏版数据结构教材。
这个文本,主要是针对线性表中的顺序表而操作的。以下代码为自己作业,如果有问题欢迎大家指点。
内容:
void print() { printf("\n\t输入数字来选择功能\n"); printf("\t0.退出\n"); printf("\t1.在L中第i个位置之前插入新的数据元素e,L的长度加1\n"); printf("\t2.删除L的第i个数据元素,并用e返回其值,L的长度减一\n"); printf("\t3.用e返回第i个元素的值\n"); printf("\t4.打印表\n"); printf("\t5.判断表是否为空\n"); printf("\t6.按值查找\n"); printf("\t7.求表的长度\n"); printf("\t8.求第i个元素的直接后继\n"); printf("\t9.求第i个元素的直接前驱\n"); printf("\t10.建表\n"); printf("\t11.摧毁顺序表\n"); printf("\t12.清空这个顺序表\n"); printf("\t13.在清空表的基础上重新输入这个表\n"); } 1.顺序表的定义 我们在这里可以使用结构体类型来定义
typedef struct{ int *elem; //顺序表基地址 int length; //顺序表当前长度 int listsize; //顺序表容量 }*Sqlist; 2.define和typedef //define区 #define List_Init_Size 100 #define List_Increment 10 #define OK 1 #define OVERFLOW -2 #define ERROR 0 //预处理指令区 #include <stdio.
灰度图像归一化到0~255(对比度拉伸)原理如下:
g' = g * Mult + Add
其中:
怎么理解这个原理?
上面的原理把简单的事情搞复杂了,我们对上式进行化简,用Python-sympy进行化简,代码如下:
from sympy import * g, Gmax, Gmin = symbols('g Gmax Gmin') Mult = 255/(Gmax-Gmin) Add = -Mult*Gmin g_ = simplify(g*Mult+Add) print(g_) 化简结果如下:
上面这个式子就很好理解了,上面的式子相当于把介于[Gmin,Gmax]区间的灰度值按比例拉伸到0~255的区间。 原理就这么简单,接下来上代码,这个代码其实我之前就已经写过基于OpenCV1.x的版本了,详情可参见我写的另一篇博文,链接如下
https://blog.csdn.net/wenhao_ir/article/details/51142979
这篇博文提供的代码是基于OpenCV2.x的,并且没有使用OpenCV的函数cvMinMaxLoc()求阵列的最大值、最小值,有兴趣的同学可以参考我之前写过的代码,将下面代码中的求最大值、最小值的代码用OpenCV的cvMinMaxLoc()函数实现。
当然,以下代码最大的作用还是为大家学习图像处理基本原理之用。因为下面的代码完全可以被OpenCV的函数normalize()代替,即下面这条语句:
normalize(srcGray, resultImage, 0, 255, NORM_MINMAX); 我在之前的代码中也用到过这个归一化函数,比如下面这篇博文中的代码:
https://blog.csdn.net/wenhao_ir/article/details/51655055
关于OpenCV的函数normalize()的详细讲解,可参考博文https://blog.csdn.net/wenhao_ir/article/details/125619073
说回来,本文要提供给大家的源码如下:
源码中用到的图像的下载链接:
https://pan.baidu.com/s/1i4Dvm2h
//原文链接:https://blog.csdn.net/wenhao_ir/article/details/51658765 #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> cv::Mat contrastStretch(cv::Mat srcImage) { cv::Mat resultImage = srcImage.clone(); int nRows = resultImage.
源码获取:俺的博客首页 "资源" 里下载! 项目介绍 本项目分为管理员与用户两种角色;
管理员角色包含以下功能:
管理员登录,菜单管理,角色管理,修改密码,用户管理,学院班级管理,日志列表管理,
实验室管理,设备管理,设备申请管理,查看我的设备申请,实验室申请管理,查看我的实验室申请等功能。
用户角色包含以下功能:
用户登录,修改密码,查看用户列表,实验室管理,设备管理等功能。
环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 5.数据库:MySql 5.7版本;
6.是否Maven项目:是;
技术栈 1. 后端:Spring+SpringMVC+Mbytes
2. 前端:JSP+css+javascript+jQuery+easyUI+h-ui
使用说明 1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;
2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;
若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;
3. 将项目中db.properties配置文件中的数据库配置改为自己的配置;
4. 运行项目,在浏览器中输入localhost:8080/ssm_ziyuan_yuyue
用户管理控制器: /** * 用户管理控制器 * */ @RequestMapping("/admin/user") @Controller public class UserController { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired PartService partService; /** * 用户列表页面 * @param model * @return */ @RequestMapping(value="
在开源还只是一个小众群体的业余爱好时,几乎做任何事情,都是自由的。但是,在软件吞噬世界、开源吞噬软件的今天,开源技术,已经成为整个世界的基础设施之一。 ——《2021年中国开源年度报告》
先告诉大家一个好消息,我们马上就要开源啦,期待一下哦
在开源前,小鸥会用一点点时间跟大家聊聊关于开源、关于社区的事儿。我们刚刚开始长大,期待与大家共建一个有价值、有活力、有温度的开源社区!
开源和闭源 开源(Open Source)即开放源代码,是源代码开放共享的开发模式,具有自由开放、共建共享的特点。它是一种依托互联网平台,通过大量群体智慧共同参与协作,不断积累,实现持续创新的方式。
“Open Source”的概念出自Debian的社长Bruce Perens起草的“自由软件指导方针”。对确立“Open Source”概念有决定意义的是在1998 年4月7日由18位自由软件运动领袖召开的“自由软件高层会议”,通过了传播开源的必要性。
那开源和闭源主要的区别都有哪些呢?
看下图
开源 闭源源代码开放代码封闭该软件通常是免费的通常是要支付版权许可费其他用户和组织可以修改此代码只有创建软件的个人或组织可以修改代码 软件的使用和修改
对用户没有那么多限制
软件的使用和修改
对用户有很多限制
开发者可以通过提交源代码修改
来获取社区认可
软件公司/组织雇用开发者来改进软件参与项目的开发者理论上无限制参与项目的开发者数量是有限的 开源的意义 GitHub 2021 年度报告数据显示:全球已有超过 7300 万开发者用户,其中 56.8% 来自北美之外的地区。我国开发者占 10%,有 755 万,位居全球第二。我国开发者数量及开源贡献度增长已成为全球最快。GitHub 预测到 2030 年我国开发者将成为全球最大的开源群体。
资料来源于网络 Raymond在《大教堂与集市》中用大教堂和集市这两个具体形象,来代表两种不同的软件开发模式:
大教堂模式:自上而下,有一群精英进行顶层设计,按照计划去完成任务。
集市模式:自下而上,没有一个绝对主导核心,靠的是普通个体们的自组织,一起去完成复杂的任务。Raymond观点是:随着互联网的发展,越来越多的大教堂会消失,那么剩下的都是大集市。
所以,我们必须认同一个趋势:“开源软件作为一种「非垄断性」和「非排他性」的知识存在,已经是软件世界的重要基础设施,也是数字世界不可或缺的未来。”
资料来源于网络 数字经济时代,人口和流量红利逐渐消失,这都需要我们开辟新的生态模式,而这一切都源于技术的推动。开源是一种开放、共享、协同的创新协作模式,它不仅是开放源代码的软件技术开发,还包括更广泛的开放技术领域及协同创新的理念与机制。无论是在全球还是国内,开源正在推动着信息技术的创新发展。这种突破物理边界、高效敏捷的沟通和协同方式必将会为数字经济的发展带来新活力。同时,开源的高度开放和自由,也会让人类智慧得到更好的共享和发展,降低学习、复用和改进成本,打破技术封锁。开源,最终将造福整个软件业和整个社会。
为什么要开源 01 WebGPU,下一代Web3D技术
实现桌面级的渲染效果,支持超大复杂场景的3D呈现。易上手、易分享、易迭代、易协作、成本低,跨平台是我们的核心优势,我们将为3D场景爆发时代提供引擎基础工具。
Web环境中一直没有出现可以实现和桌面级渲染能力相媲美的革命性技术,然而这一现状随着WebGPU标准的提出,即将得到改变,这是非常让人振奋的变革,我们将迎来网页图形的全新时代!
通过开源可以帮助社区更好地了解这项技术,同时也可以通过社区的影响力对这项技术进行推广,邀请更多的开发者参与进来。社区的积极快速反馈也能帮我们汲取更多的需求场景输入,帮助技术迭代更新,技术才更有生命力。我们期望在未来的数字经济时代能够发挥更大更积极的作用。
02 开发者生态,构建高价值社区
我们一直坚信,软件再优秀,如果没有构建起良好的生态,没有开发者和合作伙伴的共建,是很难走得更好更远的。一个开源产品,社区的文化氛围和协同创造力,才是区别于他人最大的不同。
开源生态的建设根植于社区,有了健康社区生态的哺育,开源技术才能获得持续成长。志趣相投的开发者们源于主动创造价值的内在动力,在社区共享、共创、共赢,将会激发出无限的创造力,这就是开源最大的魅力!
Orillusion在创立之初就坚定地拥抱开源,开放包容、共创共赢是我们的基本理念。我们秉承全球化与本土化相结合,既要保持全球化视角,吸引来自全球各地优秀的开发者加入进来,又要在我们原有的文化背景下打造符合本土特色的开发者生态,推动我国开发者力量长期发展。
我们深知,开源生态的建设并非一蹴而就,这将是一个长期过程,需要我们有耐心、有信心、脚踏实地、开放心态。
选择开源,源于我们坚信,“独行快,众行远”!
共建社区是这样的 社区的本质是归属感,没有归属感就没有社区。——Jono Bacon
01 每一位社区参与者才是宝藏
对于开源社区而言,最重要的宝藏不是代码,而是代码背后的每一位参与者和创造者,及大家在共创协同过程中建立起来的链接。社区的建设与成长,社区的文化与氛围,源于社区体系中的每一个人,源于个人汇集成的凝聚力。因此,从我们开源第一天起,每一位参与者是我们要珍视和保护的宝藏。
我们也会一直保持这样的敬畏之心,邀请更多行业内优秀的开发者进来,建立起共同协作的开源社区。
02 放眼全球的国际化社区
我们希望通过开源的方式将Orillusion 做成一个伟大的产品,不仅局限在国内,更要着眼全球!
Github 2021 Octoverse报告数据,全球的开发者有7300万+,2021年新增1600万+。我国2021年在Github的新增开发者103万,总数达到755万+。我国开发者在开源世界的影响力正在不断提升,已经从早期开源的受益者,逐渐转变成开源的贡献者。
科学计算-数值优化 上课跟着老师敲的。。。凑合凑合
数值优化的目的就是找局部的最小值。
主文件:任意找一组解x0,定义误差
目标函数:
梯度计算:
数值解方法,
解析解方法,
最速下降法:
ISPRS2022/云检测:Cloud detection with boundary nets基于边界网的云检测 0.摘要1.概述1.1. 云检测方法综述1.2. 挑战1.3. 有前途的策略1.4. 一种新的框架:边界网 2. 调查的数据3.边界网Boundary nets3.1. Scalable-boundary Net可伸缩边界网络3.2. Differentiable-boundary net可微边界网络 4. 训练边界网4.1. 训练数据构建4.2. 一种分布式的、全面的监督方式4.3. 损失函数4.4. 优化 5.云检测6.总结参考文献 论文下载
代码开源
0.摘要 在卫星光学图像中,云通常以不同的尺度和不同的边界显示。为了准确捕捉云的可变视觉形式,我们提出了一种基于深度学习的策略,即边界网,该策略生成一个云掩码,用于检测一幅云图中的云。边界网由两个网络组成,即(a)可伸缩边界网和(b)可微边界网。可扩展边界网从云图像中提取多尺度特征,并通过多尺度融合模块综合表征具有可变边界尺度的云。多尺度特征提取和多尺度融合一致地捕获不同大小的云,为云图像生成多尺度云掩模。可微边界网通过残差结构表征了多尺度云掩码和地面真实云掩码之间的差异。它生成一个差分云遮罩,作为多尺度云遮罩边界细节的补充。最后,通过融合多尺度云掩模和差分云掩模得到整体云掩模。在训练过程中,边界网的多个关键部分以分布式方式访问监督信息,并总结损失以进行整体训练计算。这种分布式、全面的监督不仅避免了单独训练两个网络,而且还将两个网络紧密地耦合到一个整体框架中。实验结果验证了我们的边界网络性能良好,并取得了显著的效果。
1.概述 在过去几十年遥感技术进步的推动下,光学遥感图像得到了广泛的应用。云是大气中的自然现象,经常出现在遥感图像中。全球平均年云量约为66%(张等,2004)。在遥感图像中准确探测云的任务在协助使用遥感技术观察地球方面发挥着重要作用。
云检测旨在识别遥感图像中的云像素。准确的云检测有助于遥感技术的高水平应用,例如收获产量估计(Sakamoto,2020;Holzman等人,2018)、土地变化检测(Hu等人,2018b;Yan等人,2019)和灾害管理(Boluwade,2020)。另一方面,不准确的云检测可能会给后续的实际任务带来麻烦,并对结果产生负面影响(朱和Woodcock,2012)。
云的多样性和下垫面的复杂性使得在遥感光学图像中区分云像素和非云像素很困难。因此,云检测通常是一项艰巨的任务。在本节的剩余部分,我们将回顾现有的云检测方法,解释云检测中的挑战,提出我们自己的云检测解决方案,并介绍我们的新贡献。
1.1. 云检测方法综述 在过去几年中,已经开发了许多云检测方法。在本小节中,将回顾三大类云检测方法,即基于阈值的方法、基于手工特征或规则的方法以及基于深度学习的方法。
基于阈值的云检测方法主要利用光谱信息通过设置阈值来区分云和非云像素。有各种基于阈值的方法,例如ISCCP云掩码算法(Rossow和Garder,1993),APOLLO(云、陆地和海洋上的AVHRR处理方案)方法(Kriebel等人,2003)和Fmask方法(Zhu等人,2015)。这些基于阈值的方法在某些条件下提供了良好的云检测结果(Foga等人,2017)。然而,这些基于阈值的方法存在明显的不足。一方面,基于阈值的云检测方法依赖于各种信息(例如,光谱反射率、亮度和温度),并且可能具有受类似信息影响的不正确像素分类。另一方面,阈值通常根据特定的卫星平台和传感器设置,并且具有较弱的通用能力
近年来,基于手工特征或统计规则的云检测方法蓬勃发展。胡等(2015)将随机森林算法与视觉显著性特征相结合,得到云的分割图。Lin等人(2015)使用加权主成分分析和统计模型从多时相图像中获取云掩码。Joshi等人(2019)提出了基于支持向量机(SVM)算法的STmask方法,以从流苏帽带4(TC4)和短波红外光谱带2(SWIR2,2.107–2.294μm)生成云掩码。虽然这些方法通过统计学习取得了良好的效果,但它们在很大程度上依赖于手工特征或人类指定的规则。在这种情况下,很难设计一个通用的范例来应对云的多样性。手工特征或某些人类指定规则的应用仅限于特定情况。
最近,深度学习技术被部署到云检测中。在这种情况下,云检测通常被视为通过基于深度学习的方法解决的多通道图像分割问题。在自然图像分割的文献中,提出了各种基于深度学习的方法,例如FCN(Long等人,2015)、U-Net(Ronneberger等人,2015)、SegNet(Badrinarayanan等人,2017)和DeepLab V3+(Chen等人,2017)。这些基于深度学习的图像分割方法主要依赖于卷积神经网络(CNN)(LeCun等人,1998)。CNN是一种有效的端到端深度分层特征学习模型,可以自动捕获图像的固有特征。CNN也被用来处理云检测问题。谢等(2017)应用基于浅层CNN的模型对云像素进行分类,取得了良好的性能。Shi等人(2017)提出了一种云检测方法,使用CNN进行特征提取,使用支持向量机进行分类。虽然上述两种方法都使用了基于CNN的结构来自动提取特征,但由于网络结构相对简单,在复杂场景中的检测效果并不好。李等人(2019)提出了一种融合低层次高分辨率特征和高层次高语义特征的特征金字塔网络,用于云检测。Jeppesen等人(2019)使用了一种基于编码器-解码器的结构,该结构逐渐提取和恢复特征,以在陆地卫星-8图像上生成云掩码。Mohajerani和Saeedi(2019)提出了基于复杂卷积块和各种垂直路径卷积的云网络,以区分云和非云像素。Segal Rozenhaimer等人(2020年)通过开发三种新的基于深度CNN的网络结构和一种新的转移学习框架,对使用多模式数据检测云进行了开创性研究。何等人(2021)优化了CNN结构的空间特征表示(孙等人,2021),并在高分1号图像上构建了高效的云检测网络结构。为了增强薄云的特征,张等人(2021)提出了一种用于云检测的AUDI-Net,方法是在深层结构中引入小波变换和暗通道先验,并在浅层中放置多个扩展卷积,以获得更多的空间信息。这些现有的基于深度学习的云检测方法以加深模型架构的一般方式有效地从光学图像中提取光谱和空间信息。然而,这些深层架构往往具有很强的表征一般场景的能力,但可能没有足够的能力捕捉云层显示的各种外观。
1.2. 挑战 尽管云检测已经研究了很多年,但仍有一些具有挑战性的问题尚未解决。一个主要问题来自于在不均匀土地上充满破碎薄云的高度混合场景的复杂现象(例如,图1所示的多云场景)。在这种情况下,现有的云检测方法(即使是最先进的方法)很难处理这些复杂的现象。复杂的现象给云检测带来了两大挑战,如下所示:
1) 第一个挑战是检测具有不同边界尺度的云。这一挑战源于解决各种规模的碎云的困难。大多数现有的深度模型(尤其是深度神经网络)倾向于通过固定尺度的感受野捕捉视觉特征。如图2(a)所示,卷积神经网络(CNN)中的一个固定比例感受野只能对固定大小区域内的附近像素进行建模(Szegedy等人,2015;Ranftl等人,2021)。这种结构很难应付边界尺度不稳定的云。如图3所示,一些标准方法(即U-Net(Ronneberger等人,2015年)、SegNet(Badrinarayanan等人,2017年)和DeepLab V3+(Chen等人,2017年))检测大多数具有大规模边界的云,但往往忽略小尺寸的云(由蓝色圆圈标记)。限制的一个主要原因是,这些现有方法是由固定尺度的感受野构成的,很难处理具有不稳定边界尺度的云。
2) 第二个挑战是区分复杂的云边界。具有不均匀陆地的高度混合场景导致难以区分的云边界,尤其是薄云。此外,云的形状随着环境的变化而急剧变化(朱和伍德科克,2012),使得复杂的云边界更难捕捉。现有的深度学习方法在全局范围内获得云检测结果,而不需要特别考虑边界。对于一些复杂的现象,大多数现有的基于深度学习的云检测方法在识别复杂云边界上的云像素时置信度较低。因此,如果采用检测置信度来表示云掩码,则通常会在云掩码的云边界处出现模糊。图3显示了从一些标准方法获得的模糊边界(用橙色圆圈标记)。因此,如何生成高置信度、清晰边界的云掩码仍是云检测的一个挑战
1.3. 有前途的策略 为了应对第1.2节中描述的两个挑战,我们提出了两种有前途的策略,简要介绍如下。
我们在第1.2节中提出的挑战1)的解决方案是一种多尺度处理策略。多尺度处理从多尺度的感受野开始,感受野能够捕捉不同尺度的云(如图2(b)所示)。将从多尺度感受野获得的多尺度特征进行叠加和融合,得到多云图像的多尺度表示。多尺度处理策略是可扩展的,因此它能够生成从非常小的规模到相当大的规模的云掩码。它解决了现有基于深度学习的方法中通常出现的开销敏感性缺陷。
我们在第1.2节中提出的挑战2)的解决方案是一个残差架构。它实现差分运算并生成差分云掩码。差分云掩模是增强云掩模边界的有效手段。这样,沿云遮罩边界产生的模糊被抵消。
1.4. 一种新的框架:边界网 通过利用这两种有前途的策略,我们开发了一个用于云检测的边界网总体框架。边界网由两个基于深度学习的网络组成:可扩展边界网和可微边界网。
可扩展边界网从光学图像中提取多尺度特征,并将其融合生成多尺度云掩模。在我们的工作中,我们通过暗示网络能够在多个尺度上表征云来重载“可扩展”一词的含义。
可微边界网学习云特征的固有差异,并生成差异云掩码。将差分云掩模与其对应的多尺度云掩模融合生成整体云掩模。在我们的工作中,我们通过暗示网络倾向于可区分的边界,强调了“可微”这个词的含义。
训练边界网需要训练数据,其中每个样本都由一个云图和它的地面真云遮罩组成。云图和地面真实云掩码对为训练网提供监督信息。虽然这两个网络具有不同的功能,但它们是在一种分布式的、全面的监督方式下训练的。具体而言,边界网多个关键部分分布式接入监管信息,将损失汇总,统筹两网训练。分布式监控使得培训过程更加全面,涉及到多个关键环节的监控。在总损失测量方面的全面监督不仅使两个网以一致的方式耦合,而且使边界网成为一个不可分割的框架。
一旦训练良好,边界网可以为给定的多云图像生成精确的云遮罩。大量的实验验证了边界网在云检测中的有效性。
我们的工作的新颖贡献总结如下:
1)我们开发了一种新型的边界网云检测框架,解决了基于深度学习的云检测方法长期面临的尺度不敏感和边界模糊问题。
2)我们开发了一种分布式的、整体监督的方式来训练边界网。分布式监控为两网各关键部位提供监控信息,实现全面培训。整体监督不仅使两网保持一致,而且使经济培训过载。
3)边界网实现了最先进的云检测性能。我们发布了实现边界网的代码。我们鼓励研究人员在不同的情况下对边界网进行实证评估,并使广泛的研究成为可能。
2. 调查的数据 在我们的研究中,我们使用三个数据集,即SPARCS (Hughes和Hayes, 2014)、GF1-WHU (Li等人,2017)和WHUS2-CD+ (Wu等人,2019)来验证提出的边界网。
Apache Impala 4.1概览 自从Impala 4.0发布后,历时近11个月,Impala 4.1终于发布了!新版本在Iceberg集成、Catalog优化、Parquet/ORC读取性能、嵌套类型等方面都有较大进展。限于个人认知和篇幅有限,本文只能挑些重要功能进行介绍,详细更新列表可见 Change Log-4.1.
1. Iceberg集成 Impala-4.1开始正式支持Apache Iceberg。Iceberg是开源的table format,具有以下几个特性:
ACID保证:DML都是原子操作,查询都访问一致的snapshot隐藏分区:不像传统的Hive表用文件目录来表示分区值,Iceberg表的分区值由列值转换而来,分区信息保存在metadata文件中。reader不需要知晓分区的定义,Iceberg会推断出查询所需的文件。分区演化:分区的定义可以灵活更改,得益于隐藏分区,这种更新不需要重写数据文件,只需要生成新的metadata文件表格式演化:新增、删除、更新列的定义都没有副作用,如不需要重写数据文件版本回溯(Time travel):查询可以访问特定的一个数据版本 下面的例子演示了如何在Impala中使用Iceberg表:
目前Impala只支持Iceebrg V1类型的DML操作,即insert into/insert overwrite。Iceberg V2类型的操作如行级别的修改(update, delete)仍未支持。更多细节可查看文档:Using Impala with Iceberg Tables
2. Parquet优化 Impala支持多种文件格式,如Parquet、ORC、Avro、Text等,其中Parquet格式的支持是性能最好的,做了比较多的优化,Impala-4.1在这方面又有不少改进。
2.1 延迟物化(Late Materialization) Parquet Scanner的工作主要包含数据读取、解压、解码和执行下推的谓词等。当有谓词下推时,可以先读取相关列的数据,过滤得到所需要的行号后,再去相应地读取其它列。在谓词选择性高的场景下,可以有数倍的性能提升,具体可查看 IMPALA-9873。
2.2 文件Bloom Filter Parquet文件是自解释的文件,包含了schema和索引信息(如各列min-max值),其中的索引就包含可选的Bloom Filter。Impala-4.1开始支持读写Parquet文件中的Bloom Filter,下推的等值谓词能作用在文件的Bloom Filter上。(IMPALA-10640, IMPALA-10642)
2.3 文件字典(Dictionary) Parquet文件的列可以使用字典编码,下推的谓词(Predicate/Filter)会先作用在字典上,以过滤无用的RowGroup,从而减少读取的数据量。Runtime Filter是在运行时生成的谓词,由hash join的hash表生成而来,下推到scanner提前过滤数据。
从Impala-4.1开始,Runtime Filter也会作用在字典上,前提是字典不能太大,超过一定大小将不启用此优化。这个阈值由查询选项PARQUET_DICTIONARY_RUNTIME_FILTER_ENTRY_LIMIT 控制,默认为1024。
2.4 Decimal兼容性 支持高精度类型Decimal读取的schema兼容性,即当Parquet文件的Decimal列与表字段定义的precision或scale不一致时,可兼容性地读取。(IMPALA-7087, IMPALA-8131)
3. ORC优化 Impala在ORC文件的读取方面(即ORC Scanner)集成的是第三方的ORC C++ Reader,虽然易于维护,但不像内建的Parquet Scanner那样更方便做性能优化。Impala-4.1在ORC读取方面做了不少优化,旨在缩小Parquet Scanner和ORC Scanner间的性能差距。比如下推谓词和Runtime IN-list Filter到ORC Reader,ORC Reader的异步数据读取,ORC Scanner和ORC Reader的代码优化等。许多场景下已经能做到接近读Parquet的性能。
Ctrl+S 组合键以及自动保存(提交)功能的实现 默认情况下,Chrome 中按下 Ctrl+S 组合键会进入“保存网页”界面,并不会与网页中的具体内容做交互。
网页中按下 Ctrl+S 组合件就能触发提交动作,将前端数据的改动存储到后端数据库中。
并且不管用户是否操作,每隔特定时间也会自动提交文档的当前内容到后端,实现自动保存的功能。
下面展示一些 内联代码片。
<template> <button @click="save('button')">保存</button> </template> <script> export default { mounted() { document.addEventListener('keydown', this.saveContent) this.timer = setInterval(() => { this.save('timer') }, 10 * 1000) }, beforeDestroy() { document.removeEventListener('keydown', this.saveContent) clearInterval(this.timer) }, methods: { save(type) { console.log(`content saved by ${type}`) }, saveContent(e) { var key = window.event.keyCode ? window.event.keyCode : window.event.which if (key === 83 && e.ctrlKey) { this.save('hot key') e.
第六章-谈谈“优化” 处处都有“优化”在 “优化”是通信中最为宽泛的主题,所有试图增加功能、增强性能、保证安全性、节省投资、提高利用率、减少错误、鼓励创新的技术和理念,都可以归为“优化”的范畴。
为了保证资源有效利用、通信效率更高,复用技术被广泛应用,这是节约传输资源的基本思想。为了减少传输损耗,网络拓扑的部署设备也是重要研究课题。为了保证通信网络,网络安全成为重中之重。为了提高传输速率,通信网络在编码过程中常采用压缩技术。 分工和职责——通信分层结构 1.为什么要分层? 以保证各种网络技术能清晰地共存和良好地配合,并不断激励新技术的创新。
为此,ISO建立了一套非常抽象的分层结构,这就是著名的ISO/OSI(国际标准化组织的开放网络架构)。每层都对应着通信实体,如路由器、交换机、防火墙、Web服务器、用户端软件等。
为了让两个通信实体保持最基本的沟通,在“层”的基础上,专家们定义了“协议”、“标准”和“规范”。
2.物理层 物理层就像人与人沟通中能够互相听懂的“发音”。物理层解决最基础的传送通道问题,涉及建立、维护和释放物理链路所需的机械的、电气的/光学的、功能的和规程的特性等,如光缆如何抗衰耗、无线设备如何提高发射功率、为什么双绞线要“绞”起来、为什么SDH能实现自动倒换等。
3.数据链路层 有了发音,才能有“字”或者“词”。在物理层提供的按“位(bit)”服务的基础上,在相邻的网络节点之间提供简单的、以帧为单位传输的数据,同时它还强调数据链路不要拥堵,减少出错,出错了要想办法弥补。
4.网络层 说话应该有目标、内容和语速,向谁说,说什么,以多快的速度说。网络层所干的工作,就是进行路由选择、拥塞控制和网络互连。对它的上级——传输层,它可以提供两种服务,一种叫作“面向连接”的网络服务,一种叫作“无连接”的网络服务——这有点像有轨交通和无轨交通。
5.传输层 要保证别人听到你说的话,不能“自说自话”。
传输层的任务是向用户提供可靠的、透明的端到端的数据传输,以及差错控制和流量控制机制。由于它的存在,网络硬件技术的任何变化对高层都是不可见的,也就是说会话层、表示层、应用层的设计不必考虑底层硬件细节,因此传输层起到应用软件和底层硬件之间承上启下”的作用。
所谓“端到端”,是相对链接而言的。这里读者们要记住,OSI参考模型的第4~7层属于端到端的方式,而第1~3层属于链接的方式。有了“端到端”,也就有了流量控制的能力。
6.会话层 说话要有开始、过程和终止。在不同的机器之间提供会话进程的通信,如建立、管理和拆除会话进程。会话层还提供了许多增值服务,如交互式对话管理、允许一路交互、两路交换和两路同时会话;管理用户登录远程系统;在两机器之间传输文件,进行同步控制等。
7.表示层 对于有些话,需要避免第三者听到;有些话要简单明了。表示层是处理通信进程之间交换数据的表示方法,包含语法转换、数据格式的转换、加密与解密、压缩与解压缩等。
8.应用层 应用层负责管理应用程序之间的通信。应用层为用户提供最直接的服务,包含虚拟终端、文件传输、事务处理、网络管理等。
应用层是OSI参考模型的最高层,低层所有协议的最终目的都是为应用层提供可靠的传输手段,低层协议并没有直接满足用户的任何实际需求。我们日常使用的电子邮件程序、文件传输、WWW浏览器、多媒体传输等都属于应用层的范畴。
9.是哲学,而不仅仅是技术! 一根线“掰”成几“瓣”用——复用技术 复用技术分为“确定复用技术”和“统计复用技术”。
1.确定复用 确定复用是指将管线拆成若干部分(无论是用频率拆分还是用时隙拆分),每个部分确定由某条业务连接独占,各行其道,相安无事。如:FDM、PDH、SDH、MSTP、WDM。
2.统计复用 统计复用,是指将管线不进行确定的“拆分”,而是每条业务连接通过各自的标识号来进行区分,各个业务连接根据自身需要来争抢资源,系统会定义争抢的优先级以及拥塞时的抛弃优先级。如:PSPDN(X.25)、帧中继、点对点协议(PPP)、ATM、以太网、IP网、IPRAN、PTN。
PPP是高级数据链路控制(HDLC)协议族的一般报文格式。它是为两个对等实体间传送数据包建立简单链接而设计的全双工操作。 “点对点”,是指在OSI第二层——数据链路层中的点对点,对标这一层中像以太网这样“广播”类型的通信方式。
PPP是为数不多的不需要“寻址”的协议,因为一根线两头的两个“通信实体”,就是通信双方,不需要设置地址。虽然PPP的封装格式设置了8位的地址字段,但这个字段毫无价值,在工程应用中都填充为全1的广播地址。
“排兵布阵”有讲究——网络拓扑浅析 总线型、星形、网状、环状、树形、双子星形等。
网络拓扑和线路拓扑区别:
光纤一般都呈环状分布,SDH设备在环的几个节点处放置,由于SDH要进行线路倒换,因此SDH网络一般也呈环状分布。如果在SDH设备旁边各放置一台路由器,路由器则可能做环状分布、星形分布、树形分布等。
开车还是坐地铁?——面向连接和非面向连接 1.面向连接 在一次通信过程中,信令在需要通信的双方或者多方之间呼叫,利用网络资源建立起一条通道,并在这条通道上传递信号,在通信结束后关闭这一通道。如:PSTN、帧中继、ATM、MPLS等都是面向连接的传送。
2.非面向连接 在一次数据传送过程中,数据包逐节点传递,在每个网络节点上,根据数据包中的目的地址,借助于网络节点的路由信息,选择通往下一个节点的通道。由于在数据传送前并没有预约带宽,因此在每个节点上,都需要进行“竞争”接入,并最终到达目的地。如:经典IP网络和广播电视网。
3.对两者的分析 面向连接的操作就像是城市的轨道交通,地铁、轻轨、有轨电车,车辆在出发前就已经预设好所有的路线,并严格按照这个路线走。无连接的操作则更像城市的公路交通。车辆在每个十字路口、丁字路口、岔路口都要判断如何行驶,左转、右转还是直行。 4.TCP/IP的连接性问题 TCP作为传输层协议,逻辑上是面向连接的。但在实现时,则是非面向连接的IP实现,因为TCP的面向连接体现在如果A实体传送数据给B实体,需要握手、确认(ACK)。对于IP层的数据包而言,无论是A发给B,还是B发给A,都是同一类型的包,都用报文的方式无连接地发送。如果ACK没有收到,则TCP需要3次握手建立连接,传输层的UDP没有限制。
TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区所能接纳的数据,这将防止较快的主机“淹没”较慢主机的缓冲区,所以TCP还提供了流量控制功能。
5.寻址技术的机理分类 电信网络按照机理分为“连接操作寻址技术”和“无连接操作寻址技术”。有连接操作寻址技术,最典型的是语音交换网PSTN和MPLS网,而无连接最典型的是由传统路由器和交换机组成的IP网络。
不可忽视的通信网络“摩擦力”——传输损耗 误码:接收与发送数字信号之间的单个数字的差异。如把0变成了1,1变成了0。抖动:数字信号的某些时候相对于理想位置,发生了短时的、非累积性的偏移。漂移:数字信号的各有效瞬间相对于理想时间位置的长期偏移。滑动:数字信号连续数字位置不可恢复地丢失或增加。时延:推迟。时延抖动:推迟变化的幅度,信号“迟到”时间长度的变化区间。分组(信元)丢失:数据分组或数据信元不可恢复的丢失,就是连续的信号段的完全丢失。
网络安全基本概念 网络安全包含两方面的含义,一方面是信息安全;另一方面是网络通道的安全。
1.信息安全 2.通信网络安全 信息安全是指信息内容的保密性,而网络安全是指通信“管道”(信道)本身的安全性。
信息系统由信息基础设施(基础架构)和信息业务系统(内容)组成;信息基础设施由电信网络和计算机系统组成。
eg:互联网的基础设施是A,信息系统为B,A+B=C,但是现在A被称为互联网,B被称为互联网,C也被称为互联网,通信行业所提到的互联网,应该是A。
3.安全服务举例 访问控制服务:防止未授权使用系统资源,或者当网络资源已经饱和,防止新的呼叫进去。如连接接纳控制(CAC)机制。PSTN、ATM、MPLS都有CAC机制。鉴别服务:防止假冒伪劣、盗用其他用户身份进入,包括IP地址、MAC地址、无线频率等占用网络资源。数据完整性服务:防止数据非法修改、插入、删除、中断。如黑客被商家雇佣攻击竞争对手的网站。数据保密性服务:防止泄露、信息流量分布,对保密性信息必须进行数据加密。抗抵赖性服务:防止抵赖,应尽可能追溯历史数据。如利用VoIP技术对主叫号码进行伪装,从而诈骗。木马检测服务:通信网络中存在大量“代理”,有的是出于安全需要设置的,有的是出于特定目的设置的。为“敌人”工作的代理是“木马”,黑客利用伪装成实用工具,进入计算机系统盗取信息。 4.数据加密技术 传统的通信保密技术——“密电码”技术。最简单的保密方式是通信双方拥有一样的明文和密文的对应方式。
浓缩的,都是精华!——通信压缩技术 压缩的目的那就是“节约”!节约存储空间、节省线路带宽、节省传送时间,都会给人类带来好处。当然,有些信息压缩会导致信息丢失或者失真,如声音、图像的压缩。
VoIP有几种常用的压缩算法:G.723、G.729、GSM和iLBC。
常用的语音压缩技术ADPCM,中文翻译为“差分自适应PCM”。这是一种采用平均值的方法来压缩语音编码的技术,也就是说,用差值替代绝对值。要传送一组较大的数字,只需传送其中一个数字和其他数字与它的差值即可。
Gradle 复制文件 很多大佬都是直接贴出如下代码,简单说就是 task 直接使用 from into include 等方法,然而直接复制下来之后,过了俩小时零一秒钟后依然无法使用。一直不生效。 task nestedSpecs(type: Copy) { into 'build/explodedWar' exclude '**/*staging*' from('src/dist') { include '**/*.html' } into('libs') { from configurations.runtime } } ———————————————— 版权声明:本文为CSDN博主「倾听心动旋律」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_15958689/article/details/79913625 经历无数次搜索之后发现 要在 task 里建 copy 块 把相关的 from into include 方法放到 copy块里才行。结果如下
task nestedSpecs(type: Copy) { copy { into 'build/explodedWar' exclude '**/*staging*' from('src/dist') { include '**/*.html' } into('libs') { from configurations.runtime } } } 希望有大佬讲解一下。感谢撒花
mapreduce优化 数据倾斜导致的Reduce时间长 当SQL中包含Join/GroupBy/PartitionBy/DistributedBy等操作时,通过对上述操作所用到的列进行统计,通常就能够找到造成数据倾斜的热点key
常见优化思路 1.过滤掉不符合预期的热点key,例如由于日志信息丢失导致某个字段产生大量空值
2.加入随机因素,打散热点key
3.使用map join解决小表关联大表造成的数据倾斜问题
map join是指将做连接的小表全量数据分发到作业的map端进行join,从而避免reduce task产生数据倾斜;
hive.auto.convert.join=true 这个配置跟hive.optimize.skewjoin有冲突,请保证二者只开一个即可;
map join需要在内存中加载全部小表数据,容易导致map端OOM,hive.mapjoin.smalltable.filesize这个参数用于设置小表的大小,默认25000000(25M),当小表数据量超过这个大小时,不会走map join优化逻辑,不建议用户把这个参数设置过大
hive.optimize.skewjoin可以处理热点key join 倾斜的问题,但是只支持inner join场景,不支持outer join场景
Map Task时间长 常见优化思路 1.查看上一轮作业是否存在reduce,如果有reduce task,则小文件是reduce生成的,如果单个reduce task执行时间不是特别大,可以适当控制reduce最大并发(hive.exec.reducers.max,默认5120,建议设置为2560/1280/640等);如果上一轮stage没有reduce,则小文件是map 生成的,需要加大split size减少map task(mapreduce.input.fileinputformat.split.maxsize,默认256000000,建议可以设置到1024000000);
2.在优化手段1的基础上,还可以使用数据架构组定制开发的根据文件数分片的功能(hadoop默认是按照文件大小分片),限制单个task处理的文件数大小(set mapreduce.split.by.block.num.enable = true; set mapreduce.split.block.number.threshold = 500;)
Map/Reduce gc严重 常见优化思路 1.加大内存:mapTask gc告警设置mapreduce.map.memory.mb(默认3072),reduceTask gc告警可以设置mapreduce.reduce.memory.mb(默认4096),建议按照512的幅度增加,合理使用避免浪费;
2.如果sql中有join和group by操作,可以调整参数缩小内存buffer检查间隔:
set hive.mapjoin.check.memory.rows=10000;
set hive.groupby.mapaggr.checkinterval=5000;
set hive.map.aggr.hash.percentmemory=0.3;
set hive.mapjoin.followby.map.aggr.hash.percentmemory=0.1;
set hive.map.aggr.hash.force.flush.memory.threshold=0.7;
set hive.map.aggr.hash.min.reduction=0.3;
3.可以选择关闭GBY的map端优化来争取节约内存hive.map.aggr=false;
MapTask过多,调度开销大 常见优化思路 1.加大单个map处理的数据量(mapreduce.input.fileinputformat.split.maxsize,默认256000000,建议可以设置到1024000000),减少map task个数;
2.合理设置sql查询的分区范围,尽量避免全表扫描,考虑生成一些增量的中间表来替代
map/reduce平均运行时间过长 常见优化思路 1.map运行时间过长:加大map并发需要减小split size(mapreduce.input.fileinputformat.split.maxsize,默认256000000,建议可以设置到32000000);
2.reduce运行时间过长:加大reduce并发需要减小reduce 的split size(hive.
资源下载地址:https://download.csdn.net/download/sheziqiong/85908050
资源下载地址:https://download.csdn.net/download/sheziqiong/85908050
ClipCap:让计算机学会看图说话 项目简介 Image Caption即我们常说的看图说话:给定一张图片,生成该图片对应的自然语言描述。
该任务涉及到了图像与自然语言两个模态,然而图像空间与自然语言空间本就十分庞大,并且两者之间存在巨大的语义鸿沟。
如何将两个庞大的语义空间进行对齐,这是该任务的重点。本项目对ClipCap: CLIP Prefix for Image Captioning
论文进行介绍,并且对论文在Flickr30k中文数据集上进行实验复现和效果展示。
论文概述 模型总览 ClipCap提出了一种基于Mapping Network的Encoder-Decoder模型,其中Mapping Network扮演了图像空间与文本空间之间的桥梁。模型主要分为三部分:
图像编码器:采用CLIP模型,负责对输入的图像进行编码,得到一个图片向量clip_embed。Mapping Network:扮演图像空间与文本空间之间的桥梁,负责将图片向量clip_embed映射到文本空间中,得到一个文本提示向量序列prefix_embeds。文本解码器:采用GPT2模型,根据提示向量序列prefix_embeds,生成caption。
论文中直接使用了预训练好的CLIP与GPT2-Large权重,两者分别是非常优秀的图像编码器和文本生层器,
能够将图像与文本映射到较好的语义空间中。然而两个模型是使用不同的任务进行训练的,语义空间没有进行对齐。
对于该问题,作者设计了两种Mapping Network,负责将图像与文本空间进行对齐。
MLP Mapping Network 使用多层全连接层作为CLIP与GPT2模型之间的桥梁。
具体做法如下:首先将图片向量clip_embed经过两层全连接层,映射成提示向量prefix_embeds,该向量作为提示信息输入到GPT2模型中,
然后GPT2模型根据prefix_embeds生成图片对应的caption。
Transformer Mapping Network 使用Transformer作为CLIP与GPT2模型之间的桥梁。具体做法如下:
首先将图片向量clip_embed经过一层全连接层,映射成提示向量序列prefix_embeds。Transformer中还维护了一个可学习的constant_embeds,将prefix_embeds与constant_embeds进行concat操作,然后输入到Transforemer中,让prefix_embeds与constant_embeds进行充分的交互。将prefix_embeds在Transformer对应的输出作为最终的prefix_embeds,作为GPT2模型的提示信息,生成最终的caption。 在该方法中,作者引入了constant embeds,这是一个向量序列,目的是为了让其能够在多头注意力中,捕获到prefix_embeds中携带的语义信息。
项目结构 datasets:存放数据models:存放自己实现的BERT模型代码output:输出目录pretrain_models:预训练模型存放位置scripts:脚本存放位置dataset.pypredict.py:根据图片生成captionprocess_caption.py:将flickr中文caption整理成统一格式process_clickr.py:对图片进行编码,获得image-caption训练数据statistics.py:对flickr数据集的caption长度分布进行统计train.py:训练脚本 使用方法 Quick Start 安装依赖包:
pip install -r requirements.txt 数据预处理(主要是对图像进行编码,得到train.pkl):
python process_flickr.py 训练MLP+GPT2 tuning:
bash scripts/train_finetune_gpt2.sh 训练Bert+GPT2 no_tuning:
bash scripts/train_no_finetune_gpt2.sh 使用MLP+GPT2 tuning进行生成:
bash scripts/predict_finetune_gpt2.sh 使用Bert+GPT2 no_tuning进行生成:
bash scripts/predict_no_finetune_gpt2.sh 实验介绍 数据集 图片与caption分别来自:Flickr30k数据集 与 机器翻译得到的中文caption数据
有次我的电脑出现了如上图的这种情况,wifi连不了,wlan还被禁用了
出现这种情况可以先右键连接,看能不能连上,如果还是连不上,直接用最狠的一个方法
如上图:直接点网络重置,这也会让你的电脑重启,重启之后基本就可以连上wifi了
[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021. 报错 报错以上的问题
尝试了好久--发现的问题-官网上文章看完了也没有看到
当点击 itemClick1的时候 就报以上的错误
当点击itemClick2的时候就能成功跳转
原因是: itemClick1和当前跳转的位置是同级,应该是<web-view>组件不能跳转到同级以外的地方!
总结: 所有想要使用 <web-view> 组件成功跳转的话-- 必须要使跳转的子链接在当前页码的下级子路径里面
WXML---- <view class="ad1" bindtap="itemClick1" data-url="../infoNetWork/netWork"> <image class="ad1Image" src="../../image/3533.png" mode="aspectFill"></image> <text class="ad1Text">url1</text> </view> <view class="ad1" bindtap="itemClick2" data-url="./toUrlOne/UrlOne"> <image class="ad1Image" src="../../image/3533.png" mode="aspectFill"></image> <text class="ad1Text">url2</text> </view> netWork.wxml--- <web-view src="https://www.baidu.com"></web-view> UrlOne.wxml--- <web-view src="https://mp.weixin.qq.com"></web-view> index.js---- // 点击跳转url itemClick1(e){ console.log(e, "=点击了!") wx.navigateTo({ url: e.currentTarget.dataset.url, }) }, // 点击跳转url itemClick2(e){ console.
目录
一、入门教学
第一步
第二步
第三步
二、进阶教学
如果上一步你实验不成功,那么恭喜你,请看这里
最后附实验教学材料(编辑能不能用....) 一、入门教学 第一步 接着点击应用 第二步 打开,并且复制粘贴这段代码
slmgr /skms kms.03k.org
slmgr /ato
slmgr /skms kms.03k.org slmgr /ato 接着保存 ( Ctrl+s )快捷键
第三步 然后以管理员身份运行
二、进阶教学 如果上一步你实验不成功,那么恭喜你,请看这里 将那段代码改成这样
slmgr /skms kms.03k.org
slmgr.vbs /upk
slmgr /ipk (激活密钥)
slmgr /ato
slmgr /skms kms.03k.org slmgr.vbs /upk slmgr /ipk (激活密钥) slmgr /ato 注意:激活密钥要根据自己的系统来决定
可以使用这段命令:wmic os get caption
wmic os get caption 来获取计算机系统版本
密钥根据系统版本百度查一下就行了
今天就先这样了,下期见。有什么错误或不懂的请在评论区留言,谢谢各位
一、部署XXL-JOB任务调度中心 下载地址:XXXL开源社区
1、初始化数据库
2、修改配置文件
修改数据库密码,注意spring.mail.password设置是邮箱授权码,不是邮箱密码
3、启动项目
http://localhost:8080/xxl-job-admin/ 账号和密码,admin/123456
二、使用任务调度中心 1、新建执行器
2、新增任务管理器
报警邮件:当调度任务发生异常时,会往当前邮箱发送报警邮件
JobHandler:这个名称可以随便写,但要记住这个名称,因为springboot集成时会用到这个名称
其他的默认就行
三、SpringBoot集成XXL-JOB 1、依赖
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.3.1</version> </dependency> 2、properties文件配置
server.port=8081 #------------xxl-job配置-------------- # log config logging.config=classpath:logback.xml ### 调度中心部署地址,多个配置逗号分隔 such as "http://address" or "http://address01,http://address02" xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin ### 执行器token,非空时启动 token?xxl-job, access token,这个和任务调度中心配置的accessToken保持一致 xxl.job.accessToken=default_token ### 执行器app名称,和控制台那边配置一样的名称,不然注册不上去 xxl-job executor appname xxl.job.executor.appname=itcloud-executor ### 【选填】 执行器注册:优先使用该配置作为注册地址,为空时使用内嵌服务 “IP:PORT” 作为注册地址 #从而更灵活的支持容器类型执行器动态IP和动态映射端口问题 xxl.job.executor.address= ### 【选填】执行器IP:默认为空表示自动获取IP(即springboot容器的ip和端口,可以自动获取,也可以指定),多网卡是可手动设置指定IP,该IP不会绑定Host仅作为通讯使用; xxl.job.executor.ip= #【选填】执行器端口号:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同的执行器端口; xxl.job.executor.port=9999 ### 执行器日志文件存储路径,需要对该路径拥有读写权限;为空则使用默认路径 xxl.job.executor.logpath=/data/logs/xxl-job/executor ### 执行器日志保存天数 xxl.job.executor.logretentiondays=30 3、新增logback.xml日志文件
<?xml version="1.0" encoding="
这个类是为了方便我们对将数据写入到文件中,
它的构造方法有两种,
一种是传入一个人File类
File file = new File("D:\\我的电脑\\asd\\a.txt"); try { FileOutputStream fos = new FileOutputStream(file); //FileOutputStream fos = new FileOutputStream("D:\\我的电脑\\asd\\a.txt"); } catch (IOException e) { throw new RuntimeException(e); } } 也可以直接传入一个String路径 File file = new File("D:\\我的电脑\\asd\\a.txt"); try { FileOutputStream fos = new FileOutputStream("D:\\我的电脑\\asd\\a.txt"); } catch (IOException e) { throw new RuntimeException(e); } } 写入文件的方法是write()重载了两次,分别用来写入一个字节,一串字节,和指定数量字节)
package io; import java.io.FileOutputStream; import java.io.IOException; /** * @ClassName IoFile * @Author 瞿肖 * @Date 2022/7/5 9:08 */ public class IoFile { public static void main(String[] args) { try { FileOutputStream fos = new FileOutputStream("
练习写作第一天 其实很早之前就确立了想要写作的目标了,但是苦于一些原因迟迟没有动笔。
自己并不是缺少想法,而是缺少对自己表达能力不够强文采不够出众的接纳。出于一种做不好那我就先不做的想法让我始终处于一种准备状态。但今晚看了冴羽推荐的一本有关写作的书对我的启发很大,书里提出对于写作,不要有完美主义倾向,好文笔是练出来的,好文章是改出来的,从这个角度理解,任何时候,你写的每一篇文章都是在为写好下一篇文章做准备。所以,写作的精进过程,就是你不断发现过去写得很差的过程。不要抱着“我先准备好,再一炮打响”这种念头学写作,要接受过程中的不如意,有句话说得好:先干起来,你就成功了一半。
另外要适当降低预期,没有人可以一开始就能写的好,迈出写作的第一步可以先从写一段话,阐述清楚一个观点开始。
写作有多少好处我就不多说了很多书籍公众号都已经告诉我们了,但于我这种人而言,我觉得写作(或者说用文字记录)已经是我不得不做的一件事情了。
如果一个人他有很多思绪,每天思考很多东西或者读书输入了许多内容,那么他必须要有一个载体去承载这些思绪,而如果他在日常生活中较少与人交流去表达自己的所思所想,那么写下来便是他能够理清繁杂的思绪获得内心平静的最好方式。不然就会被这些心绪困住,内心混乱,无法前进。杂乱的思绪制造的痛苦会逼着我去表达,这时候写作已经不仅仅是爱好了,而是我解决内心纷扰的一种方式。
项目运行起来后发现在测试接口的时候,total分页总是为0,查找了很多方法,以为是代码错误,结果是在配置文件中少写了一个@Configuration配置类
加上之后total就可以了
在敲写代码的时候我们总是会遗漏一些比较重要的东西,细心一点就好了。
第一次测试 第一章 绪论 数据元素是数据的基本单位。数据项是是组成数据元素的最小单位。数据对象是性质相同的数据元素的集合。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。①逻辑结构:线性结构,树结构,图结构。数据类型是一个值的集合和定义在这个值集上的一组操作的总称。抽象数据类型ADT。
算法的时间复杂度:取决于问题的规模和待处理数据的初态。 由嵌套层次最深的语句的频度决定的。空间复杂度:对数据进行操作的辅助存储空间。
1.NlogN^2和NlogN具有相同的增长速度。T NlogN^2=2NlogN≈NlogN 2.N^2logN和NlogN^2具有相同的增长速度。F
3.(NlogN)/1000是O(N)的。F O(NlogN)>O(N)NlogN的增长速度大于N的增长速度,A是B的说明A的增长速度小于B
4.N^2/1000是O(N)的。F A是B的说明A的增长速度小于B,根据函数图像来判断
5.100logN是O(N)的。T
6.
求整数n(n>=0)的阶乘的算法如下,其时间复杂度为( )。
long fact(long n) { if (n<=1) return 1; return n*fact(n-1); } C.Θ(n) 基本语句为n*fact(n-1);执行次数为n次、
7.
下列代码
for(i=0; i<n; i++) for(j=i; j>0; j/=2) printf(“%d\n”, j); 的时间复杂度是:D.O(NlogN) 我不知道呀
8.
下面程序段的时间复杂度是()。
x=90; y=100; while(y>0) if(x>100) { x=x-10; y--; } else x++;A.O(1) 根据代码可知,语句都是只执行l一次 9.下列代码
if ( A > B ) { for ( i=0; i<N; i++ ) for ( j=N*N; j>i; j-- ) A += B; } else { for ( i=0; i<N*2; i++ ) for ( j=N*2; j>i; j-- ) A += B; } 的时间复杂度是:
1.操作受限的线性表(栈和队列,即双端队列):只能在表头或表尾处做插入和删除的线性表(对于栈和队列来说,插入即输入,删除即输出)
特点:后进先出(LIFO:last imput first output)
a开头的:ab,bc,ad b开头的:ba,bc,bd c开头的:ca,cb,cd d开头的:dc,da(X),db(X) abcd abdc acbd acdb adcb 5种
bacd badc bcad bcda bdca 5种
cbad cbda cdba 3种
dcba 1种
已知入栈顺序是1,2,3....n
如果第一个出栈的是i,则表明前面的i-1个元素已经在栈中了。之后出栈的必然是i-1,i-2...1
是降序排列的
例题:入栈序列是递增升序的入栈1,2,3,4,5,确实是递增的 A项:第一位是5,后面小于5的数应该是是降序排列的 B项:第一位是4,小于4的数是1,3,2,但1,3,2不是降序排列的 C项:第一位是4,小于4的数是3,1,2,但3,1,2不是降序排列的 D项:第一位是3,小于3的数是2,1是降序排列的。再看2,再看1,再看5,再看4。每一位都要满足后面小于它的数是降序排列的
入栈序列是降序的
每一位都要满足后面大于它的数是升序排列的
A:第一位是2,大于2的数是3,4,5,6,是升序排列的 ;对。每一位都符合
B:第一位是3,大于3的数是4,6,5,不是升序排列的 ;错
入栈序列≠输入序列 因为p1=n, 该题的输出序列只能降序排列
n n-1 n-2 ... 3 2 1 代入i是2的话pi=p2=n-1来判断,故选C 输出第一个元素是i,出栈的序列就有i种,所以第j个输出元素是不确定的
p2是n,后面出栈的肯定是小于n 的且为降序的,只看p1的取值即可,有n-1种出栈序列。例如p1为5,先把1.2.3.4.5入栈,之后5出栈(p1),再将6.7.8.9...n入栈,n出栈(p2)
因为入队列和出队列的顺序一样,所以7个元素出栈的顺序已知。
队列 删除端:出队列(队头)
在队头处做出队列的操作 在队尾处做入队列的操作 特点:先进先出 直接根据尾指针rear找到尾结点,做插入时,不需要遍历整个链队列
1.可以颠倒次序,求逆序:一个字符串,每次读的时候,是以a,b,c,d的顺序读的,输出是d,c,b,a的顺序 2.函数机制的实现:当调用函数时,是在栈区里面的 要求栈和队列的插入和删除的时间复杂度都是O(1)
存储栈:顺序存储(顺序栈||循环队列)&&链式存储(链栈||链队列)
已知顺序表在表尾处做插入和删除都是O(1),base可直接代表数组(顺序表)的起始地址,而top可以是下标,也可以是地址***,可以指向栈顶元素,也可以定义成指向将要入栈的位置***
top做下标时:s.base[top]
对于顺序表而言,每次在表尾处后插入和删除的速度最快,每次在表头处做插入和删除时,需要移动大量的数据元素,删除和插入操作最慢。而对于单链表刚好相反。因为单链表是顺序存取,挨个遍历;而顺序表可以随机存取
6-5 带头结点的单链表就地逆置 (5 分)(就地:利用原节点,不生成新节点)
本题要求实现一个函数,对带有头结点的单链表进行就地逆置。
把每个元素结点从原链上取下,插在头结点(L->next)的后面。(相当于把所有的元素结点插在空表里)
1.首先让头结点的指针域为NULL,p指向a1。把结点a1(即p所指向的结点)插在头结点之后。
(单链表插入结点的操作:先修改插入结点的指针域,p->next=L->next ;再修改前驱结点的指针域L->next=p; ) 2.p按照原链下移,重复此操作
void reverse ( LinkList L ) { LinkList p=L->next;//p指向首元结点 LinkList q; L->next=NULL;//首先将头结点的指针域置为NULL,这句容易忘。否则会运行超时(结点的指针域没有为空指针的了),因为之后我们会把这个链表进行输出,会输出一片0000乱码,运行超时 while(p)//条件是p不为空,即所有结点都参与循环,遍历链表 { q=p->next;//q暂存一下p的后继,把原先还没修改的p->next送给q p->next=L->next;//把p所指向的结点插入到L结点的后面,修改p的指针域 L->next=p;//修改L的指针域 p=q;//p按照原链下移 } } if(!L) return 0;//如果链表是空表,直接return即可 //如果链表不空,让p指向第二个结点,把首元结点的指针域置为空。 //L是头指针,指向首元结点,第二个结点的地址为L->next p=L->next;L->next=NULL; while(p) { q=p->next; //把p所指向结点插入到L所只想结点之前,先修改插入结点的指针域 p->next=L;L=p;//**************** p=q; } 不带头结点的单链表,因为头指针L不断变化,形参必须使用引用参数
此时q所指向的结点就会被删掉(修改p的后继,释放q),
此时p,q的所指向结点的数据域不相等,因为该表是有序表,故后面没有1了,p下移
void delsame(LinkList L) { p=L->next;//让p指向第一个结点 if(!P) return 0; while(p->next)//判断p是否有后继,即p->next不为空 { q=p->next;//q为p的后继 if(p->data==q->data)//删除q,先修改p的指针域 { p->next=q->next;free(q); } else p=p->next;//p下移 } } 顺序表的删除,不是删除一个节点就向前移,而是*******
因为k,i所指向结点的数据域相同,所以不把i放在此处,i下移。做完之后,返回k+1
一、树的存储结构 孩子兄弟表示法--CSNode
二、树、森林与二叉树转换 都是用的孩子兄弟表示法 树转换为二叉树后,根结点无右子树,因为树中的根结点没有兄弟。
例一:设树的结点个数为n,那么当把树T转换成一棵二叉树后,且根结点的左子树上有(n-1)个结点。
例二:设树的结点个数为n,那么当把树T转换成一棵二叉树后,且根结点的右子树上有(0)个结点。
例三:设T是一棵树,B是由T变换得的二叉树。若T中有n个非终端结点(度不为0的结点),则B中右指针域为空的结点有(n+1)个。画个B、T看看。①转化后的二叉树根结点右指针域为空(树的根结点没有兄弟);②树中每个非终端节点最后一个孩子无兄弟,转换为二叉树(右指针为兄弟)后,右指针为空。
左分支是孩子,右分支是兄弟 由上图二叉树可知:B是A的孩子,C是B的兄弟,D是C的兄弟。所以B、C、D都是A的孩子。E、F是B的孩子。G、H、I是D的孩子
森林里边有若干棵树,将每棵树转换为二叉树;将第二棵树的根结点看作是第一棵树根结点的兄弟,将第三棵树的根结点看作是第二棵树根结点的兄弟,即每棵树的根结点互为兄弟(所以在右分支画)
可知左子树就是第一棵树的子孙,右子树是第一棵树、第二棵树。
例一:设森林T中有4棵树,第一、二、三、四棵树的结点个数分别是n1,n2,n3,n4,那么当把森林T转换成一棵二叉树后,且根结点的右子树上有(n2+n3+n4)个结点。
例二:设F是一个森林,B是由F变换得的二叉树。若F中有n个非终端结点,则B中右指针域为空的结点有(n+1)个。①森林的每棵树的每个非终端节点最后一个孩子无兄弟,转换为二叉树(右指针为兄弟)后,右指针为空。②最后一棵树的根无兄弟
三、树、森林遍历 要求:给定一棵树,写出先根遍历序列、后根遍历序列;给定森林,写出先序遍历序列、中序遍历序列;树与二叉树之间的相互转换;森林与二叉树之间的相互转换(画图题)
树采用孩子兄弟表示法,所以采用的存储结构是CSNode类型的
遍历这棵树用后根遍历时:E F B C I J K H G D A顺序与转换后的二叉树用中序遍历一致
树的先根遍历序列就是转换后的二叉树的先序遍历序列,树的后根遍历序列就是转换后的二叉树的中序遍历序列。
转换后的二叉树如下图:
例一: 如果T1是由有序树T转化而来的二叉树,那么T中结点的后根遍历就是T1中结点的(中序)。
森林的先序遍历就是转换后的二叉树的先序遍历,森林的中序遍历序列(我怎么觉得看上去也像是森林的后序呢)就是转换后的二叉树的后序遍历。
四、哈夫曼树 1.路径:由一个结点(一般为根结点)到另一个结点所经过的分支所构成。 2.路径长度:路径上的分支数目 3.树的路径长度:每个结点的路径长度之和
a到a的路径长度为0,a到b的路径长度为1,a到d的路径长度为2.....
4.带权路径长度:结点到根的路径长度与结点上权的乘积
5.树的带权路径长度WPL:树中所有叶子结点的带权路径长度之和(假设有n个叶子结点。路径长度为I,权值为W)
6.哈夫曼树:带权路径长度最小的二叉树
哈夫曼树:带权路径长度最小的二叉树
因为哈夫曼树是带权路径长度最小的二叉树,所以让叶子结点越矮越好。由上图知,叶子结点是5个,又由二叉树的性质3:N0=N2+1。所以度为2的结点数为4。N1=0,无度为1的结点
故哈夫曼树中,总结点数一定是奇数个 二、哈夫曼树(最优二叉树)构造的过程 给定(5个叶子结点)A、B、C、D、E,构造一棵二叉树使WPL的值最小(树中所有叶子结点的带权路径长度之和)
实际上,构造过程是构造非终端结点的
2.3两步要循环n-1次
这种题得先自己构造完之后再算
1.任何一个带权无向连通图的最小生成树——
当存在有权相等时,最小生成树就不是唯一的;极端例子就是所有权相等,即相当于无权。当所有权均不相等时,最小生成树是唯一的”。 如果带权图的权值都不一样,则最小生成树是唯一的。如果只是带权图,则不一定。
2.
对于有向图,其邻接矩阵表示比邻接表表示更易于:
A.求一个顶点的入度
B.进行图的深度优先遍历
C.求一个顶点的出边邻接点
D.进行图的广度优先遍历
邻接矩阵(具有随机存取特性):
求出度和入度,遍历对应行和列即可,时间复杂度都是O(n);
邻接表:
求出度容易:找到对应的头结点即可,时间复杂度是O(1)
求入度(弧头)难:需要遍历整个邻接表。时间复杂度是O(n+e);
3.给定无向图G,从V0出发进行深度优先遍历访问的边集合为: {(V0,V1), (V0,V4), (V1,V2), (V1,V3), (V4,V5), (V5,V6)}。则下面哪条边不可能出现在G中?
A.(V4,V6) :(V4,V5), (V5,V6)
B.(V0,V6) :从V0出发
C.(V1,V5) :
D.(V0,V2) :(V0,V1),(V1,V2),
4.
在N个顶点的无向图中,所有顶点的度之和不会超过顶点数N的多少倍?
A.1
B.(N−1)/2
C.N−1
D.2
完全无向图的边为N*(N−1)/2,度数为N*(N−1),所以为N-1倍。
5.有向图的邻接矩阵不一定是对称的,因为它是有方向的,假如从a到b是可以通行的,但是从b到a则是逆行,为0。”
首先我们先介绍数的概念。
一、树 树的结点 结点:使用树结构存储的每一个数据元素都被称为“结点”。例如,图 1(A)中,数据元素 A 就是一个结点;
父结点(双亲结点)、子结点和兄弟结点:对于图 1(A)中的结点 A、B、C、D 来说,A 是 B、C、D 结点的父结点(也称为“双亲结点”),而 B、C、D 都是 A 结点的子结点(也称“孩子结点”)。对于 B、C、D 来说,它们都有相同的父结点,所以它们互为兄弟结点。
树根结点(简称“根结点”):每一个非空树都有且只有一个被称为根的结点。图 1(A)中,结点A就是整棵树的根结点。
叶子结点:如果结点没有任何子结点,那么此结点称为叶子结点(叶结点)。例如图 1(A)中,结点 K、L、F、G、M、I、J 都是这棵树的叶子结点。
结点的度和层次 对于一个结点,拥有的子树数(结点有多少分支)称为结点的度(Degree)。例如,图 1(A)中,根结点 A 下分出了 3 个子树,所以,结点 A 的度为 3。
一棵树的度是树内各结点的度的最大值。图 1(A)表示的树中,各个结点的度的最大值为 3,所以,整棵树的度的值是 3。一棵树的度是树内各结点的度的最大值。图 1(A)表示的树中,各个结点的度的最大值为 3,所以,整棵树的度的值是 3。
结点的层次:从一棵树的树根开始,树根所在层为第一层,根的孩子结点所在的层为第二层,依次类推。对于图 1(A)来说,A 结点在第一层,B、C、D 为第二层,E、F、G、H、I、J 在第三层,K、L、M 在第四层。
树的种类: 无序树:树中任意节点的子节点之间没有顺序关系,称为无序树有序树:树中任意节点的子节点之间有顺序关系,称为有序树 二叉树:每个节点最多含有两个子树的树称为二叉树 完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其他各层的节点数目均已达到最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树称为完全二叉树,其中满二叉树的定义是所有叶子节点都在最底层的完全二叉树平衡二叉树(AVL树):当且仅当任何节点的两颗子树的高度差不大于1的二叉树排序二叉树:当我们遍历树中的节点时,是有序的霍夫曼树:带权路径最短的二叉树称为哈弗曼树或最优二叉树B树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多余两个子树 二、二叉树 简单地理解,满足以下两个条件的树就是二叉树:
本身是有序树;树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2; 例如,图 1a) 就是一棵二叉树,而图 1b) 则不是。
图 1 二叉树示意图
二叉树的性质: 性质1:在二叉树的第i层上至多有2^(i-1)个节点(i>0)性质2:深度为k的二叉树至多有2^k-1个节点(k>0)性质3:对于任意一棵二叉树,如果其叶子结点数为 n0,度为 2 的结点数为 n2,则 n0=n2+1 性质 3 的计算方法为:对于一个二叉树来说,除了度为 0 的叶子结点和度为 2 的结点,剩下的就是度为 1 的结点(设为 n1),那么总结点 n=n0+n1+n2。
接收用户输入的年份year和月份month,计算该年该月的天数并输出,
首先我们需要知道平年有365,闰年有366天
其次,能被4整除且不能被100整除则为闰年,若是世纪年(整百年)的话能被400整除的的为闰年。
反之就是平年。
代码如下:
//1.用Scanner类,先导包 import java.util.Scanner; public class If_exercise{ public static void main(String[] args){ //创建实例 Scanner sc = new Scanner(System.in); //使用功能 //用户输入年份和月份 System.out.println("您的输入的年份为?"); int year = sc.nextInt(); System.out.println("您的输入的月份为?"); int month = sc.nextInt(); int day = 0; int days = 0; switch(month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: day = 31; break; case 4: case 6: case 9: case 11: day = 30; break; case 2: if((year % 4 ==0) && (year % 100 !
今天给大家介绍另外的流程控制节点。
流程控制-ForLoop
ForLoop是利用计数器所具备的计数循环次数功能来进行处理的。循环从第一个索引值进来,然后依次增加1,达到最后一个索引的时候循环结束。
First Index:第一个索引值,Last Index:最后一个索引值,Loop Body:循环体
Index:当前索引,Completed:循环结束后执行的操作 数组与ForEachLoop
数组可以对多个值进行集中管理,处理保管于数组中的所有数据时会用到循环。
添加一个数组,并给它添加一些元素
Array连接的时一个建立的数组,LoopBody是循环体,ArrayElement是数组元素,ArrayIndex是数组索引,从0开始,Compieted是完成后的操作。 例子:求数组中元素的平均值 whileLoop
whileLoop需要一个bool值进行判断是否进入到循环中,当bool值为false的时候退出循环。
例子:判断一个数是否是质数
除了1和它本身,不可以被其他书数整除
先判断num数值是否和counter相等,如果为false,再去判断%counter是否为0,如果能被counter整除,它就不是质数,counter每次加1 。
本文首发于 Nebula Graph Community 公众号
前言 Nebula 目前作为较为成熟的产品,已经有着很丰富的生态。数据导入的维度而言就已经提供了多种选择。有大而全的Nebula Exchange,小而精简的Nebula Importer, 还有为 Spark / Flink 引擎提供的Nebula Spark Connector 和 Nebula Flink Connector。
在众多的导入方式中,究竟哪种较为方便呢?
使用场景介绍:
Nebula Exchange 需要将来自 Kafka、Pulsar 平台的流式数据, 导入 Nebula Graph 数据库需要从关系型数据库(如 MySQL)或者分布式文件系统(如 HDFS)中读取批式数据需要将大批量数据生成 Nebula Graph 能识别的 SST 文件 Nebula Importer Importer 适用于将本地 CSV 文件的内容导入至 Nebula Graph 中 Nebula Spark Connector: 在不同的 Nebula Graph 集群之间迁移数据在同一个 Nebula Graph 集群内不同图空间之间迁移数据Nebula Graph 与其他数据源之间迁移数据结合 Nebula Algorithm 进行图计算 Nebula Flink Connector 在不同的 Nebula Graph 集群之间迁移数据在同一个 Nebula Graph 集群内不同图空间之间迁移数据Nebula Graph 与其他数据源之间迁移数据 以上摘自 Nebula 官方文档:https://docs.
在formData添加数组时,会有一个的问题,就是post请求会把数组拼接成一个字符串发送给服务器。
这种时候有两种解决方案
一、后台拿到字符串后,再通过截取字符串来生成数组
二、对数据进行字符串化,即JSON.stringify()
let formData = new FormData();
formData.append('coordinate',JSON.stringify(this.$route.query.position.geometry.coordinates[0]))
这样就能成功以数组形式添加进formData,不过要注意的是,当你想要检索数据时,可以使用JSON.parse()将它解析回一个数组。
《计算机网络》
课程设计报告
题 目 远程文件传输设计方案 班 级 2020级(1)班 学 号
姓 名
院 系 计算机学院 专 业 信息安全
教 师
二O二二 年 六 月 二十五 日
目录:
目录: 1
一、 课程设计内容 3
1、项目背景: 3
2、项目要求: 3
二、 设备选型 3
三、 IP地址规划 3
四、 拓扑图设计 4
五、 主要技术 4
1、RIP2: 4
2、NAT: 4
3、PPPoE: 5
4、FTP: 5
5、CIDR: 5
6、IPv4到IPv6的过度 5
六、 配置清单 5
1、给主机、服务器和路由器命名。 5
2、配置和启动交换机、路由器、主机和服务器接口、IP地址和默认网关。 6
3、RIP2路由配置 7
护网中分析研判是属于高级工程师的工作,是攻防演练能否获胜的核心
响应作为遏制攻击、缩小攻击影响面的具体执行阶段,被视为攻防演练中的关键一步。但在对检测到的事件进行处置之前,有一个对事件从识别到评估的过程。这个过程被称为“攻击研判”,攻击研判相当于整个事件响应流程的“军师”,承担分析判断安全事件和决定处置方式的任务。
攻击研判的定义及重要性 网络安全中的攻击研判,可以理解为人工层面对攻击事件进行再分析的行为。安全人员针对安全系统或工具发出的告警,通过结合已有的经验和相关工具,来判断其是否为真实存在的攻击,并根据判断结果做出响应的响应、给出处置建议。
一般来说,对攻击事件的分析研判通常从以下 4 个维度进行:
对已发现攻击的来源进行研判;综合分析攻击技术、工具和路径,判断其威胁性大小;攻击意图研判;处置方式判断。 攻击研判可以看作安全防护流程最为关键的一环。它上承安全告警的分析,下接安全处置的实施,是安全防护过程中技术含量最高的一步。
一个企业组织,拥有攻击研判能力是至关重要的。这样在发生告警的时候,它可以做出正确的判断,进而实施有效的措施,使情况恢复控制。攻击研判,同时也是事件响应过程中最具挑战性的环节:确定是否发生了事件,事件影响面有多大,后续如何遏制或根除异常、可疑活动。
攻击研判中的团队角色分类 为了有效地处理网络安全事件,企业组织需要一个专门从事攻击研判的团队。这个团队的任务是当安全告警发出时,按照既定计划对事件及时进行分析和判断。
以下是一个组织内进行全面、协调的攻击研判所需的角色列表。用户可以根据企业组织的规模、结构以及监管和行业要求来定制此列表。例如,一个人可以担任几个角色,或者几个人可以协调分担一个角色的责任
攻击研判团队由专业安全人员组成,每个人在处理事件时都发挥着重要作用。
安全运营中心。 对每个安全警报进行分类、收集证据并确定适当的行动。轮班工作的分析师必须对网络安全威胁有广泛的了解,他们能够访问各种安全平台和工具,例如SIEM 和 EDR 解决方案。这些工具会生大量的警报,安全分析师需要能够理解和解释这些数据。如果事件为高优先级或超出技能范围,则需上报事件管理团队。
研判管理团队。 管理团队向相关人员提供证据、建议和意见,并确定事件的节奏,确定需要完成哪些任务、谁来完成,以及应该在什么时候完成。所有事件流转和通信也都由管理团队完成。
安全专家团队。 他们只参与重要或高优先级的事件。与运营中心的分析师拥有广泛的技能组合不同,专家团队由具有专业技能的个人组成,例如恶意软件分析师和数字取证专家。该团队提供专家技术建议和分析,并由管理团队分配任务。
威胁狩猎团队。 尝试确定事件的根本原因并还原攻击路径,为后续响应工作提供信息。确定对手能够在环境中访问和操作的条件。这些条件将为事件分类和事件后续活动提供信息,以调整网络和系统,使其实现更好的安全防护功能
分析研判的 6 个步骤 攻击研判属于安全事件响应的一部分,为了更好地了解攻击研判在整个事件响应过程中的作用,我们可以把列出包括攻击研判在内的事件响应全流程,其中蓝色部分属于攻击研判的流程部分。
在攻防实战中,根据告警发生后防守方的响应流程,我们可以把攻击研判服务,划分为以下6 个步骤:
攻击告警真实性研判 在接到告警研判服务请求后,安全专家通过内置的研判溯源模型并结合实际环境,快速分析告警主机的进程和操作审计事件,确认告警的真假以及攻击者还做了其他哪些操作,明确告警主机是不是已被入侵,安全专家进行系统性的梳理并给出详细的研判分析报告
对在系统发出警报后好做出响应的处置以前,需要对警报进行确认,是误报,还是真的有告警事件发生?如果告警是真实的,那么攻击者是正在试图入侵的过程中,还是已经成功入侵?只有确认告警事件为攻击者已经成功入侵后,才会启动响应处置。
告警研判的结果和对应措施也可以用下表直观地展示出来:对在系统发出警报后好做出响应的处置以前,需要对警报进行确认,是误报,还是真的有告警事件发生?如果告警是真实的,那么攻击者是正在试图入侵的过程中,还是已经成功入侵?只有确认告警事件为攻击者已经成功入侵后,才会启动响应处置。
告警研判的结果和对应措施也可以用下表直观地展示出来
告警研判的结论对应的响应措施告警为误报 不需要处理需要进行策略优化告警为尝试攻击,对系统无影响需要后续持续关注告警为真实告警,告警主机已被入侵需要上报决策组进行应急响应 攻击事件调查 一旦确定了告警的真实性,安全专家要通过主机、流量侧的日志以及系统告警等信息,对攻击事件进行调查。并根据攻击行为特征建立一套通用的方法论,生成《XXX 事件调查报告》。用户可以根据这套方法论在自己的安全设备中添加检测规则,以便在下次面对相同攻击的时候快速做出响应。
在这个过程中,请参阅以下关键问题以全面了解攻击事件:
最初的攻击媒介是什么?(即,攻击方如何获得对网络的初始访问权限?)攻击方如何访问环境?攻击方是否利用漏洞来获得访问权或特权?攻击方如何维持指挥和控制?攻击方在网络或设备上是否有持久性?持久性的方法是什么(例如,恶意软件后门、webshell、合法凭证、远程工具等)哪些账户已被盗用,这些账户是什么权限级别(例如,域管理员、本地管理员、用户账户等)?使用什么方法进行侦察?是否发生横向移动?如何进行横向移动(例如,RDP、网络共享、恶意软件等)?数据是否被泄露,如果有,是什么类型的,通过什么机制? 失陷范围排查 安全事件发生时,对于横向移动主机,安全专家首先会根据现有信息找出一台确认失陷的主机,然后以这台失陷主机的数据以及它的互联关系为线索,在用户系统中展开内网溯源,确认是否存在被横向渗透的主机,并循环此过程逐步找出所有失陷主机,确认攻击影响面及具体的失陷范围。
攻击过程还原 攻击溯源是事件响应的关键,也是安全能力提升的关键。通过对被攻击资产的分析与溯源,还原攻击路径与攻击手法,用户不仅能够有效提升攻防演练效果,还可增强常态化安全防御能力,将攻击事件转换为防御势能,避免二次攻击事件的发生
防守方成果报告整理 在攻防演练中,防守方在完成攻击确认到调查、还原的整个流程之后,需要整理出一份防守报告,阐述攻击的真实性、攻击的覆盖范围、攻击者的攻击路径及行为。并将报告提交给组织方,即可得分。
攻击清除处置建议 最后,根据对攻击者所用技术和攻击路径的反向梳理结果,安全团队要综合分析对方的攻击动机和意图,以及用户自身的防护水平及目的,给出合理的处置建议。
参考文献 GB/T 20988-2007 信息安全技术 信息系统灾难恢复规范
GB/T 22080-2008 信息技术 安全技术 信息安全管理体系-要求
GB/T 22080-2016 信息安全技术 信息安全管理体系要求
GB/T 22081-2008 信息技术 安全技术 信息安全管理实用规则
高速串行通信经常需要用到 XILINX FPGA 内部专用的 SERDESE 模块来实现串并转换。 LVDS 配合 SERDESE可以充分发挥 FPGA 的高速接口优势。 SERDESE 分输入和输出,输入采用 ISERDESE, 输出采用 OSERDESE,OSERDESE 的使用要比 ISERDESE 简单。
本文涉及到一些重要原语概念,包括 idelay 延迟原语,IDELAYCTRL原语, ISERDESE 、OSERDESE。其中很关键一点时使用 idelay 延迟模块以及 ISERDESE 原语中 BITSLIP 功能,实现比特流的时钟对齐,以及数据流的位流顺序对齐。XILINX FPGA 高速通信中经常会用到 idelay模块对信号比特流做细微的时序调整。
参考文档包括:官方手册ug471,xapp585,第三方米联客教程。
1、IDELAYCTRL模块
2、IDELAY模块
3、IDELAY模块工作时序
4、OSERDES模块 OSERDES模块数据传输方式支持SDR,DDR两种,数据位宽支持级联以扩展到14比特。
由上图可知,OSERDES串行输出的数据流与原始并行数据比较,大小端是相反的。
5、ISERDES模块 ISERDESE2 在 SDR 模式下数据转换的位宽可以为 2、 3、 4、 5、 6、 7、 8bit,在 DDR 模式时,数据转换位宽为 4、 6、 8bit, 2 个 ISERDESE2 级联使用, DDR 模式可以支持 10、 14bit。 如下图所示通过 2 个 ISERDESE2 级联输出14bit 位宽数据接口。
CentOS出现localhost login 输入密码无法登录?
一、问题描述
当大家第一次登录Centos时,出现这种情况有三种原因。
原因1:
用户名错误,如果你设置了账户,你们账号就是你设置的那个名称。如果你没有设置账户,那么第一次登录时,你的账号名称应该是root
原因2:
在输入密码时,有的人习惯用电脑右侧最右边的小键盘输入密码,但是NumLock键默认是关闭的,所以我们要先打开,再输入密码。最好是用主键盘上的数字输入密码,不要用小键盘输入密码,这样就没问题了。
原因3:
有的人输出密码后会出现下面这个界面,其实这个界面就是表示你已经登录成功了。只是没有图形化界面,我们不知道已经登录成功了。没有图像化界面的原因是因为在安装Centos时没有选择安装图像化界面,默认只安装的基本配置。
从这里进去选更改设置:
注意:要选择GNOME Desktop才会有图形化界面,系统一般默认是选Minamal Insatll(这个没有图像化界面)。
还有一种情况是你的Centos镜像是Minamal,这种包是没有图像化界面的。如图
建议下载Centos DvD版,然后安装图像化界面就完成了。
这个镜像我放在百度网盘里面了,需要的同学自取。
百度网盘链接:
https://pan.baidu.com/s/1i10YeNYT81Eyl9X6xoox5A
提取码:5wb6
————————————————
版权声明:本文为CSDN博主「计算机卷大饼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45960449/article/details/123144660
简述: 在UIPATH开发环境中搜索SAP,发现有两个SAP登录控件
第一个“SAP登录”是用于打开SAP系统选择的窗口,并选择要进入的SAP系统,如下样式:
第二个“SAP登录”是用于在上一步打开的SAP登录窗口,设置窗口上的参数,并登入SAP系统
步骤 新建一个UIPATH序列,并拖入两个SAP登录控件 配置参数 2.1 配置第一个控件参数
SAP登录路径:控件的默认路径,是电脑里安装的SAP系统路径
连接名称:SAP选择的要登录系统的名称
2.2配置第二个控件参数
“在屏幕上指明”让uipath识别“SAP登录”的窗口
客户端:对应SAP集团
用户名,密码
语言对应SAP登录时选择的语言其中中文是“ZH”
注意填写密码时要选择“标准”才可直接输入密码。
现在运行UIPATH发现机器人操作SAP系统登录成功了。 源码:
实现uipath流程机器人sap登录功能https://download.csdn.net/download/all_night_in/85895125
SQLserver高级编程
1、数据库设计
数据库设计的重要性:
减少冗余,提高性能、易维护
数据库设计的步骤:
1、收集信息、标识对象、标识属性、标识关系(一对一、一对多、多对一、多对多)
E-R图:
属性:定义实体的性质、实体的特征
实体:数据项(属性)的集合
关联:实体之间相互连接的方式
简单理解一下就可以了
数据库规范化:
第一范式(1NF):
每列都应该是原子性的,五重复的域
第二范式(2NF):
在第一范式的基础上属性完全依赖于主键
第三范式(3NF):
第三范式要求各列与主键列直接相关
T-SQL语句创建和管理数据库和表:
T-SQL创建数据库:
if DB_ID('数据库名') is not null drop database 数据库名 go create database 数据库名 on ( name='数据库名', filename='物理数据库储存路径数据库文件' ) 案例:
if DB_ID('Student')is not null drop databese Student go create databese Student on ( name='Student', finema='E:\第二学期\SQL\stuDB\Student.mdf' ) 数据文件参数 描述
name 数据库逻辑名称
filename 数据库物理文件名
size 数据文件初始化大小,单位默认为M
maxsize 数据文件可增长到最大值,单位默认阿M,不指定即无限大
filegrowth 数据库每次增长率,可以是百分比,默认单位M,0不增长
T-SQL语句创建表:
if object_ID('表名')is not null drop table 表名 go create table 表名 ( 字段1 数据类型 列的特性, 字段2 数据类型 列的特性 ) 案例:
树莓派可以作为一个小型电脑,但是它不能像windows一样使用任务管理器查看当前资源占用情况
一、使用指令查看当前资源状态 使用top指令
可以获取当前Cpu使用状态、RAM使用率等信息,但是只能查看,无法长时间运行时保存下来
使用free指令
可以获得Mem信息,但是是以byte为单位,需要转换单位
使用df指令
可以获得文件系统占用的详情
二、用Python语言获取资源状态并存储为txt文件 import os import time import logging # Return CPU temperature as a character string def getCPUtemperature(): res = os.popen( 'vcgencmd measure_temp' ).readline() return (res.replace( "temp=" ," ").replace(" 'C\t "," ")) # Return RAM information (unit=kb) in a list # Index 0: total RAM # Index 1: used RAM # Index 2: free RAM def getRAMinfo(): p = os.popen( 'free' ) i = 0 while 1 : i = i + 1 line = p.
本文目的 1、了解@Autowired的作用
2、从源码探讨是如何工作的
3、如何bebug,跟踪整个过程
4、Spring是如何找到bean哪些属性被@Autowired修饰的
5、找到需要注入的属性,那属性值是又如何找到的
准备 spring framework使用5.2.19版本
idea 2021.3.3
jdk8
greadle 5.6.4
说明 首先从@Autowired的注释下手
Marks a constructor, field, setter method, or config method as to be autowired by
* Spring's dependency injection facilities.
从源码注释得知,@Autowired可以作用于,setter方法、属性、构造器,配置方法【@Configuration的类中的@bean修饰的方法】。
因为比较复杂所以,下面只按属性注入的过程进行源码分析,其他注入过程,其他篇幅再叙说
@Autowired的作用 通过上面的注释说明就已经知道了,它的作用就是依赖注入,可以作用于setter方法、属性、构造器,配置方法,而且上篇文章Spring5.x之IOC也提到过修饰构造器相当于指定哪个构造器实例化。
在这里就得知有两个作用分别是,1、依赖注入;2、参构造器时指定用哪个构造器实例化
目前只得知这两大作用。
源码分析 在得知@Autowired的作用后,那它又是如何工作的呢? @Autowired源码注入流程图
测试代码 package com.csh.spring.dimodule.autowiredAnno; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class AutowiredAnnoTest { @Test public void testByNameOrTypeAndConstruct() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.csh.spring.dimodule.autowiredAnno"); context.refresh(); Object a = context.
Docker 配置 DNS 文章目录 Docker 配置 DNS1. docker配置DNS方法2. 默认DNS配置3. 启动时配置dns参数4. daemon.json配置DNS格式 1. docker配置DNS方法 docker容器配置dns解析地址,我知道的有以下几种办法(优先级从高到低):
启动的时候加–dns=IP_ADDRESS;守护进程启动参数中添加DOCKER_OPTS=“–dns 8.8.8.8” ;在/etc/docker/deamon.json中添加dns信息(与守护进程参数会冲突不能同时添加。);使用宿主机的/etc/resolv.conf文件; 2. 默认DNS配置 怎样为Docker提供的每一个容器进行主机名和DNS配置,而不必建立自定义镜像并将主机名写 到里面?它的诀窍是覆盖三个至关重要的在/etc下的容器内的虚拟文件,那几个文件可以写入 新的信息。你可以在容器内部运行mount看到这个:
$ mount ... /dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ... /dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ... /dev/disk/by-uuid/1fec...ebdf on /etc/resolv.conf type ext4 ... ... 3. 启动时配置dns参数 OptionsDescription-h HOSTNAME or --hostname=HOSTNAME在该容器启动时,将HOSTNAME设置到容器内的/etc/hosts, /etc/hostname, /bin/bash提示中。–link=CONTAINER_NAME or ID:ALIAS在该容器启动时,将ALIAS和CONTAINER_NAME/ID对应的容器IP添加到/etc/hosts. 如果 CONTAINER_NAME/ID有多个IP地址 ?–dns=IP_ADDRESS…在该容器启动时,将nameserver IP_ADDRESS添加到容器内的/etc/resolv.conf中。可以配置多个。–dns-search=DOMAIN…在该容器启动时,将DOMAIN添加到容器内/etc/resolv.conf的dns search列表中。可以配置多个。–dns-opt=OPTION…在该容器启动时,将OPTION添加到容器内/etc/resolv.conf中的options选项中,可以配置多个 如果docker run时不含--dns=IP_ADDRESS…, --dns-search=DOMAIN…, or --dns-opt=OPTION…参数,docker daemon会将copy本主机的/etc/resolv.conf,然后对该copy进行处理(将那些/etc/resolv.conf中ping不通的nameserver项给抛弃),处理完成后留下的部分就作为该容器内部的/etc/resolv.conf。因此,如果你想利用宿主机中的/etc/resolv.conf配置的nameserver进行域名解析,那么你需要宿主机中该dns service配置一个宿主机内容器能ping通的IP。
如果宿主机的/etc/resolv.conf内容发生改变,docker daemon有一个对应的file change notifier会watch到这一变化,然后根据容器状态采取对应的措施:
一:两种部署包: 部署之前先说下两种包,java项目部署到服务器一般有用war包的,也有用jar包的,微服务spring-cloud普及后大部分打包都是jar,部署之前先搞清楚自己要打war包还是jar包,下面小介绍两种包的区别:
spring boot既可以打成war发布,也可以找成jar包发布。说一下区别:
jar包:直接通过内置tomcat运行,不需要额外安装tomcat。如需修改内置tomcat的配置,只需要在spring boot的配置文件中配置。内置tomcat没有自己的日志输出,全靠jar包应用输出日志。但是比较方便,快速,比较简单。
war包:传统的应用交付方式,需要安装tomcat,然后放到waeapps目录下运行war包,可以灵活选择tomcat版本,可以直接修改tomcat的配置,有自己的tomcat日志输出,可以灵活配置安全策略。相对打成jar包来说没那么快速方便。
个人比较偏向打成jar包的方式发布应用,因为spring boot已经内置了tomcat,无需额外配置。其实可以搜索下spring
boot的特点,有个非常重要的特性就是spring
boot把市面优秀的开源技术,都集合起来,方便快速应用。技术没有百分百这种好,也没有百分百那种不好,存在即合理,最主要还是看个人习惯和业务场景需求了。
二:jar包署部署(推荐) 先说下jar包怎么部署启动项目,这里的jar包前提是springboot项目打的,pom文件已经设置过了入口文件等相应设置,具体设置这里就不说了。
先把jar包上传到Linux服务器 1.安装 xshell 、xftp软件
Xshell功能简介
Xshell [1] 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。
Xshell可以在Windows界面下用来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。除此之外,其还有丰富的外观配色方案以及样式选择。
Xftp 功能简介
是一个基于 MS windows 平台的功能强大的SFTP、FTP 文件传输软件。使用了 Xftp 以后,MS windows 用户能安全地在 UNIX/Linux 和 Windows PC 之间传输文件。Xftp 能同时适应初级用户和高级用户的需要。它采用了标准的 Windows 风格的向导,它简单的界面能与其他 Windows 应用程序紧密地协同工作,此外它还为高级用户提供了众多强劲的功能特性。
2.通过安装以上两个软件可以实现window电脑远程控制Linux服务器,这样就可以将我们打包好的jar文件传输到Linux服务器上进行项目的部署。
假设Linux服务上已经有了打好的jar包,下面介绍几种常用的部署方式:
1、java -jar启动方式。
java -jar *.jar 此中方式只会运行在当前窗口,当关闭窗口或断开连接,jar程序就会结束。
2、nohup启动方式。(推荐)
# nohub: 不挂断的运行命令 # &:后台运行 # >: 日志重定向输出到 nohub java -jar *.
首先, 定义结构体, 年, 月, 日
struct date{
int month;
int day;
int year;
};
然后,就可以输入今天的日期了
struct date today,tomorrow;
printf("Enter today's date(mm dd yyyy):");
scanf("%i %i %i",&today.year,&today.month,&today.day);
这里需要判断平年和闰年, 所以先调用一个函数
bool isLeap(struct date d) { bool leap = 0; if((d.year %4==0 && d.year %100 !=0) || d.year%400 == 0){ leap = 1; } return leap; } 返回的数值,就可以判断润平年了
我们思考一下,现在知道二月的天数了, 所以,我们要想知道明天日期,只用号数加一就可以了, 这里需要使用if 语句进行逐层排除
最简单的就是 , 只用号数加一天, 别的不用变, 所以我们要确保今天不是本月的最后一天, 所以就是拿着今天的号数和本月的天数作对比
today.day != number0fDays(today)
所以, 这里我们又需要进行, 调用一个含有结构体的函数, 来判断本月的天数了, 因为还要掺杂二月, 所以也得调用判断润平年的函数
高性能 Go 语言发行版优化与落地实践 | 青训营笔记 这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
内存方面 一、自动内存管理 概念: Mutator:业务线程,分配新对象,修改对象指向关系(创建的goroutine)
Collector:GC线程,找到存活对象,回收死亡对象的内存空间
Serial GC:只有一个collector
Parallel GC:支持多个collectors同时回收的GC算法
Concurrent GC:mutator(s)和collector(s)可以同时执行
GC: GC算法:安全性、吞吐率、暂停时间、内存开销
追踪垃圾回收:
标记根对象标记可达对象清理不可达对象根据对象的生命周期使用不同的标记和清理策略 分代GC:
年龄:经历过GC的次数
目的:针对不同年龄年轻或者老年的对象,制定不同的GC策略,降低整体内存管理的开销
引用计数:
每个对象有与之关联的引用次数,大于0则是存活缺点是无法回收环形数据结构、维护引用计数开销较大 二、Go内存管理及优化 内存分配: 分块
缓存
管理优化
go的内存分配
实际优化方案:Balanced GC 编译器优化 一、编译器和静态分析 编译器结构: 静态分析: 过程内分析、过程间分析: 二、Go编译器优化 函数内联: 逃逸分析: 静态分析: 过程内分析、过程间分析: 二、Go编译器优化 函数内联: 逃逸分析: Beast mode
高质量编程与性能调优实战 | 青训营笔记 这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
高质量原则:1、简单性 2、可读性 3、生产力
注释规范 代码是最好的注释,注释应该提供代码未表达出的上下文信息,公共符号始终要注释
注释应该解释代码作用注释应该解释代码如何做的注释应该解释代码实现的原因注释应该解释代码什么情况会出错 命名规范 变量命名 包含变量名的信息量有特定的含义避免传入错误的值,造成非预期的错误 函数命名 不携带包名的上下文信息
尽可能简短
eg:
包名命名 只由小写字母组成。不包含大写字母和下划线等字符包含一定上下文信息不与标准库同名。 编码规范 控制流程 避免嵌套
如果if else的两个分支都包含return语句,则可以去除冗余的else方便后续维护,else一般是正常流程,如过需要在正常流程新增判断逻辑,避免分支嵌套
优先处理错误和特殊情况,尽早返回或继续循环来减少嵌套
错误和异常处理 简单错误 优先使用errors.New来创建匿名变量来直接表示简单错误如果有格式化的需求,使用fmt.Errorf 复杂错误(Wrap和Unwrap) Wrap提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链
在fmt.Errorf中使用:%w关键字来将一个错误关联至错误链中
错误判定 特定错误:使用errors.Is来判断是否为特定错误。不同于使用==,使用该方法可以判定错误链上的所有错误是否含有特定错误
特定种类的错误:在错误链上获取特定种类的错误,使用errors.As
panic(注意!我项目里老爱用) 只用于真正异常的情况
不建议使用(当程序启动阶段发生不可逆转的错误时,可以在init或main函数中使用panic)
recover recover生效范围,在当前goroutine的被defer的函数中生效嵌套无法生效
defer的语句是后进先出
常见情况是记录panic的调用栈信息,出现问题时能够方便分析定位。如果需要更多的上下文信息,可以recover后在log中记录当前的调用栈
性能优化(Benchmark工具) slice使用建议 slice预分配内存,预估空间
尽可能在使用make()初始化切片时提供容量信息,避免多次拓展(因为要在内存中新开辟一个更大的空间存放并并复制,很浪费)可使用copy代替新建一个slice(避免调用原切片占用的巨大空间,使得原切片的大内存得不到释放) map使用建议 预分配内存,预估空间,以减少内存拷贝和Rehash消耗
字符串处理 三种字符串拼接方式中,strings.Builder最快,bytes.Buffer其次,+最慢
当使用+拼接2个字符串时,生成一个新的字符串,就需要开辟一段新的空间,新空间的大小是原来两个字符串的大小之和。拼接第三个字符串时,再开辟一段新空间、新空间大小是三个字符串的大小之和,以此类推
而strings.Builder,bytes.Buffer底层都是[]byte 数组内存扩容策略,不需要每次拼接时重新分配内存
空结构体 空结构体不占据内存空间,可作为占位符使用
实现Set,可以考虑用map来代替对于这个场景,只需要用到map的键,而不需要值即使是将map的值设置为bool类型,也会多占据1个字节空间 atomic包和加锁的区别 锁是通过操作系统实现,属于系统调用
atomic操作是通过硬件实现,效率比锁高
sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量
对于非数值操作,可以使用atomic.Value,能承载一个interface{}
调度类 不同的进程采用不同的调度策略,目前Linux内核中默认实现了4种调度策略,分别是deadline、realtime、CFS 和 idle,它们分别使用struct sched_class来定义调度类。
调度类 描述 调度策略
dl_sched_class deadline调度器 SCHED_DEADLINE
rt_sched_class 实时调度器 SCHED_FIFO、SCHED_RR
fair_sched_class 完全公平调度器 SCHED_NORMAL、SCHED_BATCH
idle_sched_class idle task SCHED_IDLE
激活进程调度(Scheduler Core)层: 可以用两种方式激活调度,一种是直接的主调度器,比如进程打算睡眠或者其他原因放弃CPU;另外一种是通过周期性调度器,以固定的频率运行,不时检测是否有必要进行进程切换
PS:
3.与fork的交互
除了以上两种场景,即周期性调度器以及主调度器之外,fork创建出新进程的时候也会出现与调度器类的交互,其入口函数是sched_fork:
// kernel/sched/core.c int sched_fork(unsigned long clone_flags, struct task_struct *p) { if (p->sched_class->task_fork) p->sched_class->task_fork(p); } sched_fork函数中会调用到对应调度器类的task_fork成员函数来处理,下面讲到CFS调度器的时候再详细分析对应的函数。
上下文切换: 当进程A切换到进程B的时候,如何能正常切换回去,需要保存当时的现场,包含用户空间的页表、用户空间的栈和硬件上下文信息
struct sched_class { const struct sched_class *next;//指向下一个调度类,按照优先级 void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);//向该调度类的runqueue(就绪队列)中添加进程 void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);//向该调度类的runqueue(就绪队列)中删除进程 void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags);//当一个进程被唤醒或者创建的时候,需要检查当前进程是否可以抢占当前cpu上正在运行的进程,如果可以抢占需要标记TIF_NEED_RESCHED flag。 //从runqueue中选择一个最适合运行的task struct task_struct * (*pick_next_task)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf); 优先级 Linux 进程 分为 3 种类型 , "
一、安装环境 操作系统:银河麒麟v10 sp1 x86_64
内核版本:4.19.90-23.8.v2101.ky10
PostgreSQL版本:11.16
二、安装过程 2.1 下载源码包 创建目录 mkdir -p /tools/postgresql
wget https://ftp.postgresql.org/pub/source/v11.16/postgresql-11.16.tar.gz -P /tools/postgresql 2.2 安装依赖包及准备 yum -y install openssl-devel libxml2-devel libxslt-devel python-devel cmake gcc-c++ zlib-devel bzip2 readline-devel expect git uuid-devel systemd-devel gcc automake autoconf libtool make vim wget
创建用户:
useradd postgres
修改密码:
echo "PGsql@123456" | passwd --stdin postgres
创建安装目录及修改权限
mkdir -p /usr/local/postgresql
chown -R postgres:postgres /usr/local/postgresql
2.3源码编译安装 2.3.1 解压源码包 cd /tools/postgresql
tar -xvf postgresql-11.16.tar.gz
2.3.2 执行configure
一起来探究MySQL吧! 一、连接管理二、解析与优化2.1查询缓存2.2语法解析2.3查询优化 三、存储引擎 一、连接管理 客户端进程可以采用TCP/IP、命名管道或共享内存、UNIX域套接字等几种通信方式与服务器进程建立连接。每当有一个客户端进程连接到服务器进程时,服务器进程都会创建一个线程来专门处理与这个客户端的交互;当该客户端退出时会与服务器断开连接,服务器并不会立即把与该客户端交互的线程销毁,而是把它缓存起来,当另一个新的客户端进行连接时,会把这个缓存的线程分配合该新客户端。这样就不用频繁地创建和销毁线程,从而节省了开销。 从这点大家也能看出,MySQL服务器会为每一个连接进来的客户端分配一个线程,但是线程分配得太多会严重影响系统性能,所以我们也需要限制可以同时连接到服务器的客户端数量。在客户端程序发起连接时,需要携带主机信息、用户名、密码等信息,服务器程序会对客户端程序提供的这些信息进行认证。如果认证失败,服务器程序会拒绝连接。另外,如果客户瑞程序和服务器程序不运行在一台计算机上, 我们还可以通过采用传输层安全性(TransportLayer Security,TLS) 协议对连接进行加密,从而保证数据传输的安全性。
当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求。MySQL服务器接收到的请求只是一个文本消息,该文本消息还要经过各种处理。欲知后事如何,请继续往下看。
二、解析与优化 到现在为止,MySQL 服务器已经获得了文本形式的请求,接着还要经过“九九八十一难”的处理,其中几个比较重要的部分分别是查询缓存、语法解析和查询优化。下面我们详细来看。
2.1查询缓存 如果我问你9 + 8 * 16- 3 * 2 * 17的值是多少,你可能会用计算器去算一下,或者再厉害一点直接心算, 最终得到了结果357。如果我再问你一遍9 + 8 * 16 - 3 * 2 * 17的值是多少,你还会傻呵呵地算么? 我们刚刚已经算过了,直接说答案就好了。
MySQL服务器程序处理查询请求的过程也是这样,会把刚刚处理过查询请求和结果缓存起来。如果下一次有同样的请求过来,直接从缓存中查找结果就好了,就不用再去底层的表中查找了。这个查询缓存可以在不同的客户端之间共享。也就是说。如果客户端A刚刚发送了一个查询请求, 而客户端B之后发送了同样的查询请求,那么客户端B的这次查询就可以直接使用查询缓存中的数据了。
当然,MySOL服务器并没有人那么聪明,如果两个查询请求有任何字符上的不同(例如,空格、注释、大小写),都会导致缓存不会命中。另外,如果查询请求中包含某些系统函数、用户自定义变量和函数、系统表,如myql、information_schema、performance_schema数据库中的表,则这个请求就不会被缓存。以某些系统函数为例,同个函数的两次调用可能会产生不一样的结果。比如函数NOW,每次调用时都会产生最新的当前时间。如果在两个查询请求中调用了这个函数,即使查询请求的文本信息都一样,那么不同时间的两次查询也应该得到不同的结果。如果在第一次查询时就缓存了结果,在第二次查询时直接使用第一次查询的结果就是错误的!
不过既然是缓存,那就有缓存失效的时候。MySQL 的缓存系统会监测涉及的每张表,只要该表的结构或者数据被修改,比如对该表使用了INSERT、UPDATE、DELETE、TRUNCATE TABLE、ALTER TABLE、DROP TABLE或DROP DATABASE语句,则与该表有关的所有查询缓存都将变为无效并从查询缓存中删除!
虽然查询缓存有时可以提升系统性能,但也不得不因维护这块缓存而造成一些开销.比如每次都要去查询缓存中检索,查询请求处理完后需要更新查询缓存,需要维护该查询缓存对应的内存区域等、从MySQL 5.7.20开始,不推荐使用查询缓存,在MySQL 8.0中直接将其删除。
2.2语法解析 如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。因为客户端程序发送过来的请求只是一段文本,所以MySQL服务器程序首先要对这段文本进行分析,判断请求的语法是否正确,然后从文本中将要查询的表、各种查询条件用都提取出来放到MySQL服务器内部使用的一些数据结构上。
从本质上来说,这个从指定的文本中提取出需要的信息算是一个编译过程,涉及词法解析、语法分析、语义分析等阶段。这些问题不属于我们讨论的范畴,大家只要了解在处理请求的过程中需要这个步骤就好了。
2.3查询优化 在语法解析之后,服务器程序获得到了需要的信息,比如要查询的表和列是哪些、搜索条件是什么等。但光有这些是不够的,因为我们写MySQL语句执行效率可能并不是很高,MySQL的优化程序会对我们的语句做一些优化,如外连接转换为内连接、表达式简化、子查询转为连接等一堆东西。优化的结果就是生成一个执行计划,这个执行计划表明了应该使用哪些索引执行查询,以及表之间的连接顺序是啥样等等。我们可以使用EXPLAIN语句来查看某个语句的执行计划。
三、存储引擎 到服务器程序完成了查询优化为止,还没有真正地去访问真实的表中的数据。MySQL服务器把数据的存储和提取操作都封装到了一个名为存储引擎的模块中。 我们知道,表是由一行一行的记录组成的,但这只是一个逻辑上的概念。在物理上如何表示记录,怎么从表中读取数据以及怎么把数据写入具体的物理存储器上,都是存储引擎负责的事情。为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表可能有不同的存储结构,采用存取算法也可能不同。
为什么叫引擎呢?可能这个名字更拉风吧,其实这在存储引擎以前叫作表处理器,后来可能人们觉得太土,就改成了存储引擎。它的功能就是接收上层传下来的指令, 然后对表中的数据进行读取或写入操作。
MySQL支持的存储引擎:
存储引擎对于某些功能的支持情况:
以上内容出自《MySQL是怎样运行的——从根儿上理解MySQL》。
希望上面我的分享对你有所帮忙,谢谢!
配置交叉编译工具链和环境变量 1 设置交叉编译工具链1.1 永久生效1.2 临时生效1.3 手动指定 2 测试交叉编译工具链2.1 测试环境变量2.2 测试交叉编译器 3 如何添加交叉编译工具链(toolchain)到环境变量?(--sysroot路径)(新:ubuntu交叉编译工具链环境变量的配置) 原文链接:https://blog.csdn.net/qq_56926420/article/details/122890366
1 设置交叉编译工具链 交叉编译工具链用来在Ubuntu主机上编译应用程序,而这些应用程序是在ARM等其他平台上运行。
设置交叉编译工具主要是设置PATH, ARCH和CROSS_COMPILE三个环境变量,下面介绍具体设置方法。
设置这3个环境变量有多种方法,任意选择其中一种方法即可,建议使用“永久生效”的方法。录制视频时我会使用多种开发板,所以在视频里我总是使用“临时生效”的方法。
库环境变量设置:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH=/usr/local/X11/lib:$LD_LIBRARY_PATH/ 1.1 永久生效 如需永久修改,请修改用户配置文件。
注意:如果不会使用vim命令,可以使用图形化的编辑工具,执行:gedit ~/.bashrc
vim ~/.bashrc
(1)
在行尾添加或修改,加上下面几行(第3行第4行为一行命令):
export ARCH=arm export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin 设置完毕后,要执行 source ~/.bashrc 命令使其生效,这条命令是加载这些设置的环境变量。 设置完毕后,要执行 source ~/.bashrc 命令使其生效,这条命令是加载这些设置的环境变量。
book@100ask:~$ source ~/.bashrc book@100ask:~$ arm-buildroot-linux-gnueabihf-gcc -v 1.2 临时生效 也可以手工执行“export”命令设置环境变量,该设置只对当前终端有效(另开一个终端需要再次设置)。
(1)
执行以下3个命令,第3个命令很长,需要包含第四行全部复制:
book@100ask:~$ export ARCH=arm book@100ask:~$ export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin 1.3 手动指定 先设置PATH环境变量,然后在make编译时指定ARCH架构 CROSS_COMPILE交叉编译工具链(执行make命令时指定的参数,只对当前命令有效;下次执行make时仍需要再次指定那些参数)。
哈喽大家好,我是保护小周ღ,本期为大家带来的是编程实现输入某年某月某日,输出它是这一年的第几天,一起来看看把~
题目: 多组输入,编程实现输入某年某月某日,输出它是这一年的第几天。
(注意数据输入范围)
实例1: 输入: 2021-5-1
输出: It is not a leap year.
Today is the 121 day of the year.
实例2: 输入: 2000-5-1
输出: It is a leap year.
Today is the 122 day of the year.
实例3: 输入: 2020-13-12
输出: Input error, please re-enter the date.
思路解析: 首先我们输入一个日期,我们可以定义三个变量year,month,day,代表年月日,也可以用结构体描述一个日期。利用switch(month)函数判断该年月日有多少天,输入年份,如果该年是闰年,那么该年的2月有29天,否则2月只有28天。
一个月有31天的月份有1 3 5 7 8 10 12
一个月有30天的月份有4 6 9 11
闰年的判断条件,年份能被4整除且不能被100整除,但是能够被400整除的才算闰年。
题目还涉及到多组输入,这个问题我们就要了解一下scanf()函数;scanf()是针对标准输入流的格式化输入函数。
怎样实现多组输入呢? scanf() 函数是有返回值的,scanf()的返回值是已经成功赋值的变量个数,且为整型。
例如:
int size=scanf("
原题链接:https://vjudge.net/problem/UVA-1380
分类:树形DP
备注:树的性质
题意:每次输入是一棵树,其中有有向边和无向边。根据拓扑顺序将树上的点全部消除,也就是入度为0的点才能被消除,问最少需要几步能消除完所有点。同时注意,无向边连接的两个点不能同时被消除。
因此问题可以转化为对每一条无向边选择一个方向来对点进行消除。因为是树的结构,所以答案的范围很特殊。设忽视无向边时的最长有向链的边数为k(边数为节点数-1),那么把无向边定好方向后答案必定是k+1或k+2。
在紫书中是这么做的,从根节点递归,将字节点判断完之后再判断自身。设当前节点为i,字节点以w表示。在保证最长链节边数不超过k的前提下, f(i)表示从后代到i的最长链边数的最小值,g(i)表示从i到后代的最长链边数最小值。
假设后代的f和g都已经指的,那么对于当前节点i,求f(i)需要在f(i)+g(i)<=k的前提下使得f(i)最小。找出所有没定向的后代w,按照f(w)从小到大排序。可以假定选取f值第p小的w定向为w->i,那么如果让f值最小到第p-1小的w也定位w->i,则不会使得f(i)变得更大,而有可能使得g(i)变得更小,而从第p+1小到最大的w定向为i->w,然后可以计算出当前假定状态的g(i),这里就获得了对一个点所有无向边的定向方案。同样,对于g(w)也可以从小到大排序,得到同样多的定向方案。
如果存在方案使得f(i)+g(i)<=k可以选取,那这个方案就是合法的。然后i的父亲又需要根据i的f值和g值计算新的f和g,那么最好选取的方案是f和g最小的方案。
这里有个疑问:对于节点i要存取的f值和g值可能不能在同一种状态下出现,但就这么保持对f和g的最优也可以获得正确答案是为什么呢?我认为对于i的父节点fa,如果它们之间是无向边,则如果选择fa->i,那么节点fa只能利用到i的g(i)值,如果选择i->fa,则只能利用到i的f(i)值,也就是说父节点不会同时用到子节点的f和g值,那么让用到的那个值是最优的是没有问题的,所以对于特定节点的f和g可以独立地获取最优值,对父节点的计算不会产生影响。
按照上述方式,只要在每个节点都有合法方案,总能找到f(i)+g(i)<=k,那么答案就是k+1,否则答案为k+2
#include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 205; struct Edge { int u, v, d; Edge(int u=0, int v=0, int d=0):u(u), v(v), d(d) {} }; vector<Edge> e[maxn]; int f[maxn], g[maxn], have_father[maxn], maxlen; int dfs(int u) { int ans = 0; for (int i = 0; i < e[u].size(); i++) { int v = e[u][i].
本章目录 引言工程建立及WebView2包安装建立WPF工程安装WebView2 Nuget包 使用WebView2控件结语 引言 在上一篇文章中,我们介绍了WebView2的环境搭建,点此前往,在这一章节,我们将使用WebView2简单搭建一个WPF程序,在程序中加载百度搜索页面,废话不多说,直接上流程。
工程建立及WebView2包安装 建立WPF工程 建立WPF工程步骤很简单,在此不再截图,直接上步骤:
打开Visual Stido 2022(博主使用的是vs 2022,其他版本也可)选择创建新项目在项目模板处选择WPF应用程序输入项目名称选择项目框架创建完成 选择版本时需要注意,vs 2022中有两种WPF工程模板:WPF应用程序和WPF应用,其中WPF应用程序是使用.net core/.net 6框架的,WPF应用使用.Net Framework框架,大家根据自己的需求创建即可
安装WebView2 Nuget包 打开Nuget包管理器:选中项目->右键->选择“管理NuGet程序包”。
在浏览选项卡中搜索WebView2包,选择Microsoft.Web.WebView2包,并点击安装。
使用WebView2控件 打开项目中的MainWindow.xaml文件,然后添加WebView2的命名空间: xmlns:webview2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" 在Grid控件中,添加WebView2控件,并填写Source属性,这个属性是用来标识加载的网址,在这里我们填入百度的网址。 <Window x:Class="WebViewDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:webview2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <webview2:WebView2 Source="https://www.baidu.com" /> </Grid> </Window> 最后,附上一张运行截图
结语 至此,一个简单使用WebView2加载网页的Demo就已经完成,可以看出WebView2整体使用是比较简单的,也没有比较复杂的配置,其Nuget包提交也较小,在使用简单使用上比CefSharp还是有一定优势的,后续我们将深入使用WebView2,实现一些复杂功能,敬请期待!
使用WebView2的相关代码已经上传至GitHub中,有需要的可以自行下载,码字不易,顺手给个 Star 吧!
欢迎关注博主个人博客,有更多精彩内容哦!
目录 引言WebView2系统要求WebView2下载安装结语 引言 在WPF开发中,经常会有混合开发的需求,即在WPF中加载网页,目前最常用也是最流行的方式是CefSharp,它的功能非常强大,可以提供较为完善的开发和使用体验,但是CefSharp也有一定的缺点,如体积过大,配置繁琐等。
值得兴奋的是,微软基于Edge浏览器推出了webview2控件,用于解决混合开发的痛点,下面就一起来了解一下吧!
WebView2系统要求 WebView2是基于Microsoft Edge浏览器的,其对所使用的操作系统环境有一定要求,支持以下系统:
Windows 11Windows 10Windows 10 IoT 企业版 LTSC x32 2019Windows 10 IoT 企业版 LTSC x64 2019Windows 10 IoT 企业版 21h1 x64Windows 8.1Windows 7 **Windows Server 2019Windows Server 2016Windows Server 2012Windows Server 2012 R2Windows Server 2008 R2 ** 对于Windows 7 和 Windows Server 2008 R2支持是有一定限制的,详细可查看:微软文档。
WebView2下载安装 WebView2提供了三种方式的安装,可根据需求进行下载安装,详细对比请看下表:
常青版引导程序常青版独立安装程序已修复版本安装程序引导包,双击后会自动下载最新的WebView2并安装到计算机中WebView2安装程序WebView2安装程序跟随系统更新,更新版本不需再次安装跟随系统更新,更新版本不需再次安装安装的是特定版本,需控制版本,安装其他版本需要再次下载安装体积极小体积较大体积较大不可离线使用,必须联网可离线安装可离线安装 推荐开发人员使用长青版安装程序,在此我选择常青版引导程序安装:
安装过程就不再赘述,一路点下一步即可,安装完成后可在设置->应用->应用和功能中查看安装的好的程序:
结语 至此,WebView2的环境已经搭建完毕。如果代码中有什么出错或者不清楚的地方,欢迎大家批评指正哦。
电子信息类推免经验 个人基本信息推免面试院校:推免经验及注意事项一、推免流程一、时间安排二、注意事项 二、准备材料三、目标定位四、联系老师五、面试流程及注意问题六、面试院校及注意问题 个人基本信息 本科院校:某末流211
本科专业:电子信息科学与技术
绩点排名:1/58
推免排名:1/58
奖励荣誉:国家级奖项1项,省级奖项5项,校级奖项若干、
最终去向:某985高校信息与通信工程(学硕)
推免情况:主要面试各高校电子信息类专业,例如通信、信号处理等方向,也包含少量部分高校的自动化、电子科学与技术等方向的面试。
面试院校:参与面试的院校清单如下文所述,关于具体院校的面试经验、面试真题等可以关注公众号舒意的碎碎念获取,面试经验及真题正在公众号逐步更新中,敬请关注。
注:面试经验、面试真题可关注公众号:舒意的碎碎念。对于推免经验可点击下方视频链接观看,由于文字阐述有限,视频中的信息会更加详细,大家可移步视频观看。
推免面试院校: 北京航空航天大学信息与通信工程学院电子科技大学信息与通信工程学院上海科技大学信息科学与技术学院北京交通大学计算机与信息技术学院北京理工大学信息与电子学院山东大学机电与信息工程学院兰州大学信息科学与工程学院中科院上海高等研究院中科院西安光机所中科院沈阳自动化所东南大学显示科学与技术中国科学院空天信息研究院 推免经验及注意事项 一、推免流程 一、时间安排 首先,推免早期直到6月份前都要及时关注各院校的保研信息,对目标院校的推免动态要保持时刻的关注,同时认真准备专业课和一些必要的申请材料,例如个人简历、自我介绍、成绩单以及获奖证书的等,尤其注意,这些材料都要准备好电子版,由于疫情原因,近两年的推免面试基本都是线上,因此材料的提交等都是提交电子版,所以个人材料的电子版都要保存和整理好。
6,7月份会迎来推免面试的第一个高峰期-夏令营,这个时期可以关注一些保研相关的公众号、及时关注各个院校推免信息,并根据各院校要求投递申请;其次是这个阶段可以尝试联系目标院校的老师,很多院校联系老师占据很大的比例,联系老师要趁早!再是认真复习专业课,等待面试通知,最后通过面试收获第一波offer。
在经历夏令营这段时间后,9月份会迎来第二个面试高峰-预推免阶段,这是第二次面试机会,夏令营期间未通过的院校可以继续申请,预推免的简历筛选通过概率增加,但面试难度也会有所增加,是“宽进严出”类型,此阶段认真准备面试即可收获第二波offer。
时间到达系统填报日期,对于已经确定学校的同学可以直接填报系统等待录取,对于还没有满意offer的同学,可以在此时期进行“捡漏”,参加一些学校的面试,这个时候就是高风险高收益,可能会收到意想不到的offer。
二、注意事项 对于课程的复习,电子信息类专业一是包括高数、线代、概率论、C语言等基础课程,二是专业课主要包含数字信号处理、通信原理、信号与系统等,针对不同的面试方向专业课也会有略微的不同。其次是面试主要考察一些定义性的知识,所以需要多关注定义、考虑对于一些定理、参数怎样使用语言去定义和描述。要及时关注院校的保研信息,可以通过保研公众号、论坛等获取信息。这里举例一些:后保研;保研通;保研党;保研论坛。另外,可以关注目标院校的官网,从而及时获取推免信息。 二、准备材料 准备的材料大致包括以下四部分:
个人简历:要注意(1)简历排版简单,不要太过花哨。推荐一个在线简历制作网站:超级简历(2)尽量使用教育邮箱(3)简历内容:科研经历写自己最熟悉的、和未来研究方向相关的,对于不熟悉的科研经历不要写,否则可能成为减分项(4)简历使用PDF格式,减少乱码问题的出现电子版的材料:扫描件:成绩单、排名表、获奖证书、四六级证书、
计算机证书、身份证、学生证、大创证明、学籍报告书面材料:面试中英文自我介绍、中英文个人陈述
联系老师邮件、部分学校需要PPT式简历各院校系统填报材料:各院校系统填报材料:1.获奖列表 2.简短的个人陈述/申请理由:300-500字
部分材料例如本人的个人简历、中英文介绍、个人陈述已在公众号上传,可酌情参考。 三、目标定位 目标定位非常重要,要尽量在推免前期确定自己的目标方向和院校,这一可以给出一个思考方向:
(1)如果之后比较偏向于走科研学术道路,那么导师更重要(人品、专业能力),且对城市的要求可以适当降低,此外可以尽量申请学硕、直博。
(2)如果之后偏向于硕士之后就业,那么学校的选择可以关注以下几点(1)目标院校综合实力强(2)城市发达(3)可以考虑申请专硕
四、联系老师 联系老师是推免过程中很重要的一环,很多院校的老师占有很多话语权,或者是老师组内面试而非全院整体面试,那么联系老师就很重要。联系老师时要注意(1)邮件主题清晰明了,例如,可以写【推免生自荐】XXXX大学-XXX专业-姓名(2)邮件内容要简介,不要长篇大论,只需要进行一个简短的自我介绍并说明对目标老师的仰慕之意即可,对于想要向老师陈述的具体内容可以在附件中添加个人陈述等(3)附件一般要包含个人简历和成绩单。此外个人陈述等可酌情添加。
五、面试流程及注意问题 (1)面试开始大部分院校会有中文或英文自我介绍环节,一般要求1分钟,或者3分钟等
(2)部分院校还会进行一些英语问题的提问,提问基本是日常问题,包括你的大学、家乡、爱好等(商店中保研资料,面试问题总结包含了英语日常问题的一些总结)
(3)大部分院校会进行专业课的提问,主要关注基础定义(部分专业课的个人总结笔记后期会在商店上线)
(4)对简历中的科研经历提问,面试老师一般关注3个问题:(1)项目内容(2)你在项目中扮演的角色,即自己主要负责项目的哪一部分内容,负责干什么(3)项目过程中遇到了什么困难,怎么解决的
(5)一些院校会在结束时问:你有什么要问我们的问题?可以面试院校准备一个问题进行应对
(6)在面试时要注意着装得体,语速平缓
六、面试院校及注意问题 各个院校有不同的面试方式、注意事项等,具体信息可关注公众号舒意的碎碎念进行详细了解,后续会在该公众号进行实时更新。
由于文字阐述有限,后期会视频分享保研经验,视频内容会比文字版更加详细一些,公众号内也在陆续更新相关的面试真题,有需要的小伙伴可以关注公众号等待后续分享。
注:舒意的碎碎念公众号包含保研面试相关经验分享、电子信息类面试真题、文献管理软件的安装与使用等内容分享,后续也会进行求职其他方面的分享。
客户端client.h
#ifndef CLIENT_H #define CLIENT_H #include <QWidget> #include <QUdpSocket> #include <QTcpSocket> #include <QFile> #include <QFileDialog> #include <QProgressBar> #include <QTimer> #include <QDebug> #include "stdlib.h" namespace Ui { class client; } class client : public QWidget { Q_OBJECT public: explicit client(QWidget *parent = 0); Ui::client *ui; ~client(); private: QTcpSocket *tcpClient; QFile *localFile; QPushButton *btn1,*btn2; QDialog *dialog; //资源选择框 QPushButton *btn3; QProgressBar *bar1; QString filename; //保存文件路径 QByteArray outBlock; //数据缓冲区 qint64 totalBytes; //文件总字节数 qint64 fileSize; //文件名字的字节数 qint64 bytestoWrite; //尚未发送的字节数 qint64 bytesWritten; //已发送的字节数 qint64 loadSize; //每次发送数据的大小 private slots: void updateFileProgress(qint64 numBytes); //更新文件发送进度 void send_File(); //发送文件 void select_File(); //选择文件 void startTransfer(); //发送文件大小等信息 }; #endif // client.
第四章-说说“编码” 网络的价值 V = K × N V = K \times N V=K×N( K K K为价值系数, N N N为用户数量)
香农提出并证明“在被高斯白噪声干扰的信道中,计算最大信息传送速率 C C C的公式”:
C = B log 2 ( 1 + S / N ) C = B{\log _2}\left( {1 + S/N} \right) C=Blog2(1+S/N)其中, B B B是信道带宽(Hz), S S S是信号功率(W), N N N是噪声功率(W)。
当讨论“信噪比”时,以分贝(dB)为单位, S N R = 10 l g ( S / N ) SNR=10lg(S/N) SNR=10lg(S/N)。从公式中表明,信道带宽 B B B限制了比特率的增加,信道容量 C C C还是取决于信噪比以及编码技术。
本文目的 1、知道什么是IOC
2、知道什么是IOC容器
3、知道什么是bean
3、autowireMode的作用
准备 spring framework使用5.2.19版本
什么是IOC 英文:Inversion of Control (IoC) ,中文:控制反转
也称之为依赖注入dependency injection (DI)
这是一个过程,此过程是通过使用直接构造类来控制其依赖的对象的实例化,是依赖bean本身的逆序,因此称之为控制反转。
大白话说明 原先我要使用B但B依赖A,我是先创建A,在创建B时将A传递进去,才使用B。现在我直接使用B创建B和A交给了Spring容器,而你在向Spring容器获取B时,它有就直接返回没有创建,这时发现依赖再先创建A,A创建好再创建B并注入,然后返回B给你使用,整体流程和原先是反着来的。 官网对IOC的解释原文: This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method.
Sentinel 实战:如何接入 Nacos 实现规则持久化? 在前几篇文章里,我们已经知道了如何配置 Sentinel 的降级规则和流量整形规则。不过这套方案还有一个不完美的地方。因为我们配置的这些容错规则并没有被“保存”到某个存储介质中,所以,如果你重新启动 Sentinel 服务器或者重启应用程序,先前配置的所有规则就都消失不见了。那如何才能解决这个问题呢?
这篇文章,我将带你对 Sentinel 的源码做一下二次开发,我们将通过集成 Nacos Config 来实现一套持久化方案,把 Sentinel 中设置的限流规则保存到 Nacos 配置中心。这样一来,当应用服务或 Sentinel Dashboard 重新启动时,它们就可以自动把 Nacos 中的限流规则同步到本地,不管怎么重启服务都不会导致规则失效了。
在前面,我们采取了一种“直连”的方式,将应用程序和 Sentinel 做了直接集成。在我们引入 Nacos Config 之后,现有的集成方式会发生些许的变化,我画了一幅图来帮你从架构层面理解新的对接方式。 从上面的图中,你会发现,Sentinel 控制台将限流规则同步到了 Nacos Config 服务器来实现持久化。同时,在应用程序中,我们配置了一个 Sentinel Datasource,从 Nacos Config 服务器获取具体配置信息。
在应用启动阶段,程序会主动从 Sentinel Datasource 获取限流规则配置。而在运行期,我们也可以在 Sentinel 控制台动态修改限流规则,应用程序会实时监听配置中心的数据变化,进而获取变更后的数据。
为了将 Sentinel 与 Nacos Config 集成,我们需要做两部分改造。
Sentinel 组件二次开发:将限流规则同步到 Nacos Config 服务器。微服务改造:从 Nacos Config 获取限流规则。 接下来我们就开始第一步改造:对 Sentinel 组件进行二次开发吧。
Sentinel 组件二次开发 在开始二次开发之前,我们需要将 Sentinel 的代码下载到本地。你可以从GitHub 的 Releases 页面中找到 1.
目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象 int[] reset() 重设数组到它的初始状态并返回 int[] shuffle() 返回数组随机打乱后的结果 示例 1:
输入 ["Solution", "shuffle", "reset", "shuffle"] [[[1, 2, 3]], [], [], []] 输出 [null, [3, 1, 2], [1, 2, 3], [1, 3, 2]] 解释 Solution solution = new Solution([1, 2, 3]); solution.shuffle(); // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。例如,返回 [3, 1, 2] solution.reset(); // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3] solution.
开门练习 1.盒体触发器:感应装置(用门举例,感应什么时候开门/关门)。
2.事件:为组件添加事件来达到交互的目的(onActorBeginOverlap :开始触发事件,onActorEndOverlap:离开触发事件)。
3.引用:让系统知道事件作用于谁(如开门/关门时,引用对象为门,是让门开/关)。
4.让门旋转:setActorRatation表示actor内所有组件都旋转;setrelativerotation设置局部坐标系下的相对位置旋转;setworldrotation设置世界坐标系下的旋转(世界坐标不会被改变);
5.时间轴:用于过渡,让画面不会那么生硬。点击函数fx,右键添加关键帧设置时间与数值,需要几个关键帧就设置几次;选中关键帧节点右键使用自动进行平滑;注意:上方长度要改为我们设置的时间长度;如开门/关门(第一个关键帧(时间为0,值为0),第二个关键帧(时间为2,值为85)。用2秒开门,开85°的门。
6.play:正向播放,reverse:方向播放,update:更新(每帧美妙的进行更新),新建轨迹与相对应的值相连。play from start:从设置的第一个关键帧开始播放,set new time:自定义播放时间,direction:时间轴方向的判定。
7.Actor:在世界中可以放置或生成的对象。
创建门的蓝图类 Actor和组件区别、门的轴心点修改
1.创建一个蓝图类,在添加组件栏目添加静态网格(staticMesh),静态网格相当于模型,并对其赋予对应的网格体组件进行组合;
2.此处的碰撞触发器叫做BoxCollision合体碰撞(感应装置);并将其与门放到同一级,避免随门一起动,并且若不和门同一级,开关门也可能检测到重叠事件,产生bug;
3.Gate节点:用于流程控制,open相当于插入钥匙,close相当于拔出钥匙决定Gate是否有后续执行;当有了钥匙状态之后通过操作Enter往后执行(处于open);有关对Enter的操作可以使用键盘,此时会用到节点Enable Input或者Disable Input,有关玩家控制使用playercontroller;
4.键盘输入:keyboard +具体哪个键盘值,Enable Inpu:允许输入,Disable Input:禁止输入。
5.按键响应需要有控制器
6.flipflo:执行第一次走a,执行第二次走b,第三次走a,......
7.鼠标点击:on clicked,然后要开启控制器中的点击事件
进行以下设置
1.Enable Input(启用输入)
2.Disable Input(禁用输出)
3.Get Player Controller(获取玩家控制器)
【以上三个组合总而言之就是规定了一个控制角色(Get Player Controller),确定了蓝图可以接受或拒绝操作该角色的玩家从键盘发出的指令:启用输入(Enable Input)禁用输入(Disable Input),一旦该角色满足了触发条件,就启用输入或者禁用输入,即该角色可以获得或者丧失从键盘(这个案例是,下面那个案例是鼠标,总结总结应该接受从设备输入)输入按键的权利,然后触发后面乱七八糟东西的】
4.E【就是按键E】
5.Gate【门,就是当怎么样(在Open或Close满足时)的前提下然后怎么样(Enter个啥玩意)的时候允许触发事件】
6.Flip Flop【切换翻转,就是A和B轮流执行,第一次调用执行A,第二次B,第三次A……】
按键开门具体蓝图:
Set Show Mouse Cursor【设置显示鼠标光标】
On Clicked(点击时)【在需要点击才会触发的组件最右侧细节面板中的事件里找!】
鼠标点击开门完整的蓝图:
注意:要想激活鼠标单击能触发事件,还需要做一个工作:
升降电梯 1.Lerp插值(由A、B、Alpha三部分输入节点和一个Reruen Value输出节点组成,A、B进行数值从A到B的变换过程,A为起始值,B为最终值,Alpha控制A到B转化到了什么程度,类似于进度条从0到100%(即0到1)的转化,Alpha可以和前面的时间轴输出轨道相连,即用时间轴在多少秒内其值从0到1来控制Alpha,用于位置移动,有一个很好过渡效果,A填写电梯位移初始值,B填写电梯位置末值)
2.用了lerp后,时间轴里面可以不设置值。这样时间轴就可以用于设置任何对象,有多个需求时可避免创建很多个时间轴轨迹或者时间轴
具体蓝图
注意时间轴是怎么和后面连线的,时间轴连左侧门,左侧门连右侧门,但是左右两个门要分别设置插值去控制它们位置的变化。
有个坑!由于盒体碰撞检测器会因为门的运动而被再次触发,所以会产生bug(例如在门正在开的同时往门里走,会导致无法触发关闭,必须再次走出来),所以要将两扇门的细节面板中碰撞栏里的“生成重叠事件”对号取消掉。这样才可以保证盒体碰撞检测器不受两扇门的运动的影响。(门的运动也会被算为重叠触发!)
双开门 (此时只需要设置你想把门开到多大即可,不用再手动调初始和结束位置)
通过获取组件一开始位置的方法,将组件的初始位置存储在一个变量中(变量在左侧新建),然后通过再次新建一个变量输入想要移动的参数,用加法(Float+Float)实现门的移动。
此蓝图有bug,因为.Get Relative Location所连接的变量所处的连接位置在触发按键之后,所以一旦在开门动作中(即开关门动作未完成时)再次按键,则会将当前位置存储在变量中,那么再次触发时将不再是我们希望的起始或者结束位置,从而产生bug。
新的节点:
1.Get Relative Location(获取Relative Location)【获取当前相对位置,与此同时还有Get Relative Rotation】
web前端JavaScript嵌入百度地图API最详细的方法 参考百度地图官方api:百度地图官方api
百度地图提供的拾取坐标: 百度地图提供的拾取坐标
加载地图前提:
申请百度地图账号申请开发者填写开发者信息申请AK 点击查看申请步骤 (具体可看个人主页免费视频课程) 一:百度地图概念 百度地图API是百度地图开放平台面向广大政府、企业、互联网等开发者开放的免费地图服务。拥有定位、地图、导航、轨迹、路况、路线规划、搜索,七大基础地图服务能力,并将七大服务能力开放给各行业开发者使用。
二:百度地图特点 1.免费
百度地图API是免费的对于使用者能够减少使用成本。
2.简单
百度地图API中有详细的教程,一步一步的指导使用者学习和使用,对于刚开始使用API或刚开始学习编程的人来说比较方便。
3.功能齐全
百度地图API提供的功能较多,有定位、地图、导航、轨迹、路况、路线规划、搜索,七大基础地图服务,并且都是常用的实用性较强。
4.支持性较好
百度地图API可以在移动端和PC端使用,还支持在微信小程序中使用,还有javascript相应的API,有利于前端开发的对接。
三: 加载地图 加载地图步骤
1.新建一个html页面
2.引入js
<script type="text/javascript" src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=申请的AK"></script> 3..写下样式
<style> html, body, #container { width: 100%; height: 100%; overflow: hidden; margin: 0; padding: 0 } </style> 4.创建地图容器元素
<div id="container"></div> 5.开始写js 初始化地图
<script> //1.创建地图实例 var map = new BMapGL.Map("container"); //2.设置中心经纬度 这里我们使用BMapGL命名空间下的Point类来创建一个坐标点。Point类描述了一个地理坐标点,其中120.872845表示经度,32.021089表示纬度。(为南通濠河风景区坐标) var point = new BMapGL.Point(120.872845, 32.021089); //3.在创建地图实例后,我们需要对其进行初始化,BMapGL.Map.centerAndZoom()方法要求设置中心点坐标和地图级别。 地图必须经过初始化才可以执行其他操作 值一般是3-19 map.centerAndZoom(point, 15); </script> map.
Chisel环境配置和第一个Chisel模块的实现与测试 动机 现在已经对Scala有一定的了解了,可以开始构造一些硬件了。Chisel的全称为Constructing Hardware In a Scala Embedded Language,是一个基于Scala的DSL(Domain Specific Language,特定领域专用语言),因此可以在同一串代码内兼得Scala和Chisel编程的优点。
理解哪些代码是Scala哪些又是Chisel这点很重要,不过后面再谈。
现在开始,应该把Chisel和本章的代码看作写Verilog更好的方式。本章会展示一个完整的Chisel模块和测试模块,用于了解相关要点,后续后给出更多充足的例子。
环境配置(先不包括Chisel) 安装JDK、git、make和gtkwave等基本环境:
sudo apt install openjdk-8-jdk git make gtkwave 安装sbt
echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add sudo apt-get update sudo apt-get install sbt 在VS Code中安装插件,先安装Scala Syntax (official),再安装Scala (Metals):
Scala测试
新建源文件test.scala:
object HelloScala extends App { println("Hello Scala") } 运行:
#############################
net.inet.ip.sourceroute=0
net.inet.ip.accept_sourceroute=0
#############################
通过源路由,攻击者可以尝试到达内部IP地址 --包括RFC1918中的地址,所以不接受源路由信息包可以防止你的内部网络被探测。
#################################
net.inet.tcp.drop_synfin=1
###################################
安全参数,编译内核的时候加了options TCP_DROP_SYNFIN才可以用,可以阻止某些OS探测。
##################################
kern.maxvnodes=8446
##################################
vnode 是对文件或目录的一种内部表达。 因此, 增加可以被操作系统利用的 vnode 数量将降低磁盘的 I/O。
一般而言, 这是由操作系统自行完成的,也不需要加以修改。但在某些时候磁盘 I/O 会成为瓶颈,
而系统的 vnode 不足, 则这一配置应被增加。此时需要考虑是非活跃和空闲内存的数量。
####################################
kern.maxproc: 964 #Maximum number of processes
kern.maxprocperuid: 867 #Maximum processes allowed per userid
kern.maxfiles: 1928 #系统中支持最多同时开启的文件数量,如果你在运行数据库或大的很吃描述符的进程,那么应该设置在20000以上,比如kde这样的桌面环境,它同时要用的文件非常多。一般推荐设置为32768或者65536。
kern.argmax: 262144 #maximum number of bytes (or characters) in an argument list.
###################################
kern.securelevel: -1
###################################
这是系统默认级别,没有提供任何内核的保护错误;
0:基本上作用不多,当你的系统刚启动就是0级别的,当进入多用户模式的时候就自动变成1级了。
1:在这个级别上,有如下几个限制:
a. 不能通过kldload或者kldunload加载或者卸载可加载内核模块;
b. 应用程序不能通过/dev/mem或者/dev/kmem直接写内存;
本文中的json对象直接来自与菜鸟教程,推荐直接去菜鸟教程学习。
JSON,全称avaScript Object Notation,即JavaScript 对象表示法,也是当下最流行的web前后端数据交互格式。作为一名后端开发人员,在设计restful接口,或使用postman测试接口的时候,经常和Json打交道,因此必须掌握json。
json语法 json语法 json语法中主要有以下几种元素
key: value键值对是基本的数据单元
大括号 {} 保存对象
中括号 [] 保存数组,数组可以包含多个对象
对象的元素可以是数组,数组的元素也可以是对象。数据(键值对或数据元素)之间由逗号分隔,对象之间也由逗号分隔。
json值 JSON 值可以是
数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组(在中括号中)对象(在大括号中)null 常见json数据 简单json对象 // 字符串为值 { "name": "菜鸟教程" } // 数字为值 { "age": 30 } // bool作值 { "age": true } // null为值 { "age": null } 多个键值对 对象可以包含多个名称/值对
{ "name": "runoob", "alexa": 10000, "site": null } 嵌套json对象 JSON 对象中可以包含另外一个 JSON 对象
{ "name":"runoob", "alexa":10000, "sites": { "
1.背景 2.演练场景:HyperClone特性场景演练
背景 有时,我们需要在页面加载时,动态获取一些局部信息,如:在浏览文章时,我们希望在文章页面加载时,同时动态加载文章的评论消息,这时,我们可以通过Ajax技术,从后台获取评论,并将其展示在页面上,这个过程是在页面加载完成后自动完成的
HTML JS
用java里的Scanner类实现输入成绩,用if判断成绩等级
代码如下:
//用java实现输入成绩,判断等级 //导包 import java.util.Scanner; public class Exercise{ public static void main(String[] args){ System.out.println("请输入您的成绩:"); //创建实例 Scanner sc=new Scanner(System.in); //使用接收键盘输入功能,存放到整数类型score int score=sc.nextInt(); //判断用户输入的成绩 if(score>=0&score<60){ System.out.println("您的成绩为E,不及格"); }else if(score>=60&score<70){ System.out.println("您的成绩为D"); }else if(score>=70&score<80){ System.out.println("您的成绩为C"); }else if(score>=80&score<90){ System.out.println("您的成绩为B"); }else if(score>=90&score<=100){ System.out.println("您的成绩为A"); }else{ //如果用户输入的不是0-100的数字,提示输出错误提示 System.out.println("输入错误"); } } } 输出结果:
知识点:
Scanner类:java为我们提供接收用户键盘输入的类
Scanner sc=new Scanner(System.in);
功能:接收用户输入的整数 nextInt();
接收用户输入的字符串 next();
类的命名规则:首字母大写,第二个单词首字母也得大写 – 大驼峰命名法
变量的命名规则:首字母必须小写,第二个单词首字母大写 –小驼峰命名法
启动Cobalt Strike4服务端 Linux类系统启动命令 进入CS目录后执行 启动命令
./teamserver [服务端ip] [密码] 例如
./teamserver 192.168.56.129 text Windows系统启动 管理员运行 cmd 进入CS目录后执行 启动命令
teamserver.bat [服务端ip] [密码] 例如:
teamserver.bat 192.168.56.129 text 启动Cobalt Strike4客户端 在Windows下CS目录中一个叫 cobaltstrike.bat双击即可(启动失败缺少Java环境)
运行后出现下面界面
Linux系统下启动客户端 javaagent:CobaltStrikeCN.jar是中文汉化插件
java -Dfile.encoding=UTF-8 -javaagent:CobaltStrikeCN.jar -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -jar cobaltstrike.jar 登录CS4客户端 主机:服务端ip
端口:没修改默认50050
用户名:随便
密码:密码是你启动服务端设置的
登入成功进入下面
cs4 监听器添加 界面介绍 添加 删除 cs4生成Windows木马 生成木马前一定要有监听器,并且将杀毒软件关闭防止杀掉
完整过程:
木马被执行会自动上线
查看Windows屏幕
一、查具体某个时间段的日志
cat xxx.log |sed -n '/2022-01-19 23:12/,/2022-01-19 23:15/p' 命令: grep '时间' '日志文件名 ' 例如:查询info.log文件中2022年01月6号11:34至11点37之间的日志信息 grep '2022-01-06 11:3[4-7]' info.log 按秒查 grep '2022-01-06 11:42:[01-59]' log.log 查询2022-01-06 11:42 的日志 grep '2022-01-06 11:42' log.log 查询2022-01-06 十点到十一点的数据 grep '2022-01-06 1[0-1]' log.log
当我遇到下载的gif动图尺寸不合适需要通过裁剪gif图来改变尺寸时,就会使用【GIF中文网】的gif裁剪(https://www.gif.cn/)功能来裁剪动图的大小,非常的简单。最大可上传30m的gif动图三步就能够完成在线裁剪gif动图尺寸的操作。
通过拖拽或是点击上传本地图片,也可以选择复制图片地址到搜索框上传网络图片进行裁剪,在不影响画质的情况下,对gif动图进行自由裁剪尺寸的同时还能够缩小gif动图的体积。
使用方法以及入口链接
链接:https://www.gif.cn/tools/cut
打开网站点击“GIF工具-GIF裁剪”功能,将需要裁剪的gif动图上传。
Gif动图上传后,可按比例裁剪也可以通过设置尺寸调整的数据以及拖动灰色裁剪框的方式来裁剪gif动图,完成后,点击“裁剪”。
裁剪完成后,点击“下载”即可。
推荐理由
1、最大可上传30M的gif动图裁剪
2、支持本地gif动图和网络图片上传两种方式进行裁剪
3、能够在保证画质的情况下,对gif动图进行裁剪的同时还能有效的减小gif动图的体积