当官方提供的所有断言工厂无法满足业务需求时,还可以自定义断言工厂。
添加自定义断言工厂类 自定断言工厂主要注意一下几点:
需要声明是Springboot的Bean,添加注解@Component,名称必须以RoutePredicateFactory结尾,这个是命名约束。如果不按照命名约束来命名,那么就会找不到该断言工厂。前缀就是配置中配置的断言。可以直接复制Gateway中已经实现的断言工厂,修改对应的内容,避免踩坑。继承父类AbstractRoutePredicateFactory,并重写方法。需要定义一个Config静态内部类,来接收断言配置的数据。在重写的shortcutFieldOrder方法中,绑定Config中的属性。传入数组的内容需要与Config中的属性一致。在重写的apply方法中,实现具体验证逻辑。 import com.alibaba.cloud.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import javax.validation.constraints.NotNull; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; /** * @ClassName CustomVerifyRoutePredicateFactory * @Description * @Author tigerkin * @Date 2022/3/14 15:15 */ @Component public class CustomVerifyRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomVerifyRoutePredicateFactory.Config> { private final Logger log = LoggerFactory.getLogger(this.getClass()); /** * 验证内容 key. */ public static final String VERIFY_CONTENT_KEY = "verifyContentKey"; /** * 验证内容 val.
使用VuePress搭建在线文档网站 在线文档 VuePress官方在线文档(opens new window)
搭建基本环境 # 将 VuePress 作为一个本地依赖安装 npm install -D vuepress # 新建一个 docs 文件夹 mkdir docs # 新建一个文件: docs/README.md echo '# Hello VuePress!' > docs/README.md # 启动文档项目 npx vuepress dev docs # 构建静态文件 npx vuepress build docs |-- docs |-- .vuepress |-- config.js |-- README.md 配置ts教程文档 整体结构 |-- dist |-- dics |-- .vuepress |-- public |-- ts-logo.png |-- config.js |-- chapter1 |-- 01_初识TS.md |-- 02_安装TS.md |-- 03_HelloWorld.
实现一个时间为横坐标,整数为纵坐标的例子:
import datetime import matplotlib.pyplot as plt #导入中文字体,避免显示乱码 import pylab as mpl import numpy as np #数据源 list_date = ['20190813', '20190814', '20190815', '20190816', '20190819'] list_count = [8, 8, 6, 11, 19] #中文乱码问题 mpl.rcParams['font.sans-serif'] = ['SimHei'] # 生成figure对象,相当于准备一个画板 fig = plt.figure(figsize=(8, 3)) # 生成axis对象,相当于在画板上准备一张白纸,111,11表示只有一个表格, #第3个1,表示在第1个表格上画图 ax = fig.add_subplot(111) plt.title(conspt) plt.xlabel('日期') plt.ylabel('涨停数量') #将字符串的日期,转换成日期对象 xs = [datetime.datetime.strptime(d, '%Y%m%d').date() for d in list_date] #日期对象作为参数设置到横坐标,并且使用list_date中的字符串日志作为对象的标签(别名) plt.xticks(xs, list_date, rotation=45, fontsize=10) plt.yticks(np.arange(0, 30, step=2), fontsize=10) ax.plot(xs, list_count, color='r') #下方图片显示不完整的问题 plt.
此时在右下角会提示command ‘gitlens.showSettingsPage’ not found
1、更新插件到最新版;
2、在插件列表旁的设置按钮上右键安装另一个早期的版本;
3、清除所有已安装的插件,重新下载安装vscode;
4、如果以上都不行,则需要找插件作者协助解决
建议 在此建议使用vscode的童鞋么,把同步设置打开,在更换电脑或者重新安装vscode的时候,真的很方便
1. 什么是vue.js Vue.js是一套构建用户界面的渐进式框架, 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架。
2.框架和库的区别 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。
库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。
3.MVC与MVVM的区别 MVC 是后端的分层开发概念,MVC分别是:model(模型层)、controller(调度层)、view(视图层)
MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分为了三部分Model(业务逻辑,数据)、View(界面展示)、VM ViewModel(链接view和model);
4.Vue.js代码结构 1.引入vue.js 。如:<script src="./vue-2.4.0.js"></script>,本地和网上的都可以。
2.写视图层(我们要展示的内容)
3.实例化一个Vue()
如图:
5.插值表达式、v-cloak、v-text、v-html 插值表达式{{}},可以在前后插入内容
v-cloak:防止页面闪烁,使用的时候需要在style标签里加一个display:none
v-text:会替换掉元素里的内容
v-html:可以渲染html页面
6.页面元素属性值的绑定 v-bind和事件绑定v-on v-bind用于绑定页面元素的属性值,简写 :
v-on进行事件的绑定,用的最多是click事件绑定,简写 @
如:
7.事件修饰符 .stop 阻止冒泡.prevent 阻止默认事件.capture 添加事件侦听器时使用事件捕获模式.self 只当事件在该元素本身(比如不是子元素)触发时触发回调.once 事件只触发一次 8.v-model数据双向绑定(用于绑定表单控件) 例:
双向数据绑定底层实现原理:主要采用数据劫持结合“发布-订阅”模式的方式,通过Object.defineProperty()的setter和getter,在数据变动时发布消息给订阅者 9.v-for和key属性 遍历数组,参数(item,index) in list
遍历对象,参数(value,key,index) in list
遍历数字,num in 10 (1~10)
在使用v-for的时候都需要设置key
让界面元素和数组里的每个记录进行绑定
key只能是字符串或者数字
key必须是唯一的
10.v-if与v-show的区别 v-if是删除dom元素,v-show是设置display:none
只修改一次的时候,状态不频繁切换的时候可以使用v-if,状态频繁切换的时候可以使用v-show
使用了Makefile中的VPATH,但是遇到make: *** No rule to make target ‘test.c’, needed by ‘test.o’. Stop.
原因是Makefile中的VPATH,只会改变你的依赖关系,并不会改变你的cmd命令.因此,你想要在cmd中引用你的依赖关系
如下图所示,为你写的目标文件的依赖文件(prerequisites
)中的文件添加了路径前缀.但是没有给你的cmd中的文件添加前缀
targets : prerequisites
command
例如: src中存放test.c
1.
VPATH = ./src
test.o:test.c
gcc -c test.c -o test.o
你此时运行make,可以看到cmd中运行的命令就是gcc -c test.c -o test.o.显然会提示找不到文件
2.
VPATH = ./src
test.o:test.c
gcc -c $< -o test.o
你此时运行make,可以看到cmd中运行的命令时gcc -c ./src/test.c -o test.o
下图参考:GNU make
Spring(详解) 什么是spring? Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。
然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
它是一个容器框架,用来装javabean(java对象),中间层框架(万能胶)可以起一个连接作用,比如说把Struts和hibernate粘合在一起运用。简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
简单来说就是:spring 是地球母亲他可以融汇万物
1.什么是IOC IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。
1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。
控制反转(依赖注入)
//通过工厂的指定流水线来生产 // Dog d = (Dog) ax.getBean("dog");//IOC // Cat c = (Cat) ax.getBean("cat");//IOC // System.out.println(d.getDid()); // System.out.println(d.getDname()); // System.out.println(c.getCid()); // System.out.println(c.getCname()); Master m=(Master) ax.getBean("master"); System.out.println(m.getC().getCid()+"~"+m.getD().getDid()); Set注入
<bean id="dog" class="entity.Dog"> <property name="did" value="1"></property> <!--依赖注入--> <property name="dname" value="陈狗1"></property> </bean> <bean id="cat" class="entity.Cat"> <property name="cid" value="2"></property> <!--依赖注入--> <property name="cname" value="陈狗2"></property> </bean> <bean id="
题库来源:安全生产模拟考试一点通公众号小程序
2022年氧化工艺考试练习题系氧化工艺上岗证题目考前必练习题目!2022年氧化工艺特种作业证考试题库模拟考试平台操作根据氧化工艺最新教材汇编。氧化工艺模拟考试题库通过安全生产模拟考试一点通上同步学习。
1、【单选题】 PX氧化反应过程中,使用的溶剂是()。( C )
A、溴化物
B、醋酸锰
C、HAC
2、【单选题】 分子中含有()是羧酸。( C )
A、-CHO
B、-OH
C、-COOH
3、【单选题】 ()应当包括危险性分析、可能发生的事故特征、应急组织机构与职责、预防措施、应急处置程序和应急保障等内容。( A )
A、专项应急预案
B、综合应急预案
C、现场处置方案
4、【单选题】 ()物质低浓度时有臭鸡蛋味道,随着浓度升高,臭味逐渐消失,人一旦中毒会导致电击样死亡。( B )
A、一氧化碳
B、硫化氢
C、液氨
5、【单选题】 1211灭火器的使用方法分为七步:拿,站,(),压,查。( A )
A、拔,握,对
B、压,握,拔
C、拔,压,握
6、【单选题】 一般情况下,安全帽能抗()kg铁锤自1m高度落下的冲击。( B )
A、2
B、3
C、4
7、【单选题】 下列不是爆炸性物质的是()。( B )
A、黑索金
B、硝酸钾
C、雷汞
8、【单选题】 下列选现中,属于氢气化学性质的是()。( C )
A、氢气难溶于水
B、在标准状况下,氢气的密度小于空气的密度
C、混有空气的氢气点燃易发生爆炸
9、【单选题】 下列选项中,会引起往复式压缩机气缸内发出突然冲击声的是()。( C )
A、气阀窜气
B、气缸余隙大
C、气缸内有异物
10、【单选题】 不是石化行业污染主要途径的是()。( A )
使用百问网的STM32F103MINI开发板完成下面实验。
1、通过F103MINI连接ESP8266。
F103MINI开发板的3V3和GND分别连接ESP8266的3V3和GND。
F103的UART2_TX连接ESP8266的RX。
F103的UART2_RX连接ESP8266的TX。
2、F103MINI下载虚拟串口的程序,
F103MINI就相当于一个USB转串口模块。
3、通过串口助手程序操作ESP8266。
①复位:AT+RST
②模式设置:AT+CWMODE_DEF=1
③WIFI连接:AT+CWJAP_DEF="CMCC-NpgE","ahRHrb5A"
④查看IP:AT+CIFSR
⑤创建UDP连接:AT+CIPSTART="UDP","192.168.12.12",9999,9999,2
通过上述步骤操作时,不能通过微信小程序操作F103MINI开发板。
4、连接路由器改为连接电脑热点。
①复位:AT+RST
②模式设置:AT+CWMODE_DEF=1
③WIFI连接:AT+CWJAP_DEF="110","12345678"
④查看IP:AT+CIFSR
⑤创建UDP连接:AT+CIPSTART="UDP","192.168.12.12",9999,9999,2
微信小程序绑定ESP8266的IP,点台灯,串口有收到从程序。
创建UDP的IP是随意写的,紧跟着是IP的端口和自己的端口,2表示UDP远端可变。
5、创建TCP的连接。
①复位:AT+RST
②模式设置:AT+CWMODE_DEF=1
③WIFI连接:AT+CWJAP_DEF="110","12345678"
④查看IP:AT+CIFSR
⑤创建TCP连接:
打开SSCOM,选择TCP Server服务器,
IP选择本机IP,设置端口,并进行侦听,
AT+CIPSTART="TCP","192.168.1.6",9998,0 即可连接上服务器
AT+CIPSEND=4 发送4字节数据
发送数据时需要注意新行,一个新行顶两个字节,\r\n 回车 换行。
DateFormat类介绍
java.text.DateFormat类 public abstract class DateFormat extends Format DateFormat 是日期/时间格式化子类的抽象类==>DateFormat是Format类的子类,DateFormat类本身还是一个抽象类,无法直接创建对象使用 DateFormat作用: 它以与语言无关的方式格式化并解析日期或时间 格式化(也就是日期 -> 文本) 解析(文本-> 日期 DateFormat类的成员方法: String format(Date date) 参数传递Date日期,把日期格式化为符合模式的字符串 Date parse(String source) 参数传递字符串,把符合模式的字符串解析为Date日期 ----------------------------------------------------------------------------------------- DateFormat类本身还是一个抽象类,无法直接创建对象使用,需要使用DateFormat类的子类创建对象使用 java.text.SimpleDateFormat extends DateFormat类 SimpleDateFormat类的构造方法: SimpleDateFormat(String pattern) 用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。 参数: String pattern:传递日期和时间的模式 在模式中写y代表年 在模式中写M代表月 在模式中写d代表日 在模式中写H代表时 在模式中写m代表分 在模式中写s代表秒 "yyyy-MM-dd HH:mm:ss" "2020-08-10 11:56:03" "yyyy年MM月dd日 HH时mm分ss秒" "2021年3月19日 11:10:22" "yyyy/MM/dd HH:mm:ss" 注意: 1.表示模式的字母不能随便写(y代表年,M代表月...),表示年月日时分秒的连接符号可以随意写(-,/...) 2.表示模式的字母严格区分大小写 DataFormat类的常用方法
package com.itheima.demo06DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /* DateFormat类的成员方法: format:格式化 String format(Date date) 参数传递Date日期,把日期格式化为符合模式的字符串 使用步骤: 1.
我们在用ESP32做开发时,由于初始化配网的需要,往往是需要工作在AP模式,但是也要能使用STA模式的扫描功能,列出周围可用的wifi热点列表,方便用户通过选择的方式输入热点名。这就需要进入STA和AP的混合模式。
但是,在micropython的标准文档中,wifi的模式只有STA和AP两种模式,似乎没有混合模式。并且STA模式和AP模式的切换很容易出现扫描不到周围的wifi热点、wifi模块报unknown error 0x0102错误导致wifi模块失效等问题。
为此,笔者经过研究发现,micropython可以通过以下代码方法(注意代码中的注释)稳妥操作wifi模块进入STA与AP的混合模式,充当AP的同时,可以扫描出周围的wifi热点供配网使用。
具体场景是这样的:
1.ESP32启动时,尝试读取设备上保存的wifi热点配置文件。如果找不到配置文件,或者连接不上配置文件中的热点,就进入AP模式,启动web服务,等待用户登录web进行热点信息配置(所谓配网)。
wifi热点配置文件wificonfig.json内容如下:
{"wifiname": "YourRouterName", "wifipassword": "YourRouterPassword"}
该文件的自动生成和WEB服务配网部分代码不是此文重点,不在此叙述,需要的可以私信我。测试后述代码时,人工生成一个wificonfig.json在根目录即可。
2.ESP32启动时,如果能顺利连接到配置文件中的热点,就直接进入STA正常模式,不开启AP功能。该模式也就是完成了配网之后设备的正常运行模式,该模式下也应该通过WEB提供热点信息的修改功能,以方便用户修改。
以下为代码。
class myWifiSet: def __init__(self) : self.Mode ="" self.APList ={}#保存热点扫描结果 #先尝试进入STA模式,连接热点,如果出错,就进入STA和AP混合模式 if self.StaMode()==False: self.APMode() print("连接热点失败,进入STA&AP混合模式...") self.Mode="Hybrid" else: print("已进入STA模式,连接热点成功!") self.Mode="STA" def scanAP(self): #此方法只能在本类实例化后才能调用,即wifi变量已存在 import utime,ujson #try: # self.wifi.scan()#先尝试一次扫描 #except: # pass print("now in %s mode"%self.Mode) #self.wifi.active(False)#启停一次,确保扫描成功 #utime.sleep(0.5) #self.wifi.active(True) #utime.sleep(0.5) #有时模块会读不出来信号弱的路由器名,因此写一段把名字为空的热点全部干掉! try: self.APList=self.wifi.scan() print("扫描AP结束,列表如下:") print(self.APList) f=open("/wifiAPList.json","w") #print(APList_json) for item in self.APList: print(item) if item[0]==b'': print("one item deleted!") self.
话不多说,上才艺。
下面代码粘贴即用
/** * * 导出表格带下拉框 */ @GetMapping("exportBox") public void export(HttpServletResponse response) throws IOException { String fileName = "模板.xls"; WriteCellStyle headWriteCellStyle = new WriteCellStyle(); // 设置背景颜色 headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); // 设置头字体 WriteFont headWriteFont = new WriteFont(); headWriteFont.setFontHeightInPoints((short)14); // 字体加粗 headWriteFont.setBold(true); headWriteCellStyle.setWriteFont(headWriteFont); // 设置头居中 headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 内容策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); // 设置内容字体 WriteFont contentWriteFont = new WriteFont(); contentWriteFont.setFontHeightInPoints((short)12); contentWriteFont.setFontName("宋体"); contentWriteCellStyle.setWriteFont(contentWriteFont); // 设置 水平居中 contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 设置 垂直居中 contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置单元格格式为 文本 contentWriteCellStyle.
实验一 多级反馈队列调度算法 一. 主要实现方法和代码介绍 1.编写进程类,其只包含所需的运行时间和进程编号两个属性,还有一个运行方法,此方法就是将所需的运行时间属性减去.传入的运行时间.
2.创建进程函数:创建maxp个进程,(应该不超过10,在此创建九个,即暂时不进行进程队列越界处理),其运行时间符合均值为0,方差为20的高斯分布,并取整取绝对之后所得到的值, (此处是为了全自动创建进程),进程号自己自增. 在创建进程时,使用mutex库将每一个queue 加锁和解锁,以实现互斥访问.
3.运行函数. 主要的算法函数. 首先判断队列非空,即进入运行,一级队列非空时,优先运行第一级队列,一级队列空后,才检差后几级队列. 但是后几级队列每一次执行后,都重新检查一级队列是否非空.具体实现是:if(一级队列非空) { while(一级队列非空){ 运行}} ;而高级别不执行while. 其次,当一次执行没有执行完,则立即放入下一级队列,每次写入都加锁.
二. 程序流程图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8AyJRjO-1647856457764)(C:\Users\51330\AppData\Roaming\Typora\typora-user-images\image-20211009101816266.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S14kJ5Lg-1647856457765)(C:\Users\51330\AppData\Roaming\Typora\typora-user-images\image-20211009101923526.png)]
三. 程序代码 #include <iostream> #include <queue> //随机数 #include <random> #include <chrono> #include <cmath> #include <thread> #include <mutex> #define T 10 #define Qsize 10 using namespace std; mutex mym1; mutex mym2; mutex mym3; mutex mym4; int ALLP = 0; int CPUTIME = 0; int information = 0; class Process { public: int RUNTIME; int PNUM; void run(int runt); }; void Process::run(int rt) { cout << CPUTIME << "
编译Maven项目时报错,was cached in the local repository, resolution will not be reattempted until the update interval of local-nexus-mirror has elapsed or updates are forced
错误信息:
[ERROR] Failed to execute goal on project platform-xxx: Could not resolve dependencies for project com.frond.xxx:platform-xxx:jar:0.1: Failed to collect dependencies at com.trip.public:common-utils:jar:1.2.0-SNAPSHOT: Failed to read artifact descriptor for com.trip.public:common-utils:jar:1.2.0-SNAPSHOT: Failure to find com.trip.public:platform-common:pom:0.6 in http://nexus.tool.cn/repository/ was cached in the local repository, resolution will not be reattempted until the update interval of local-nexus-mirror has elapsed or updates are forced -> [Help 1] 问题原因:
1 校招应聘流程 网申/内推→在线笔试(技术类)及测评→面试→发放offer →正式入职
2 阿里校招时间 春招(基本3-5月):实习offer,后续走实习生转正秋招(基本7月-12月):直接拿正式offer,可不实习 3 内推与网申的区别? 内推人可以帮助学生获得更多的业务部门和岗位相关信息,并帮助学生找到更合适的岗位;内推人可以随时查看校招进展,帮忙跟进流程。 4 校招海报 略
5 重点岗位 5.1 数据科学家 描述
如果你想接触和使用先进的机器学习的框架和统计方法设计方案,解决业务中的从未被解决过的问题;
如果你想通过Python/R等流行的语言编写高效的机器学习算法,产出新颖实用的分析图表;
如果你想参与阿里发挥你的商业sense,发现改变商业决策的洞察;
如果你想沉浸在电商大数据,通过数据分析来创造性地提出切实可行的营销策略。并且通过科学的实验设计证明商业效果;
如果你想接触世界领先的数据科学大牛,获得数据科学浪潮之巅的各类大牛的指导;
那就加入我们吧!
要求
如果你所学专业是计算机、数学、统计、数据科学、精算与大数据技术等相关专业;
如果你有强的动手能力和学习能力,熟悉一门数据科学语言,如Python、R、SQL、Java等;
如果你具备扎实的专业基础,良好的沟通能力和团队合作,主动积极,乐于面对挑战;
如果你有参与过数据科学、分析、数据挖掘、算法等相关项目更好;
如果你有大数据操作的实际经验更好;
那么成为数据科学团队的一员吧,这里就是你的舞台。
5.2 数据研发工程师 描述
如果你想参与阿里大数据的采集、存储、处理,通过分布式大数据平台加工数据,支持业务管理决策, 如果你想参与阿里大数据体系的模型设计、开发、维护,通过元数据、质量体系有效的管理和组织EB级的数据, 如果你想参与阿里大数据产品的研发,发挥你的商业sense,通过数据分析和算法来洞察数据背后的机会,来探索大数据商业化, 如果你想接触世界领先的大数据处理与应用的技术和平台,获得大数据浪潮之巅的各类大牛的指导, 那就加入我们吧!
要求
如果你所学专业是计算机、数学、统计、数据科学与大数据技术等相关专业;
如果你有强的动手能力和学习能力,熟悉一门数据处理语言,如SQL、JAVA、Python、Perl等,熟悉unix或者linux操作;
如果你具备扎实的专业基础,良好的沟通能力和团队合作,主动积极,乐于面对挑战;
如果你有参与过数据处理、分析、挖掘等相关项目更好;
如果你对Hadoop、Hive、Hbase等分布式平台有一定的理解更好;
那么成为数据工程师吧,这里就是你的舞台。
5.3 研发工程师JAVA 描述
如果你想了解JAVA开发在阿里巴巴互联网生态系统中无与伦比的应用广度与深度; 如果你对基础技术感兴趣,你可以参与基础软件的设计、开发和维护,如分布式文件系统、缓存系统、Key/Value存储系统、数据库、Linux操作系统和Java优化等; 如果你热衷于高性能分布式技术,你可以参与高性能分布式服务端程序的系统设计,为阿里巴巴的产品提供强有力的后台支持,在海量的网络访问和数据处理中,设计并设施最强大的解决方案; 如果你喜欢研究搜索技术,你可以参与搜索引擎各个功能模块的设计和实现,构建高可靠性、高可用性、高可扩展性的体系结构,满足日趋复杂的业务需求; 如果你对电子商务产品技术感兴趣,你可以参与产品的开发和维护,完成从需求到设计、开发和上线等整个项目周期内的工作; 如果你对数据敏感,你可以参与海量数据处理和开发,通过sql、pl/sql、java进行etl程序开发,满足商业上对数据的开发需求; 如果你热衷于客户端开发,你可以参与为用户提供丰富而有价值的桌面或无线软件产品。
要求
或许,你来自计算机专业,机械专业;
但是,你酷爱着计算机以及互联网技术,热衷于解决挑战性的问题,追求极致的用户体验;
或许,你痴迷于数据结构和算法,热衷于ACM,常常为看到“accept”而兴奋的手足舞蹈;
或许,你熟悉Unix/Linux/Win32环境下编程,并有相关开发经验,熟练使用调试工具,并熟悉Perl,Python,shell等脚本语言;
或许,你熟悉网络编程和多线程编程,对TCP/IP,HTTP等网络协议有很深的理解,并了解XML和HTML语言;
或许,你热衷于数据库技术,能够熟练编写SQL脚本,有MySql或Oracle应用开发经验;
或许,你并不熟悉Java编程语言,更精通C,C++,PHP,.NET等编程语言中的一种或几种,但你有良好和快速的学习能力;
有可能,你参加过大学生数学建模竞赛,“挑战杯”,机器人足球比赛等;
也有可能,你在学校的时候作为骨干参与学生网站的建设和开发。
一段全新、有意思的旅程正待开启!为了更全面的展现你自己,你还可以在简历中附上你认为自己最有意思的爱好、特长、经历,或是对未来有意思的畅想,没有限制,此项非必填。加入我们,一起打开有意思的未来!
6 疑问咨询渠道
文章目录 1、下载Apache2、修改 httpd.conf 文件3、启动Apache服务 1、下载Apache 点击:[https://www.apachehaus.com/cgi-bin/download.plx]
点击图中红圈的版本下载:
下载后,解压文件,把如图这两个文件拿出来放到你的Apache目录下
例如:我的放到D盘,如图:
2、修改 httpd.conf 文件 在文件夹中查找conf文件夹下边的httpd.conf文件,修改文件为自己的路径(写你自己的路径),如图:
注:还是在此文件中下边,有一个端口号配置:Listen 80 ,如果你的80端口被已经被占用,你自己修改一个没有用的端口号!!!!!
然后,在你的文件中 bin目录下,用【管理员】身份打开 CMD,输入httpd.exe -k install,如图我的例子:
到这里下载成功了!!
3、启动Apache服务 继续输入命令:net start Apache2.4 ,成功后在页面输入:localhost:你刚写的端口号 就会成功出现如下所示:(还有一种启动方法)
第二种启动方法:
右键此电脑 -> 管理 , 然后启动如图所圈的:
python包镜像地址:
https://pypi.tuna.tsinghua.edu.cn/simple
http://mirrors.aliyun.com/pypi/simple/
http://pypi.douban.com/simple/
http://pypi.hustunique.com/
http://pypi.sdutlinux.org/
http://pypi.mirrors.ustc.edu.cn/
下载依赖包:https://pypi.org/project
pip install -i https://pypi.douban.com/simple/ scrapy
pip install -i https://pypi.douban.com/simple/ wheel
pip install -i https://pypi.douban.com/simple/ Pillow
pip install -i https://pypi.douban.com/simple/ requests
pip install -i https://pypi.douban.com/simple/ tesserocr
pip install -i https://pypi.douban.com/simple/ virtualenv
pip install -i https://pypi.douban.com/simple/ -r D:\project\topoda\cm_notices\requirement.txt
pip install -i https://pypi.douban.com/simple/ -r /home/topoda/cm_notices/requirement.txt
pip install -i https://pypi.douban.com/simple/ pandas
pip install -i https://pypi.douban.com/simple/ opencv-python
pip install -i https://pypi.douban.com/simple/ bs4
pip install -i https://pypi.douban.com/simple/ elasticsearch
最近CentOS 6已经停止更新支持,同时官方也把yum源删除了,目前CentOS 6系统使用yum命令安装软件包基本都是失败,因此需要更换yum源。
在ssh界面执行以下命令即可一键更换yum源为CentOS的Vault源(包括CentOS官方和阿里云的源):
wget -O /etc/yum.repos.d/CentOS-Base.repo http://file.kangle.odata.cc/repo/Centos-6.repo
wget -O /etc/yum.repos.d/epel.repo http://file.kangle.odata.cc/repo/epel-6.repo
yum makecache
首先看一下warnning信息
WARNING: The script normalizer is installed in '/home/llxy/.local/bin' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. 配置环境变量
gedit ~/.bashrc # 在文件最后添加路径,该路径来源于第一步中安装 pip 时发出的警告 export PATH=/home/llxy/.local/bin:$PATH source ~/.bashrc
情景:创建多brick卷后执行gluster v delete xxx 由于timeout超时导致删除卷失败,此时需要手动删除gluster volume:
setps:
1. 停止gluster服务: systemctl stop glusterd
2. 查看gluster brick 使用情况,并卸载: umount /gluster/brick/xxx
3. 查看lv 使用情况,并移除 lvremove /dev/node-1_pool/xxx
4. 因为glusterd服务停止并不能将brick停止,需手动将gluster brick 停止,执行脚本:sh /usr/share/glusterfs/scripts/stop-all-gluster-processes.sh
5. 手动删除gluster volume 目录: rm -rf /var/lib/glusterd/vols/xxx
6. 清除gluster 临时缓存文件: cd /var/run/gluster; rm -rf *
7. 启动gluster 服务,systemctl start glusterd
8. 检查gluster 卷列表,并查看gluster 卷目录是否挂载正确: gluster v list(发现xxx已经不存在了)df查看之前的卷目录是否挂载正确
1.1.1 信息的定义 信息论的创始人 香农 指出:信息是用来消除随机不定性的东西。
信息(Information)是物质运动规律总和,信息不是物质,也不是能量。
信息的重要特征:价值,即可用来消除不确定性。
信息有多种表现形式,可以打印书写到纸上,可以以电子数据的方式存储,可以通过邮寄或者电子邮件的形式传播,可以以胶片形式显示或者交谈表达。总之,信息无处不在。
1.1.2 信息的属性 信息是具有价值的,而其价值则是通过其具体属性来体现的。
信息的安全属性:
● 真实性
● 保密性
● 完整性
● 可用性
● 不可抵赖性
● 可控制性
● 可审查性
1.1.3 信息安全 信息的价值和流动性是信息安全问题存在的根源。
信息的直接或潜在价值使其成为攻击者实施攻击的重要目标,由于信息通常是流动的,信息在流动过程中,也大大增加了其价值被他人获取的隐患。
人们对信息安全的认识经历了数据保密阶段(强调保密通信)、网络信息安全时代(强调网络环境)和目前的信息保障时代(强调不能被动地保护,需要“保护-检测-反应-恢复”四个环节)。
信息安全的定义:
CIA:信息安全是对信息的保密性(confidentiality)、完整性(integrity)和可用性(availability)的保持。
信息安全的实质:要保护信息系统或信息网络中的信息资源免受各种类型的威胁,干扰和破坏,以维护信息的价值,促进业务的连续性。
信息保障机制PDRR:Protection + Detection + Reaction + Restoration
P2DR2:信息安全是研究在特定的应用环境下,依据特定的安全策略(policy),对信息及其系统实施保护(protection)、检测(detection)、响应(reaction)和恢复(restoration)的科学。
信息安全威胁方式:
● 信息中断:使得信息不可获得,如DDoS攻击。 破坏信息的可用性
● 信息截取:使得信息中途被人获取,如网络数据包嗅探攻击。 破坏信息的保密性
● 信息修改:使得信息被非法篡改,如网站首页被非法篡改。 破坏信息的完整性
● 信息伪造:使得信息来源和内容不可信,如邮件伪造。 破坏信息的真实性
信息系统 狭义定义:是以提供信息服务为主要目的的数据密集型、人机交互的计算机应用系统。
广义信息系统 ≠ 计算机应用系统。
网络空间 是信息时代人类赖以生存信息环境,是所有信息系统的集合,以计算机和网络系统实现的信息化为特征。
1.2 软件安全 软件安全是使软件在受到恶意攻击的情形下依然能够继续正确运行的工程化软件思想。
解决软件安全问题的根本方法就是改善我们建造软件的方式,以建造健壮的软件,使其在遭受恶意攻击时依然能够安全可靠和正确运行。
软件安全威胁主要包括三个方面:软件自身安全(软件缺陷与漏洞)、恶意软件攻击与检测、软件逆向分析(软件破解)与防护。
1.3.1 软件缺陷与漏洞 软件缺陷(defect),又被称作Bug,是指计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。
基于NavMesh的A*寻路算法 源码地址:https://github.com/WarZhan/NavMeshOpenGL
一、导入数据生成NavMesh导航轮廓 1、由文本导入数据,数据要求:可走轮廓的最外围为顺时针方向,障碍物为逆时针方向,顶点不可有重复的,各障碍物不可叠加;
2、使用扫描线算法划分三角形,生成多边形轮廓;
3、将生成轮廓顶点信息转换为逆时针存储。
二、NavMesh导航网格的构建 1、在第一步生成的基础上构建多边形轮廓对象;
2、根据输入的轮廓三角形化,划分为紧凑拼接的三角形;
3、合并三角形,合并中先判断合成之后的多边形是否为凸多边形,是则合并,不是则跳过。
4、生成一个rcPolyMesh对象,包含顶点信息及多边形信息,npolys为多边形的数量,polys为多边形的数据,存放的为对应的多边形定点索引,nvp为多边形最大的顶点数。
三、寻路算法的实现(Dijkstra)(红色) 1、根据生成的rcPolyMesh,计算邻接信息(int二维数组),生成邻接矩阵,邻接的权值用所在多边形的最低点和最高点所连接对角线的长度。
2、鼠标左键点击确定起点,右键点击确定终点,点击鼠标的中间开始寻路。
3、根据起点和终点的位置确定两点分别在的多边形,使用顶点与多边形的边进行叉乘运算,若都在边得左侧,则点位于该多边形中。
4、根据Dijkstra算法得出一条最短路,找出所有邻接多边形的公共边,使用拐点发优化路径。
四、优化(A*)(绿色) 1、根据生成的rcPolyMesh,计算邻接信息(bool二维数组)和多边形重心位置(Vec3),重心计算方式为;
2、鼠标左键点击确定起点,右键点击确定终点,点击鼠标的中间开始寻路;
3、根据起点和终点的位置确定两点分别在的多边形,使用顶点与多边形的边进行叉乘运算,若都在边得左侧,则点位于该多边形中;
4、A* 中所用估值函数为位置上两方向的增量(dx+dy),两多边形间的花费近似为两多边形重心的位置,得到路径后用拐点法优化。
注:两种寻路算法在出现扁长形多边形时,可能搜出的路径不是最优,当两种算法路径一样时,红色的被覆盖只能看见绿色的。
参考文献:
1、多边形生成三角形:http://sites-final.uclouvain.be/mema/Poly2Tri/poly2tri.html(网页很旧了 可能打不开需要资料者留下邮箱)
2、凸多边形网格构建:recastnavigation https://github.com/memononen/recastnavigation
3、凸多边形网络三角形划分:http://www.critterai.org/nmgen_polygen
4、路径优化拐点法: http://www.navpower.com/gdc2006_miles_david_pathplanning.ppt
通过一个简单的 Demo 来阐述 MyBatis-Plus 的强大功能, 步骤是这样,结果是那样:
1、 准备我们要访问的数据表,我用的是mysql .
2、添加依赖
3、制作自动生成代码类。
4、测试mapper获取数据。
这里我们先准备一个简单的数据表。
DROP TABLE IF EXISTS user; CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@qq.com'), (2, 'Jack', 20, 'test2@qq.
士兵排队问题
Description
有N个士兵(1≤N≤26),编号依次为A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
Input
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
Output
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
Sample Input 1
A>B B>D F>B F<A Sample Output 1
AFBD 解题思路:这题的核心是拓扑排序和优先级队列。先将输入的信息建立出一张图(用邻接表实现),再结合拓扑排序和优先级队列以及STL里的关联容器map解决问题。
源代码:
#include<iostream>
#include<vector>
#include<map>
#include<queue>
using namespace std;
struct Enode
{
char name;
Enode* next;
};
struct Vnode
{
char name;
int in;
Enode* first;
Vnode() {
in = 0;
first = nullptr;
}
};
class ALGraph
{
private:
vector<Vnode> v;
map<char, int> m;
int vN, eN;
最近在研究图片识别算法,
有个网站挺不错的。没太细究。
iBooker - 可能是东半球最大的 AI 社区 | 欢迎大家贡献项目 -- ApacheCN 提供支持
有一些电子书收集,很用心。
想保留下来,内容太多了,于是写了个自动下载脚本。
import os,sys cmd = 'cdrive download ' def download(md_dir): cwd = os.getcwd() old_root = md_dir for root,dirs,files in os.walk(md_dir): for file in files: if root!=old_root: old_root = root new_dir = cwd+'/'+(root[len(md_dir):]) try: os.mkdir(new_dir) finally: print('dir exist %s'%new_dir) os.chdir(new_dir) print('----- deal '+root) file_obj = open(root+'/'+file,'r') try: for line in file_obj: for item in line.split('|'): litem = item.
Description 打印字符图形。输出n行n列"*"
Format Input 一个整数 n(0 < n < 10)
Output 一个矩形字符图形
Samples 输入数据 1 3 Copy
输出数据 1 *** *** *** Copy
思路:双重循环枚举输出即可。。。 代码 #include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cout<<"*"; } cout<<endl; } return 0; }
activity_main.xml
在res/layout文件中,放置一个TextView控件用于显示购物商城界面的标题,放置一个ListView控件用于显示购物商场界面的列表
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="45dp" android:text="购物商城" android:textSize="18sp" android:textColor="#FFFFFF" android:background="#FF8F03" android:gravity="center"/> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content" android:listSelector="@color/colorAccent" /> </LinearLayout> list_Item.xml
在res/layout文件中创建一个列表条目界面的布局文件list_item.xml,在该文件中放置一个Image View控件用于显示商品的图片;放置2个TextView控件分别用于显示商品的名称和价格!
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <ImageView android:id="@+id/iv" android:layout_width="120dp" android:layout_height="90dp" android:layout_centerVertical="true" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_toRightOf="@+id/iv"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="桌子" android:textColor="#000000" android:textSize="20sp" /> <TextView android:id="@+id/tv_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/title" android:layout_marginTop="10dp" android:text="价格:" android:textColor="#FF8F03" android:textSize="20sp" /> <TextView android:id="
目录
1 用户-创建数据表
2 创建用户实体类
3 持久层
1 准备
2 规划需要执行的SQL语句
3 接口与抽象方法
4 配置SQL映射
4 业务层
1 规划异常
2 设计接口和抽象方法
3 实现接口方法
4 设置MD5加密密码
5 测试检查
5 控制层
1 创建响应
2 设计请求
3 处理请求
4 控制层优化设计
6 前端页面
1 用户-创建数据表 创建数据库并创建数据表,在库中创建数据库
2 创建用户实体类 在创建用户实体类前,观察是否有通用基类分离,项目中许多实体类都会有日志相关的四个属性,所以在创建实体类之前,应先创建这些实体类的基类,将4个日志属性声明在基类中。
1.entity包下创建BaseEntity类,作为实体类的基类。因为这个基类的作用就是用于被其它实体类继承的,所以应声明为抽象类。
2.创建用户数据的实体类User,继承自BaseEntity类,并在类中声明与数据库对应的属性,创建
Getter and Setter、
Generate hashCode() and equals():比较值是否相等定义比较规则,hashcode地址输出、
toString():方便测试使用
等方法,
熟练可用lombok通过注解的形式自动生成构造器,提高开发效率,不过新手可以手动创建,提高源代码的可读性和完整性。
3.注:用户的实体类 :SpringBoot 约定大于配置,在spring boot中提供了一套默认配置,不需要手动去写xml配置文件,只有默认配置不能满足我们的需求时,才会去修改配置。如果没有配置,会取默认值,而所取的默认值就是约定,具体可以了解“约定大于配置“这个概念。
3 持久层 1 准备 1.测试类中编写并执行“获取数据库连接”的单元测试,以检查数据库连接的配置是否正确。
注意application文件的配置。
2.执行测试类中的contextLoads()测试方法,以检查测试环境是否正常。
2 规划需要执行的SQL语句 1.
一、什么是pinctrl子系统和gpio子系统 pinctrl子系统 用于引脚的配置。如复用为那种引脚(GPIO模式,I2C模式),电器特性等等。
gpio子系统 用于引脚的控制。如配置输出,输出高低电平等等。
当pinctrl子系统配置引脚为GPIO模式后,才能用gpio子系统控制引脚。gpio 子系统是基于 pinctrl 子系统的,gpio 的 API 接口的实现很多都是基于 pinctrl 子系统的函数。
二、.Linux Pinctrl子系统 2.1、相关概念 2.1.1、pin controller和client device pin controller:实现复用引脚、配置引脚服务,是服务的提供者client device:调用pin controller配置自己所需要的IO,是服务的使用者 note:pin controller 子节点格式是由芯片厂商自定义的,即每家芯片pin controller子节点格式都是不一样的。各个厂商的 pinctrl 使用说明可以参考厂商提供的文档或去内核源码路径 Documentation/devicetree/bindings/pinctrl 目录下找到对应厂商的使用说明。
imx6ull格式:
//client端: @节点名字 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_自定义名字A>; status = "okay"; }; //pincontroller服务端 pinctrl_自定义名字A: 自定义名字B { fsl,pins = < 引脚复用宏定义 PAD(引脚)属性, // 引脚 A 引脚复用宏定义 PAD(引脚)属性; // 引脚 B >; }; rk3288实例:
//client端 @uart0 { pinctrl-names = "
什么是Lambda表达式 lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。
它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
Lambda 表达式是实现函数式接口的一种方式,可以看做匿名内部类的简写形式:它没有名称,但它有参数列表,函数主体,返回类型,可能还有一个可以抛出的异常列表。
Lambda 是一个匿名函数,可以把 Lambda表达式 理解为是一段可以传递的代码 (将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升 ,JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。
什么是函数式接口 定义:接口中只有一个抽象方法的接口。
函数式接口一般使用 @FunctionalInterface 注解修饰,目的是检查接口是否符合函数式接口规范。
注意点:
函数式接口中可以有 默认方法 和静态方法函数式接口重写父类的方法,并不会计入到自己的抽象方法中 函数式接口Runnable java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。
每个 Lambda 表达式都能隐式地赋值给函数式接口,例如,我们可以通过 Lambda 表达式创建 Runnable 接口的引用。
Runnable r = () -> System.out.println("hello world"); 当不指明函数式接口时,编译器会自动解释这种转化:
new Thread( () -> System.out.println("hello world") ).start(); 因此,在上面的代码中,编译器会自动推断:根据线程类的构造函数签名 public Thread(Runnable r) { },将该 Lambda 表达式赋给 Runnable 接口。
4类常用函数式接口 Consumer 消费型接口:接受一个参数并进行逻辑操作,无返回值;Supplier 供给型接口:不接受参数,操作后返回一个对象;Function<T, R> 函数型接口:接收一个泛型T对象,操作后返回泛型R对象;Predicate 断言型接口:接收一个参数,操作后返回一个 boolean 值; Consumer 接口定义:
一.概述: 计算机网络
●是指将地理位置不同的具有 独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
网络编程
●在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换
二.网络编程三要素: IP地址
●要想让网络中的计算机能够 互相通信,必须为每台计算机指定一个标识号, 通过这个标识号来指定要接收数据的计算机和识别发送的计算机,而P地址就是这个标识号。也就是设备的标识
端口
●网络的通信,本质上是两个应用程序的通信。每台计算机都有很多的应用程序,那么在网络通信时,如何区分这些应用程序呢?如果说IP地址可以唯一标识网络中的设备 ,那么端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识
协议
●通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统规定,通信双方必须同时遵守才能完成数据交换。常见的协议有UDP协议和TCP协议
一.IP地址 IP地址:是网络中设备的唯一标识。
1.ip地址的分类 ●IPv4: 是给每个连接在网络上的主机分配一个32bit地址。 按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,也就是4个字节。例如一个采用二进制形式的IP地址是 “1100000 1010100 00000001 01000010* , 这么长的地址,处理起来也太费劲了。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号"."分隔不同的字节。于是,上面的IP地址可以表示为 “192.168.1.66" 。IP地址的这种表示法叫做“点分十进制表示法”,这显然比1和0容易记忆得多
●IPv6: 由于互联网的蓬勃发展, IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组, 分成8组十六进制数,这样就解决了网络地址资源数量不够的问题
2.IP常用命令: ipconfig:查看本机IP地址
ping IP地址:检查网络是否连通
3.IP地址操作类-InetAddress InetAddress类概述:
一个该类的对象就代表一个IP地址对象。
InetAddress类成员方法:
static InetAddress getLocalHost()
* 获得本地主机IP地址对象。
static InetAddress getByName(String host)
* 根据IP地址字符串或主机名获得对应的IP地址对象。
String getHostName()
* 获得主机名。
String getHostAddress()
* 获得IP地址字符串。
package 海绵hong; import java.net.InetAddress; public class InetAddressDemo01 { public static void main(String[] args) throws Exception { // 1.
(目录
一、在CentOS下搭建redis环境
二、启动redis服务器和客户端,尝试简单命令
三、总结
一、在CentOS下搭建redis环境 su //用root用户执行后续操作
wget http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
make install //把可执行程序复制到/usr/local/bin中,方便后面直接使用命令redis-server
如图:
注意这个时候你下载的redis-stable是在你的主用户文件中,如此时是在我的/home/winwin文件中,因为此时我打开终端没进行cd操作进入的目录~就是我的主用户目录。
如图:
然后输入redis-server出现了下列3个报错:
第一个Warning: no config file specified, using the default config.
In order to specify a config file use 'redis-server /path/to/redis.conf'
警告:没有明确的config文件,使用默认配置。为了明确配置文件请使用'redis-server /path/to/redis.conf'
解决:redis-server /home/你的用户名/redis-stable/redis-conf
或者你也可以找到redis-conf文件把他cp复制到你熟悉的目录下如cp redis-conf /etc
第二个Warning:WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.
编译Seata源码少io.seata.serializer.protobuf.generated 问题原因:缺少protobuf编译的java文件 解决方案:idea安装protobuf support插件,重启idea。 插件下载地址: https://github.com/ksprojects/protobuf-jetbrains-plugin 下载的ZIP包在idea导入到plugins中去,直接将ZIP导入,然后重启idea,看下图
构建当前报错项目,看下图,双击protobuf:compile
下面这个项目还是类似
博客主页:🏆看看是李XX还是李歘歘 🏆
🌺每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点,以及职场小菜鸡的生活。🌺
💗点关注不迷路,总有一些📖知识点📖是你想要的💗
⛽️今天的内容是7000字的内存管理相关的知识点,篇幅较长,建议先收藏后阅读⛽️💻💻💻
操作系统中的进程管理请参考:操作系统之进程问题总结——进来背书_李歘歘的博客-CSDN博客
目录
内存管理
内存管理的功能
程序装入和链接
内存保护
内存覆盖与内存交换
内存连续分配管理方式
动态分区分配策略
内存非连续分配管理方式
1.基本分页存储管理方式
2.基本分段存储管理方式
3.段页式存储管理方式
虚拟内存管理
传统存储管理的特征
局部性原理
虚拟存储器的定义和特征
虚拟存储器的实现
请求分页存储管理
页面置换算法
最佳置换算法(OPT)
先进先出页面置换算法(FIFO)
最近最久未使用置换算法(LRU)
时钟置换算法(CLOCK)
改进型CLOCK算法
内存管理 内存管理的功能 内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。地址转换:在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供地址变换功能,把逻辑地址转换成相应的物理地址。内存空间的扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存。存储保护:保证各道作业在各自的存储空间内运行,互不干扰。 程序装入和链接 创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需要以下几个步骤:
编译:由编译程序将用户源代码编译成若干个目标模块。链接:由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块。装入:由装入程序将装入模块装入内存运行。
内存保护 采取两种方法
在CPU中设置一对上、下限寄存器,存放用户作业在主存中的上下限地址,每当CPU要访问一个地址时,分别和两个寄存器的值相比,判断有无越界。采用重定位寄存器(或基址寄存器)和界地址寄存器(限长寄存器)来实现这种保护。 重定位寄存器含最小的物理地址值,界地址寄存器含逻辑地址值。每个逻辑地址值必须小于界地址寄存器;内存管理机构动态地将逻辑地址与界地址寄存器进行比较,如果未发生地址越界,则加上重定位寄存器的值后映射成物理地址,再送交内存单元。 内存覆盖与内存交换 覆盖:把用户空间分成一个固定区和若干个覆盖区。将经常活跃的部分放在固定区,其余部分按调用关系分段。首先将那些即将要访问的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区,替换覆盖区中原有的段。
交换(对换):把处于等待状态(或在CPU调度原则下被剥夺运行权利)的程序从内存移到辅存,把内存空间腾出来,这一过程又叫换出;把准备好竞争CPU运行的程序从辅存移到内存,这一过程又称为换入。中级调度就是釆用交换技术。
交换技术主要是在不同进程(或作业)之间进行,而覆盖则用于同一个程序或进程中。
覆盖技术要求给出程序段之间的覆盖结构,使得其对用户和程序员不透明,所以对于主存无法存放用户程序的矛盾,现代操作系统是通过虚拟内存技术来解决的,覆盖技术则已成为历史。
内存连续分配管理方式 为一个用户程序分配一个连续的内存空间,包括单一连续分配、固定分区分配和动态分区分配。
分配方法说明优点缺点单一连续分配分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分;用户区是为用户提供的、除系统区之外的内存空间。这种方式无需进行内存保护。 简单、无外部碎片,可以釆用覆盖技术,不需要额外的技术支持;无须进行内存保护,不会出现越界异常只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低。固定分区分配 将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业;
固定分区分配在划分分区时,有两种不同的方法:
分区大小相等:用于利用一台计算机去控制多个相同对象的场合,缺乏灵活性。分区大小不等:划分为含有多个较小的分区、适量的中等分区及少量的大分区。通常将分区按大小排队,并为之建立一张分区说明表,分配时检索该表,以找到合适的分区给予分配,将其状态置为”已分配”
可用于多道程序设计最简单的存储分配,无外部碎片。 程序可能太大而放不进任何一个分区中,这时用户不得不使用覆盖技术来使用内存空间;主存利用率低,当程序小于固定分区大小时,也占用了一个完整的内存分区空间,这样分区内部有空间浪费,产生内部碎片。动态分区分配又称为可变分区分配,是一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。 分区大小可以根据进程的实际情况进行分配;无内部碎片内存中会产生越来越多的外部碎片【可用拼接技术为已解决外部碎片】 内部碎片:分配给某些进程的内存区域中,如果有些部分没有用上,(动态分配,按需分配,对于进程来说,没有空的)。
外部碎片:是指内存中的一些空闲分区由于太小而难以利用。
动态分区分配策略 首次适应(First Fit)算法:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。最佳适应(Best Fit)算法:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区。最坏适应(Worst Fit)算法:又称最大适应(Largest Fit)算法,空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。邻近适应(Next Fit)算法:又称循环首次适应算法,由首次适应算法演变而成。不同之处是分配内存时从上次查找结束的位置开始继续查找。 首次适应算法不仅是最简单的,而且通常也是最好和最快的。但是它会使得内存的低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。
邻近适应算法试图解决这个问题,但实际上,它常常会导致在内存的末尾分配空间(因为在一遍扫描中,内存前面部分使用后再释放时,不会参与分配),会使高地址的大分区也被用完,分裂成小碎片。它通常比首次适应算法的结果要差。
最佳适应的分配会留下很小的难以利用的内存块,它会产生最多的外部碎片。
最坏适应算法与最佳适应算法相反,选择最大的可用块,把最大的连续内存划分开,会很快导致没有可用的大的内存块。
如何使用winrar压缩工具实现:文件打包为自解压EXE类型
**第一步:安装WinRAR压缩工具
**第二步:**选择你想要直接双击就能自解压的文件,右键选择“添加到压缩文件(A)…”
**第三步:**输入打包后的EXE文件包的名称,勾选“创建自解压格式压缩文件(X)”,随后再切换到“高级”tab页。
进入“高级”tab页之后,先点击“自解压选项”,弹出高级自解压选项之后,点击“模式”,选择“全部隐藏”,全部隐藏的效果就是,在解压时不弹出解压提示和解压进度条的显示,静默解压。
最后一步:进入到“更新”tab,如果我们是要做文件的更新和替换,那么我们可以根据实际情况进行“覆盖模式”的选择,这里我是想直接进行文件覆盖替换,也就是如果原来路径下有这些文件,就把它们直接替换掉,不进行询问。
设置完了之后,记得对设置好的窗口点击确定,确定后自解压EXE文件包就打包成功啦。
双击就直接自动解压里面的文件了。
设计模式 - 抽象工厂模式案例 抽象工厂模式vs工厂方法模式引入两个概念产品等级结构产品族 模式结构的角色抽象工厂模式案例案例背景案例分析实现步骤代码实现(按顺序)文件结构/类图1. 抽象产品类(2个)2. 具体产品类(4个)3. 抽象工厂(1个)4. 具体工厂(2个)5. 配置类(config.xml)6. 读取配置类(XMLUtil.java)7. 客户类输出结果 模式适用环境 抽象工厂模式vs工厂方法模式 工厂方法模式中具体工厂只需要生产一种具体产品抽象工厂模式中具体工厂可以生产相关的一组具体产品,这样的一组产品称为产品族 引入两个概念 产品等级结构 产品等级结构:产品的继承结构。
比如:抽象电视机和具体品牌电视之间构成了一个产品等级结构
产品族 产品族:是指由同一个工厂生产的,位于不同产品等级结构的一组产品
比如:
① 海尔工厂生成的海尔电视机、海尔电冰箱。
② 海尔电视机、海尔电冰箱就属于同一个产品族
③ 在这里海尔电视机属于电视机产品等级结构,海尔电冰箱属于电冰箱等级结构 ,它们位于不同产品等级结构
模式结构的角色 抽象工厂 ① 定义了返回具体产品对象的方法
② 产品有几种就定义几个方法
具体工厂 ① 实现父类中 返回具体产品对象的方法
② 具体工厂的个数 = 产品族的个数 --> 品牌的个数
抽象产品 ① 将业务方法抽象出来
② 抽象产品的个数 = 产品等级结构的个数 -->电视机、电冰箱 (产品类别的个数)
具体产品 ① 只要指明一个产品所处的产品族,以及所属的产品等级结构,就可以唯一确定这个产品
② 实现该产品的业务方法
③ 具体产品的个数 = 产品族个数(品牌) * 产品等级结构的个数(产品类别)
比如品牌(产品族)有两个:海尔和海信
抽象产品(产品等级结构)有两个:电视机、电冰箱
则具体产品就是2 * 2
JVM内存模型、相关参数设置与命令查看 JVM内存模型,你看这一篇就够了 - 知乎 (zhihu.com)
Java虚拟机—Java8内存模型JVM(整理版) - 牧梦者 - 博客园 (cnblogs.com)
JVM入门——JVM内存结构 - 那股泥石流 - 博客园 (cnblogs.com)
JVM参数调优总结 -Xms -Xmx -Xmn -Xss_jakeswang的博客-CSDN博客_xms xmx
JVM的垃圾回收机制——垃圾回收算法 - 知乎 (zhihu.com)
元空间与直接内存的关系_Ethan_199402的博客-CSDN博客_元空间和直接内存有什么区别
jstat 参数详解_netboy_n的博客-CSDN博客_jstat参数分析
为什么设置-Xmx4g但是java进程内存占用达到8g?_斗者_2013的博客-CSDN博客_java占用多少内存
1、JVM简介 1.1 什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的简称,是一种用于计算设备的规范,是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。
1.2 JVM的优点: 一次编写,到处运行。 JVM可以让java程序,一次编写,导出运行。让底层代码和运行环境分离开,编写好一份代码后,不用再次修改内容,只用通过安装不同的JVM环境自动进行转换即可运行,在各种系统中无缝连接。
自动内存管理,垃圾回收机制。 在Java诞生之时,C和C++称霸天下,但是这两种语言中没有内存管理机制,是通过手动操作来进行的管理,非常麻烦和繁琐。
此时Java应运而生,为了处理内存管理这个方面,专门设计了垃圾回收机制,来自动进行内存的管理。极大的优化了操作,让程序员们不用正在噼里啪啦在码代的海洋中遨游时,还要操心内存会不会溢出这些“影响我方输出”的问题,顿时获得了成吨的好评。
数组下标越界检查 在Java诞生之时,还有个让当时C和C++大佬头疼的问题是,数组下标越界是没有检查机制的,这还了得,又是一个影响“我方暴力输出”的罪魁祸首,因此JVM继续抱着暖男的思想,又来了个爱的抱抱。
JVM又一次看见了大佬们的烦恼,果断提供了数组下标越界的自动检查机制,在检测到数组下标出现越界后,会在运行时自动抛出“java.lang.ArrayIndexOutOfBoundsException”这个异常,在当时可是感动了很多业界大佬(我猜的)。
多态 JVM还有一个多态功能,是通过相同接口,不同的实例进行实现,完成不同的业务操作,比如:定义了一个动物接口(里面有一个吃的方法),我们就可以通过这个动物创造小猫(吃鱼),再创造一个狗狗(吃肉)。
1.3 JVM、JRE、JDK之间的关系 JVM JVM是Java Virtual Machine的简称,是Java虚拟机,是一种模拟出来的虚拟计算机,它通过在不同的计算机环境当中模拟实现计算功能来实现的。引入Java虚拟机后,Java语言在不同平台上运行时就不需要重新编译。在其中,Java虚拟机屏蔽了与具体平台的相关信息,使得Java源程序在编译完成之后即可在不同的平台运行,达到“一次编译,到处运行”的目的,Java语言重要的特点之一跨平台,也即与平台的无关性,其关键点就是JVM。
JRE JRE是Java Runtime Environment的简称,是Java运行环境,是让操作系统运行Java应用程序的环境,其内部包含JVM,也就是说JRE只负责对已经存在的Java源程序进行运行的操作,它不包含开发工具JDK,对JDK内部的编译器、调试器和其它工具均不包含。
JRE包括JVM和基础类库 JDK JDK是Java Development Kit的简称,是Java开发工具包,是整个Java程序开发的核心。其主要包含了JRE、Java的系统类库以及对Java程序进行编译以及运行的工具,例如:javac.
第六章 字典 6.1 一个简单的字典6.2 使用字典6.2.1 访问字典中的值6.2.2 添加键值对6.2.3 先创建一个空字典6.2.4 修改字典中的值6.2.5 删除键值对6.2.6 由类似对象组成的字典6.2.7 使用get()来访问值 6.3 遍历字典6.3.1 遍历所有键值对6.3.2 遍历字典中的所有键6.3.3 按特定顺序遍历字典中的所有键6.3.4 遍历字典中的所有值 6.4 嵌套6.4.1 字典列表6.4.2 在字典中存储列表6.4.3 在字典中存储字典 6.1 一个简单的字典 输入:
# 6.1 一个简单的字典 alien_0 = {'color':'green','points':5} #存储外星人的颜色和分数 print(alien_0['color']) print(alien_0['points']) 输出:
green 5 6.2 使用字典 字典是一系列键值对。每个 键 与 一个值相关联,可以使用键来访问相关联的值。
与键关联的值可以是 数、字符串、列表乃至字典。可将任何Python对象用作字典中的值。
alien_0 = {'color':'green','points':5} 键值对,键和·值之间用冒号分隔,而键值对之间用逗号分隔。
在字典中,想存储多少个键值对都可以。
6.2.1 访问字典中的值 输入:
alien_0 = {'color':'green'} #依次指定 字典名 和 放在方括号内的键 与 值 print(alien_0['color']) 输出:
green 下面访问alien_0的颜色和分数。
alien_0 = {'color':'green','points':5} #定义字典 new_points = alien_0['points'] #获取值赋值给变量 print(f"
使用背景: 在很多场合下,我们需要分析数据库操作日志来确认开发人员是否存在误操作,类似删表和删除数据等操作。这个时候就可以使用logmnr工具来分析归档日志。
使用方法:
(1)首先确保数据库处于归档模式下,且保留的归档文件日志包含误操作日志。
(2)确保数据库参数RLOG_APPEND_LOGIC为1或者2,如果为0,归档文件记录的操作会很少。
查询参数值方法:
select * from v$dm_ini where para_name=’RLOG_APPEND_LOGIC’;
(3)查看数据库保留归档信息,通过如下sql语句查看归档文件信息
select first_time,name from v$archived_log;
根据FIRST_NAME(日志文件起始时间)来确定需要查看的归档范围。
(4)添加需要分析的归档日志
call dbms_logmnr.add_logfile('/dm8/dmarch/ARCHIVE_LOCAL1_20161013025146670_0.log');
(5)确认归档日志是否被加载
select * from v$logmnr_logs;
(6)启动日志分析
DBMS_LOGMNR.START_LOGMNR(OPTIONS=>2128,STARTTIME=>TO_DATE('2021-05-01 00:00:00','YYYY-MM-DD HH24:MI:SS') ,
ENDTIME=>TO_DATE('2021-05-25 00:00:00','YYYY-MM-DD HH24:MI:SS'));
(7)查看v$logmnr_contents视图找出对应的操作,例如:
select start_timestamp,sql_redo from v$logmnr_contents
where table_name='TEST' and operation='INSERT';
SELECT * FROM v$logmnr_contents
where table_name='TEST' and USERNAME<>’SYSDBA’;
v$logmnr_contents视图
(8)通过分析v$logmnr_contents视图分析所有的操作日志。
注:(dbms_logmnr.add_logfile语句中每次只能添加一个归档文件,但是可以通过批量执行多个dbms_logmnr.add_logfile语句的方式添加归档,再次分析需要停止日志分析DBMS_LOGMNR.END_LOGMNR)
批量添加要分析的归档方式如下:
call dbms_logmnr.add_logfile('/dm8/dmarch/ARCHIVE_LOCAL1_20210513025146670_0.log');
call dbms_logmnr.add_logfile('/dm8/dmarch/ARCHIVE_LOCAL1_20210514152249980_0.log');
call dbms_logmnr.add_logfile('/dm8/dmarch/ARCHIVE_LOCAL1_20210516152386170_0.log');
call dbms_logmnr.add_logfile('/dm8/dmarch/ARCHIVE_LOCAL1_20210521192837512_0.log');
之后再分析即可:
DBMS_LOGMNR.START_LOGMNR(OPTIONS=>2128,STARTTIME=>TO_DATE('2021-05-01 00:00:00','YYYY-MM-DD HH24:MI:SS') ,
ENDTIME=>TO_DATE('2021-05-25 00:00:00','YYYY-MM-DD HH24:MI:SS'));
一维数组能开到 4 9909 9039 (四亿多)
二维数组能开到 2 2340 (两万多)
这个数据是我在自己电脑上用codeblocks运行测试得到的结果
如果数组大小稍微超过上面的两个数字不会报错,但是测试输出最后一位输出为空
如果数组大小超过上面两个数字很多,例如五亿,那么会报错,无法编译成功
看了一下这个数据,大概就是二维的平方差不多就是一维的大小
该文主要介绍滞后差分和diff()函数。文章仅供学习使用,欢迎留言交流哦!
首先解释滞后差分。
滞后差分:滞后项一般是指该变量的前一期的值,而差分则是当期值与前一期的值之差(一阶)。
例如:存在向量C(x1,x2,x3,x4,x5),若为一阶(滞后一阶是前一期的值),滞后差则是当前项与前一项的差,如:x2-x1,x3-x2。
若为二阶(滞后二阶是前两期的值),滞后差则是当前项与前二项的差。如:x3-x1,x4-x2。
其次介绍diff()函数:
diff(x , lag , differences)
# x 指输入的数据,可以是向量,也可以是矩阵 。
# lag 指为几阶滞后,默认为 1 。
# differences 指连续执行 n 次 diff 。默认为 1 。
输入以下代码(在Rstudio上运行),运行后可以获得 diff 函数的结果:
set.seed(2002)#设置随机数种子,获得和我一样的随机数 x <- sample(1:100,10)#获得1到100中随机十个数 diff(x,lag = 1)#一阶滞后差分 diff(x,lag = 2)#二阶滞后差分 diff(x,lag = 1,differences = 2)#执行两次一阶滞后差分 产生的随机数如下所示:
> x [1] 35 89 97 96 48 72 86 81 16 26 点击 “run” 之后,获得结果如下图所示:
如果有什么问题或者疑问,欢迎留言交流!记得点赞哦!
1.Linunx的基础操作和命令 CentOs6的都可以 使用 init 3 进入命令界面 init 5 进入图形界面 CentOs7就没用安装图形界面的功能,需要自己安装图形界面! CentOs7 如果需要修改IP 如下: cat /etc/issue 查看系统版本 ip addr 查看网卡 名称 1.打开配置文件
输入下面命令,打开目录进入文件夹。
cd /etc/sysconfig/network-scripts/ 使用 ls 查看列表
编辑
vim ifcfg-Auto_eth2 进入后按 esc 后 按 i 编辑, 编辑好后, 按esc 后 按 :wq 保存
1.场景1----以下是正在使用的 以dhcp模式的自动获取IP的方式所有,文件中没用静态固定ip
2.场景2=-----可以自己设定IP---- esc-i-输入进入ip等等 -esc-:wq 保存
然后 刷新网络
service network restart 修改完成!
: 如果是 CentOs7或者8的话 一般网卡都是 eth33 相同的地址进去就是修改更方便
cd /etc/sysconfig/network-scripts/ vim ifcfg-ens33 Linux常用命令: 临时关闭防火墙 Service iptables stop (关闭后就生效) 临时开启防火墙 Service iptables start 永久关闭防火墙 chkconfig iptables off (需要重启才能生效,不想重启就要先执行临时关闭命令) 永久开启防火墙 chkconfig iptables on 2.
Java中对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去。
例如:对象A和对象B都属于类S,具有属性a和b。那么对对象A进行拷贝操作赋值给对象B
就是: B.b = A.a;
B.b = A.a;
Java中的对象拷贝主要分为:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)
浅拷贝:
对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性复制一份给新的对象。因为是两份不同的数据,所以对其中一的对象的成员变量值进行修改,不会影响另一个对象拷贝得到的数据。对于数据类型是引用类型的成员变量,比如说成员变量是某个数组,某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用指(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。 实现浅拷贝主要有以下方式:
通过拷贝构造方法 public class CopyConstructor { public static void main(String[] args) { Age a = new Age(20); Person p1 = new Person(a,"宁采臣"); Person p2 = new Person(p1); System.out.println("p1是"+p1); System.out.println("p2是"+p2); //修改p1的各属性值,观察p2得到各属性值是否跟随变化 p1.setName("聂小倩"); a.setAge(18); System.out.println("修改后的p1是"+p1); System.out.println("修改后的p2是"+p2); } } class Person{ private Age age; private String name; public Person(Age age,String name){ this.age = age; this.name = name; } //拷贝构造方法 public Person(Person p){ this.
技巧总结 有的题目直接按照题意模拟很繁琐,有时候解题可以像解数学题目一样,数形结合,画个图总结一下变化规律,再根据规律实现代码要容易的多(题目很繁琐的时候,再向前推导一步) 解题思路 k = 0,t表示行驶路程的时间,直接累加
k = 1;t表示人在起点时,该红灯剩余的时间
k = 2;t表示人在起点时,该黄灯剩余的时间
k = 3;t表示人在起点时,该绿灯剩余的时间
可以画一个坐标图模拟过时间cnt后灯的颜色,从而计算还需等待多久
代码实现 #include <iostream> #include <cstring> #include <algorithm> using namespace std; int main() { int r, y, g, n; cin >> r >> y >> g >> n; int cnt = 0; //记录从起点开始总共花费的时间 while (n --) { int k, t; cin >> k >> t; if (!k) //是路程则直接加 { cnt += t; continue; } else { //将t转换成坐标值 if (k == 1) t = r - t; else if (k == 2) t = r + g + y - t; else t = r + g - t; //坐标上的点移动cnt的长度 t = (t + cnt) % (r + g + y); //判断终点此时还需要等待多久才能变成绿灯 if (t >= 0 && t < r) cnt += (r - t); else if (t >= r && t < r + g) cnt += 0; else if (t >= r + g && t < r + g + y) cnt += (r + g + y - t) + r; } } cout << cnt; return 0; }
RabbitMQ安装 RabbitMQ安装整理Add Yum Repositories for RabbitMQ and Modern ErlangInstall Packages with Yum RabbitMQ安装整理 CentOS 8.5 x64
## Uses a PackageCloud-provided Yum repository setup script. ## Always verify what is downloaded before piping it to a privileged shell! curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash ## primary RabbitMQ signing key rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc ## modern Erlang repository rpm --import https://packagecloud.io/rabbitmq/erlang/gpgkey ## RabbitMQ server repository rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey 如果下载失败,可以下载到本地再上传并rpm import
Add Yum Repositories for RabbitMQ and Modern Erlang In order to use the Yum repository, a .
转载:全网最全:Java9全部新特性一览 - 知乎
甲骨文发布了具有丰富新特性的Java9。它包括对Java编程、JVM、工具和库的各种升级。在本篇文章中,我们将讨论下面给出的所有主要特性:
平台模块系统(Jigsaw项目)接口私有方法Try-With Resources匿名类@SafeVarargs注释集合工厂方法Process API改进新版本字符串方案JShell:javashell(REPL)控制面板流API改进针对Microsoft windows及更多应用程序的安装程序增强功能 Java平台模块系统(Jigsaw项目) 它是一种新的Java编程组件,可以用来收集Java代码(类和包)。这个项目的主要目标是轻松地将应用程序缩小到小型设备。在Java9中,JDK本身已经划分为一组模块,以使其更加轻量级。它还允许我们开发模块化应用程序。
接口私有方法 在Java9中,我们可以在接口中创建私有方法。接口允许我们声明有助于在非抽象方法之间共享公共代码的私有方法。
在Java9之前,在接口中创建私有方法会导致编译时错误。
Try-With Resources Java在java7中引入了 try-with-resource 特性,该特性有助于在使用资源后自动关闭资源。
换句话说,我们可以说我们不需要显式地关闭资源(文件、连接、网络等),尝试使用 AutoClosable 接口自动关闭资源。
在Java7中,try with resources有一个限制,要求resource在区块中本地声明。
匿名类改进 Java9引入了一个新特性,允许我们将 diamond 运算符用于匿名类。Java7中不允许在匿名类中使用 diamond 。
在Java9中,只要推断的类型是可表示的,我们就可以在创建匿名内部类时使用菱形运算符。
Java@SafeVarargs注释 它是应用于接受 varargs 参数的方法或构造函数的注释。它用于确保方法不会对其 varargs参数执行不安全的操作。
它包含在Java7中,只能应用于
最终方法静态方法构造函数 Java集合工厂方法 工厂方法是一种特殊类型的静态方法,用于创建集合的不可修改实例。这意味着我们可以使用这些方法创建少量元素的列表、集合和映射。
它是 不可修改 的,因此添加新元素将引发 java.lang.UnsupportedOperationException 异常
Java Process API改进 Java改进了java9版本中的process api,有助于管理和控制操作系统进程。
在早期版本中,使用Java编程来管理和控制操作系统进程非常复杂。现在,添加了新的类和接口来执行此任务。
Java新版本字符串方案 Java版本字符串是包含特定于版本的信息的格式。此版本字符串由主要版本、次要版本、安全版本和修补程序更新版本组成。
在java9中,引入了一种新的字符串格式。
JShell:javashell(REPL) 它是一个交互式Javashell工具,它允许我们从Shell执行Java代码并立即显示输出。JShell是一个REPL(Read Evaluate Print Loop)工具,从命令行运行。如果我们想测试我们的业务逻辑并立即得到结果,这是有益的。
Java 9控制面板 Java控制面板用于控制嵌入在浏览器中的Java应用程序。此控制面板维护管理嵌入在浏览器中的Java应用程序的设置。
在Java9中,控制面板被重写为JavaFX应用程序,并且存储位置发生了变化。
Java9流API改进 在Java9中,流API得到了改进,并向流接口添加了新方法。 TakeWhile 、 dropWhile 和 ofNullable ,以及一个重载迭代方法来对流元素执行操作。
navicat怎么清除干净? 1、win + R 输入 regedit
2、输入:计算机\HKEY_CURRENT_USER\Software\PremiumSoft
这样就把Navicat清除干净了。
目录
前言:
1、什么是值拷贝?
2、什么是引用赋值?
3、例子:
(1)代码1:值拷贝
(2)代码2:引用赋值 4、代码纠正: 前言: 打卡!打卡!
今天看到这个容易混淆的地方,在这之前我都不知道、没注意,今天补上,当个笔记。
1、什么是值拷贝? 简单来说就是复制,把第一个变量的值复制给第二个变量,改变第二个变量的值不会影响第一个变量的值。
2、什么是引用赋值? 就是引用值,在堆中放有一堆数据,栈中的变量1和变量2去引用这个堆里的数据,改变任何一个变量的值,就是改变堆里的值,另一个变量的值也会随之而变。
3、例子: (1)代码1:值拷贝 int n1 = 10; //初始化 int n2 = n1; //初始化 n2 = 80; //改变n2的值 System.out.println(n1); //结果为10 System.out.println(n2); //结果为80 我们可以看到上面代码,值拷贝只改变一个变量,另一个变量不会改变。
(2)代码2:引用赋值 int[] arr1 = { 1, 2, 3}; //数组初始化 int[] arr2 = arr1; //数组初始化 arr2[0] = 10; //改变第二个数组的第一个元素 System.out.println(arr1[0]); //结果为10 System.out.println(arr2[0]); //结果为10 为什么两个结果都改变了呢?因为数组赋值(arr2 = arr1)是赋的地址,把arr1的地址给了arr2,两个数组使用的是同一个堆中的数据,所以无论改变哪个数据,另一个也会改变。
那怎么使两个数组数据分开,互不干扰呢?前面说了,是因为使用了同一个堆,那我们再开辟一个堆出来不就解决问题了。
4、代码纠正: int[] arr1 = { 1, 2, 3}; //赋初值 int[] arr2 = new int[arr1.
不仅要在宝塔面板中放行8080端口还要在华为云的入方向规则中放行8080端口才行。
嵌套式CMakeLists写法,文件结构如下:
|--examples | |--add_example.c | |--sub_example.c |--CMakeLists.txt |--add | |--add.c | |--add.h |--sub | |--sub.c | |--sub.h 文件内容详情见C/C++开发之CMakelist(其一)
将C/C++开发之CMakeList(其一)的内容推广,我们可以将对应文件相对路径分别记录,再统一编译运行
需要注意添加include_directories,指定include目录,否则在add.c与sub.c中可能找不到头文件。
#最小cmake版本 cmake_minimum_required(VERSION 2.8) #项目名字,随意起 project(simple_exe) #设置C/c++版本(如c99,c++11,c++17等版本),下面表示使用c99版本 set(CMAKE_C_STANDARD 99) #指定include路径 #${CMAKE_CURRENT_SOURCE_DIR}表示当前文件目录,是cmake内置变量 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/add/) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sub/) #set作用为将第一个字符之后的字符命名为第一个字符, #下面的例子表示将add.c与sub.c用SOURCES表示,即SOURCES = [add.c, sub.c] set(SOURCES add/add.c sub/sub.c ) #将可执行文件统一命名为MAIN_FILES set(MAIN_FILES examples/add_example.c examples/sub_example.c ) #将文件打包成alg库,中间的选项STATIC表示静态库,${SOURCES}为源文件,alg为生成的静态库名字 add_library(alg STATIC ${SOURCES}) #循环MAIN_FILES中的每一个元素 foreach(mainfile ${MAIN_FILES}) #获取不带文件后缀的文件名,下面的作用为提取add_example与sub_example get_filename_component(mainname ${mainfile} NAME_WE) #将mainfile编译生成可执行文件mainname add_executable(${mainname} ${mainfile}) #将静态库链接到可执行文件中 target_link_libraries(${mainname} alg) endforeach() 但是头文件过多时,写起来不方便,用户调用也不方便,最好的方式是将所有头文件整合到一起,统一加到alg.h中,文件结构如下:
|--examples | |--add_example.c | |--sub_example.
打开Navicat Premium 出现如下情况:
解决方案:
1.右击“此电脑”,再点击“管理”,
2.找到“服务与应用程序”下的“服务”,并点击“服务”
3.找到MYSQL右击启动即可。
useUrlState 使用起来特别简单
第一步
npm i @ahooksjs/use-url-state -S
第二步使用
import useUrlState from '@ahooksjs/use-url-state';
const [state, setState] = useUrlState({ 路径参数1: '1', 路径参数2: '10' });
state:即你当前路径上的参数
setState:即修改你当前路径上的参数
官网地址贴这里了 贼好用
useUrlState - ahooks 3.0
报错内容:
从报错信息中可以看到是路径:${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D错误。
修改hive组件配置文件hive-site.xml(由hive-default.xml.template复制而来):
cd /usr/local/src/hive/conf/hive-site.xml 将以下位置的 ${system:java.io.tmpdir}/${system:user.name} 替换为 “/usr/local/src/hive/tmp”目录及其子目录。
需要替换以下 4 处配置内容:
<name>hive.querylog.location</name> <value>/usr/local/src/hive/tmp</value> <description>Location of Hive run time structured log file</description> <name>hive.exec.local.scratchdir</name> <value>/usr/local/src/hive/tmp</value> <name>hive.downloaded.resources.dir</name> <value>/usr/local/src/hive/tmp/resources</value> <name>hive.server2.logging.operation.log.location</name> <value>/usr/local/src/hive/tmp/operation_logs</value> 注意:四个位置不是连续的
修改完之后再重新打开hive即可
最早用ReadDriverInfoNT,发现在特殊的笔记本上获取不到数据,一下的方法能解决这个问题。
试了很多台电脑,总是有一种方法是能获取到数据的
主函数部分:
unsigned char hdsn[41]; OSVERSIONINFO version; memset(&version,0,sizeof(OSVERSIONINFO)); version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&version); if(version.dwPlatformId == VER_PLATFORM_WIN32_NT) { int ret= ReadDriverInfoNT(hdsn); if (ret ==FALSE) { ret =ReadPhysicalDriveInNTWithAdminRights(hdsn); } if (ret ==FALSE) { ret =ReadIdeDriveAsScsiDriveInNT(hdsn); } if (ret ==FALSE) { ReadPhysicalDriveInNTWithZeroRights(hdsn); } } else { MessageBox(NULL,"ReadDriverInfoNT Failure!","LicenseApp",NULL); return 0; } ReadDriverInfoNT
int ReadDriverInfoNT(unsigned char *hdsn) { int iDone = FALSE; HANDLE hPhysicalDriverIOCTL = 0; char drivename[256]; sprintf(drivename,"\\\\.\\PHYSICALDRIVE%d",0); hPhysicalDriverIOCTL = CreateFile(drivename,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING, 0, NULL); if(hPhysicalDriverIOCTL !
DHCP 代表动态主机配置协议。它是存在于应用层的网络管理协议。在它的帮助下,可以将 Internet 协议 IP 地址动态分配给网络上的任何设备或节点,以便它们可以使用该 IP 进行通信。网络管理员的任务是为网络中的所有设备手动分配大量 IP 地址。然而,在这种情况下,任务是自动化和集中管理的,而不是手动的。小型本地网络和大型企业网络都实施它。它的基本目标是为主机分配一个唯一的 IP 地址。它还提供其他网络地址,例如 :
子网掩码路由器地址DNS 地址供应商类标识符 它有两种不同的方式,即作为客户端和服务器。
DHCP 的历史
它是 BOOTP 的扩展版本,通常称为 Bootstrap 协议,这是 1985 年的网络 IP 管理协议。如果这些客户端存在于网络中, DHCP 服务器足以处理来自 BOOTP 客户端的请求。不仅如此,与 BOOTP 相比,DHCP 更先进。
它是如何工作的?
充当服务器时,DHCP 服务器会自动分配唯一的 IP 地址以及配置网络的其他信息。在小型企业或家庭中,DHCP 服务器就是路由器。但是,在大型网络中,DHCP 服务器可以是单台计算机。
对这个过程中发生的事情的一个非常简短的总结是:
客户端向主机发送一个 IP 地址请求。客户端可以是任何发送请求的设备,主机可以是路由器。主机将寻找可用的 IP 地址并将其分配给客户端。使用此 IP 地址,客户端将能够在网络上进行通信。 现在让我们更详细地看一下这个过程。下面提到的步骤对其进行了深入的了解:
1、连接到具有 DHCP 服务器的网络的设备发送的请求称为 DHCPDISCOVER 请求。
2、此请求以名为 DISCOVER 的数据包的形式发送到 DHCP 服务器。一旦 DHCP 服务器收到此数据包,服务器就会查找设备使用的 IP 地址。一旦找到,服务器通过向客户端发送一个名为 DHCPOFFER 的数据包进行响应。
3、设备或客户端现在必须使用名为 DHCPREQUEST 数据包的数据包响应服务器,以接受所选的 IP 地址。对于此数据包,服务器会发送确认 (ACK) 以确认设备现在可以使用该特定 IP 地址。它还说明了特定 IP 地址的有效性,以便设备确切知道何时必须获取新的 IP 地址。
1、检测telnet-server的rpm包是否安装
rpm -qa telnet-server
2、安装telnet(服务端客户端都安装)
yum install -y telnet
yum install -y telnet-server
yum install -y xinetd
3、修改配置文件
vim /etc/xinetd.d/telnet
service telnet
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
disable = yes #改为 no 或者注释这一行
}
4、重启telnet服务
service xinetd restart
提示: Login incorrect
tail /var/log/secure
Jun 11 17:24:32 vm-kvm9188-app login: pam_securetty(remote:auth): access denied: tty 'pts/2' is not secure !
问题描述 **fastadmin安装报错**
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
原因分析: 由于MySQL 8默认使用了新的密码验证插件:caching_sha2_password,而之前的PHP版本中所带的mysqlnd无法支持这种验证。解决这个问题,有两种办法。
解决方案: 方案1:升级PHP支持MySQL 8的新验证插件或者降低MySQL版本。;
方案2:开启MySQL 8的向PHP兼容。;
修改默认MySql8支持mysql_native_password
etc/my.cnf配置文件中,有一行:
# default-authentication-plugin=mysql_native_password
取消注释或者自己添加。
然后创建的新用户就会默认支持mysql_native_password
创建新用户开启插件方法如下
CREATE USER ‘native‘@‘localhost‘ IDENTIFIED WITH mysql_native_password BY ‘password!2#4‘;
已经创建好的用户修改方法如下
ALTER USER ‘native‘@‘localhost‘ IDENTIFIED WITH mysql_native_password;
上面这种方法会清除账户密码,下面这种方式会指定一个新密码
ALTER USER ‘native‘@‘localhost‘ IDENTIFIED WITH mysql_native_password BY ‘new_password‘;
EXSI导入ovf、vmdk提示缺少所需的磁盘映像
编辑ovf文件,找到ovf:href后的乱码名称(实为中文名称,平台无法通过.OVF找到对应的磁盘印象),修改为vmdk一致名称即可。
文章目录 ISO标准C 委员会 与 C++ 委员会如何制定标准C++ 的实现compiler intrinsicMSVCGCCC++11 标准后 参考 ISO标准 这里直接照搬百度百科:https://baike.baidu.com/item/ISO%E6%A0%87%E5%87%86/9818656?fr=aladdin
ISO标准是指由『 国际标准化组织 (International Organization for Standardization), ISO 』制订的标准。 国际标准化组织是一个由国家标准化机构组成的世界范围的联合会,现有140个成员国。根据该组织章程,每一个国家只能有一个最有代表性的标准化团体作为其成员,中国原国家质量技术监督局以CSBTS名义国参加ISO活动。
ISO的前身是国际标准化协会(ISA),ISA成立于1926年(1926年美、英、加等七国标准化机构第三次代表联席会议决定成立国际标准化协会,并于1928年成立)。第二次世界大战的爆发,迫使ISA停止工作。战争结束后,大环境为工业恢复提供了条件,于是1946年10月,来自25个国家标准化机构的领导人在伦敦聚会,讨论成立国际标准化组织的问题,并把这个新组织称为ISO,即International Organization for Standardization的简称。会议一致通过了ISO章程和议事规则。1947年2月23日ISO开始正式运行,ISO的中央办事机构设在瑞士的日内瓦。中国既是发起国又是首批成员国。
ISO的组织机构包括:ISO全体大会、主要官员、成员团体、通信成员、捐助成员、政策发展委员会、合格评定委员会(CASCO)、消费者政策委员会(COPOLCO)、发展中国家事务委员会(DEVCO)、特别咨询小组、技术管理局、技术委员会TC、理事会、中央秘书处等。
C 委员会 与 C++ 委员会 https://www.open-std.org/jtc1/sc22/wg21/
https://isocpp.org/std/the-standard
上面第一个链接可以看到一堆paper,第二个链接则可以看到标准。草案不需要购买,但是标准是需要购买的。
通过这个网站:
https://www.open-std.org/jtc1/sc22/
可以看的 JTC1/SC22 的成员,有 C(WG14)、C++(WG21)、Linux(WG14)
国际 C++ 标准委员会正式名称为 ISO/IEC JTC1/SC22/WG21,它是 C++ 发展的核心。
同时我们参考维基百科,可以看到:
https://en.wikipedia.org/wiki/C%2B%2B
主要受到 Simula 和 C 的影响,同时 C++ 影响了众多语言。
如何制定标准 传统上,ISO 标准每十年左右修订一次。例如,我们有 C89、C99 和 C11。如此长的修订周期是有问题的,如果新特性错过了特性冻结,我们就会要再等上 12 年左右才能将它加入标准。人们自然就会主张将即将通过的标准拖延一两年:“这个特性太重要了,不能等,因此得延迟一下标准的发布!”这就是为什么原本的 C++0x 结果成了 C++11,在 C++98 后过了 13 年。
一、安装驱动 cd ~ git clone https://github.com/jetsonhacksnano/installSwapfile cd installSwapfile ./installSwapfile.sh reboot cd ~ git clone https://github.com/jetsonhacksnano/installLibrealsense //下载自己想要的版本,这里使用2.50.0(最新版),记住realsense-ros对realsense的版本有要求 git clone https://github.com/IntelRealSense/librealsense/releases/tag/v2.50.0 cd installLibrealsense gedit ./buildLibrealsense.sh 修改上图中的1、2、4行内容,和自己的系统匹配
其中第一行是git clone下来的librealsense位置;第二行是对应的版本;第四行进/usr/local看看自己的cuda是什么版本的,改成相应的版本就行了。下一步确保自己的系统能顺利git clone, 而且关闭本终端外的其他应用,以下编译过程会占用很大运行内存,编译到一半后会卡住,请耐心等待编译:
./buildLibrealsense.sh 这一步中会git一个东西。
测试:
cd ~/Documents/librealsense/build/examples/capture ./rs-capture 但我realsense-viewer打开后始终没有显示设备接入,这里先不管,因为后面能正常跑realsense的ROS包。
二、安装ROS包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src/ git clone https://github.com/IntelRealSense/realsense-ros.git cd realsense-ros/ git checkout `git tag | sort -V | grep -P "^\d+\.\d+\.\d+" | tail -1` cd .. catkin_init_workspace cd .. catkin_make clean catkin_make -DCATKIN_ENABLE_TESTING=False -DCMAKE_BUILD_TYPE=Release catkin_make install echo "
java:1.8
flink-1.13.6-bin-scala_2.11
hive:1.1.1
hadoop:2.6.0-cdh5.16.2
通过纯SQL的流模式提交到远程flink集群执行,中间遇到不少问题,现在终于能跑通了,附码云地址
https://gitee.com/shenxiang2020/flink-study.git
首先我们可以知道在Python中,数学模块包含许多数学运算,可以使用该模块轻松执行。例如math.gcd()函数计算其参数中提到的2个数的最大公约数 计算最大公约数和最小公倍数的代码如下
import math
def gcd(x, y):#获取最大公约数
a = math.gcd(x,y)
return a
def lcm(x, y):#获取最小公倍数
b = x * y // math.gcd(x,y)
return b
不知道小伙伴们在配置新电脑的java时有没有遇到过这样的情况,明明下载好了jdk的安装包,双击之后点了下一步就啥都没有了,网上各路大神纷纷出招,但是小弟我的电脑却不行,在总结网上的和自己的之后给大伙安排这篇博客,望各位观众姥爷笑纳~~ 这里我们选择从官网上下载jdk的解压缩版。
链接:https://www.oracle.com/java/technologies/downloads/archive/
进去之后往下拉,会看到这样的。
jdk的所有版本都在这里了,大家凭自己的需要下载。
如果大家没有Oracle的账号,我这里给大家准备了jdk的三个版本。
百度网盘自取,提取码在评论区。
链接:https://pan.baidu.com/s/1ZI6obOjFAh1ccI3MVNyfAQ
第一步 下载一个7-zip解压缩软件,目前我知道的就这一个软件可以实现下面的功能
链接:https://www.7-zip.org/
第二步 右击安装包,选择7-zip软件,选择提取到“jdk-8u251-windows-x64\”,这样它会在此目录下生成一个相同名称的文件夹。
第三步 进入此文件夹里面 =>.rsrc =>1033=>JAVA_CAB10
我们会看一个名为111的文件,右击此文件,选择7-zip然后提取到当前位置
接下来会出来一个tools.zip的压缩包。
第四步 把这个压缩包解压完之后打开就可以看到这样的文件和文件夹,是不是和双击jdk安装包之后的文件夹内容很像啊。
第五步 我们把这些东西复制到新的文件夹,我这里取名为D:/Java/jdk/jdk1.8.0_251,后续我们在更改环境变量时,这个文件就是我们的JAVA_HOME的值了。
第六步 最后一步了,这一步走完我们的jdk才算安装完成
在此D:/Java/jdk/jdk1.8.0_251目录下调出cmd,输入下面命令
for /r %x in (*.pack) do .\bin\unpack200 -r "%x" "%~dx%~px%~nx.jar"
至此,新的jdk安装完成,如果我们需要更换我们电脑的jdk版本可以看我之前的文章,里面有非常详细的更换jdk教程。
链接:https://blog.csdn.net/lcszz0302/article/details/119177184?spm=1001.2014.3001.5501
1.教师表
2.课程表
3.学生表
4.成绩表
1、查询“c001”课程比“c002”课程成绩高的所有学生的学号;
①先查询sc成绩表再在外层设置个s1
②设s1的课程号是c001 ③设条件s1的分数比s2的分数高
④查询出c002的分数并设为s2
⑤判断是同一个人比较,内层的学号等于外层的学号
⑥完整答案视图如下:
2、查询平均成绩大于60 分的同学的学号和平均成绩;
①先查询出学生的学号和成绩平均值,使用AVG函数返回平均值
②学生表和成绩表进行内连接
③最后进行分组判断平均成绩大于60 分 3、查询所有同学的学号、姓名、选课数、总成绩;
①查询学生学号、姓名、选课数、总成绩,选课数和总成绩分别使用函数count和sum
②接着就是学生表和成绩表进行内连接
③最后使用group by分组得出结果
文章目录 L1-1 人与神 (5 分)题目描述题目分析 L1-2 两小时学完C语言 (5 分)题目描述题目分析 L1-3 强迫症 (10 分)题目描述题目分析 L1-4 降价提醒机器人 (10 分)题目描述题目分析 L1-5 大笨钟的心情 (15 分)题目描述题目分析 L1-6 吉老师的回归 (15 分)题目描述题目分析 L1-7 天梯赛的善良 (20 分)题目描述题目分析 L1-8 乘法口诀数列 (20 分)题目描述题目分析 L2-1 包装机 (25 分)题目描述题目分析 L2-2 病毒溯源 (25 分)题目描述题目分析 L2-3 清点代码库 (25 分)题目描述题目分析 L2-4 哲哲打游戏 (25 分)题目描述题目分析 L3-1 森森旅游 (30 分)题目描述题目分析 L3-2 还原文件 (30 分)题目描述题目分析 L3-3 可怜的简单题 (30 分)题目描述题目分析 编辑时间:2022年3月17日14:59:48祝旗开得胜! L1-1 人与神 (5 分) 题目描述 跨界大神 L. Peter Deutsch 有一句名言:“To iterate is human, to recurse divine.
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
是稳定的排序方法
时间复杂度:O(n^2)
二、查找过程
首先计算表中间的位置,将表中间位置处的关键字与查找的关键字进行比较,如果相等,则查找成功;否则利用中间位置将表分为前、后两个子表,如果中间位置的关键字大于查找的关键字,则查找前子表,否则查找后子表。重复上面的过程,直到找到要查找的关键字为止,否则查找失败不存在此关键字。
图示:以i=4时为例:
阅读者可仔细思考一下里面的逻辑,理清思路
第一步
第二步
第三步:
第四步:
第五步:
第六步:
第七步:
public class InsertSort { public static void main(String[] arg) { int[] a=new int[] {49,38,65,97,76,13,27}; int n=a.length; InsertSort1(a,n); } static void InsertSort1(int a[],int n) { int i,j,low,high,mid,temp; int h=1; for (i=1;i<n;i++){ //将a[i]暂存到中间变量,从第二个数开始与前面的数开始依次比较并排序 temp=a[i]; low=0;high=i-1; //判断low是否小于high,如果小于则执行while循环 while(low<=high){ mid=(low+high)/2; //取中间索引位置与temp比较,不断寻找它要插入的位置,知道不满足low<high退出循环 if (a[mid]>temp) high=mid-1; else low=mid+1; } //位置寻找完毕,开始进行数据插入,然后进行到下一个最外层的for循环 for (j=i-1;j>=high+1;--j){ a[j+1]=a[j]; } a[high+1]=temp; //遍历打印每一次插入排序的结果 for(int c=0;c<n;c++) { System.out.print(a[c]+" "
1、case…end (具体的值)
case后面有值,相当于c#中的switch case
注意:case后必须有条件,并且when后面必须是值不能为条件。
-----------------case–end—语法结构---------------------
select name , --注意逗号
case level --case后跟条件
when 1 then ‘骨灰’
when 2 then ‘大虾’
when 3 then’菜鸟’
end as’头衔’from [user]
2、case…end (范围)
case 后面无值,相当于c#中的if…else if…else…
注意:case后不根条件
------------------case—end--------------------------------
select studentId, case
when english between 80 and 90 then ‘优’
when english between 60 and 79 then ‘良’
else ‘差’
end
from Score
------------------case—end--------------------------------
select studentId, case
when english >=80 then ‘优’
when english >=60 then ‘良’
一、环境准备 **(下载并安装好以下工具软件,注:以下版本的工具在win10-64位专业版下正常测试通过)
实验目的:某些小型工业环境中,同网段但是部门不同的PC之间不允许相互访问,可把接口划到不同的VLAN中,以实现局域网的隔离。
1、安装ENSP (1)安装winpcap4.13
(2)安装wireshark_64位3.2.2
(3)安装virtualbox5.2.16
(4)安装ENSP1.3.100
2、打开ENSP,拖出拓扑图如下: 3、情境分析 (1)5台PC机,都是使用192.168.1.0/24的网段IP地址,分别属于IT部、人事部、市场部、研发部,仅client1与client2同属IT部,其余PC各自1个部门。
(2)跨交换机,所以交换机之间的端口作干道trunk处理,直连PC的端口使用access工作模式
(3)为方便管理,每个部门使用一个不同的VLAN ID
二、开始配置 1、依次双击client1、client2、client3、client4、client5配置好IP地址与子网掩码 client2、client3、client4、client5方法相同,不再赘述
2、配置SW1 (1)思路:与SW2相连的干道接口配置为trunk
(2)与PC相连的接口配置为access
(3)把各接口划分到对应的VLAN中
undo terminal monitor
system-view
vlan batch 10 20 30 40
interface Ethernet0/0/1
description to sw2
port link-type trunk
port trunk allow-pass vlan 10 20 30 40
interface Ethernet0/0/2
description it_pc1
port link-type access
port default vlan 10
interface Ethernet0/0/3
description it_pc2
port link-type access
port default vlan 10
第十四章 count(*)这么慢,我该怎么办? count(*) 的实现方式 在不同的 MySQL 引擎中,count(*) 有不同的实现方式:
MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高而 InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数 为什么 InnoDB 不跟 MyISAM 一样,也把数字存起来呢 ?
和 InnoDB 的事务设计有关系,可重复读是它默认的隔离级别,在代码上就是通过多版本并发控制,也就是 MVCC 来实现的。每一行记录都要判断自己是否对这个会话可见,因此对于 count(*) 请求来说,InnoDB 只好把数据一行一行地读出依次判断,可见的行才能够用于计算“基于这个查询”的表的总行数。 MySQL 在查询总数的时候会找到最小的那棵树进行遍历,这也是优化的一部分
B+树只有叶子结点上有数据,全部遍历其实就是对叶子结点的链表进行遍历。此时如果遍历主键索引树,由于其叶子结点上存放的是完整的行信息,对于一个数据页而言其行密度会比较小,最终导致要扫描的数据页较多,进而IO开销也比较大。如果遍历第二索引树,其叶子结点只存放主键信息,其数据页的行密度比较大,最终扫描的数据页较少,节省了IO开销。 show table status 命令中的 TABLE_ROWS 能代替 count(*) 吗 ?
不能实际上,TABLE_ROWS 是通过采样估算得来的,因此它也很不准。官方文档说误差可能达到 40% 到 50%。所以,show table status 命令显示的行数也不能直接使用。 总结 count(*)
MyISAM 表虽然 count(*) 很快,但是不支持事务;show table status 命令虽然返回很快,但是不准确;InnoDB 表直接 count(*) 会遍历全表,虽然结果准确,但会导致性能问题 用缓存系统保存计数 将计数保存在缓存系统中的方式,还不只是丢失更新的问题。即使 Redis 正常工作,这个值还是逻辑上不精确的。
这里主要原因是因为 “MySQL插入一行数据” 跟 “Redis计数加1” 这两个操作是分开的,不是原子性的,这就很可能在中间过程因为某些并发出现问题。更抽象一点:MySQL 和 Redis 是两个不同的载体,将关联数据记录到不同的载体,而不同载体要实现原子性很难,由于不是原子性很容易引起并发问题。如果能将数据统一在同个载体即 MySQL,并由其保证操作的原子性,即将插入一行数据和计数加1作为一个完整的事务,通过事务的隔离此时外界看到的就是要么全部执行完毕,要么全部都没执行,进而保持逻辑一致。 在数据库保存计数 在数据库中建表计数,可以得到精准的计数,方法是通过数据库中的事务来实现的。计数器的修改和数据的写入都在一个事务中。读取计数器和查询最近数据也在一个事务中。 不同的 count 用法 count(*)、count(主键 id)、count(字段) 和 count(1) 等不同用法的性能差别 ?
一、Linux下安装MySQL 1、先检查系统是否有MySQL
rpm -qa | grep mysql
2、下载MySQL的repo源
先切换到/usr/local路径下
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
3、安装mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
4、安装MySQL
yum install mysql-server
5、登录并重置MySQL密码
mysql -u root
报错:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
因为/var/lib/mysql/mysql.sock没有访问权限
授权
chown root /var/lib/mysql
6、重启服务
service mysqld restart
7、修改密码
use mysql;
update user set password=password('root') where user='root';
GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "root";
重启服务
service mysqld restart
8、验证登录MySQL
文章目录 1.说一说三大范式2.MyISAM 与 InnoDB 的区别是什么?3.为什么推荐使用自增 id 作为主键?4.一条查询语句是怎么执行的?5.使用 Innodb 的情况下,一条更新语句是怎么执行的?6.Innodb 事务为什么要两阶段提交?7.什么是索引?8.索引失效的场景有哪些?9.为什么采用 B+ 树,而不是 B-树10.WAl 是什么?有什么好处?11.什么是回表?12.什么是覆盖索引?13.什么是最左前缀原则?14.普通索引和唯一索引该怎么选择?15.什么是事务?其特性是什么?16.事务的隔离级别?17.binlog 是做什么的?18.undolog 是做什么的?19.relaylog 是做什么的?20.redolog 是做什么的?21.redolog 是怎么记录日志的?22.redolog 和 binlog 的区别是什么?23.说一说 mvcc 吧,有什么作用?24.一条 Sql 语句查询一直慢会是什么原因?25.Mysql 主从之间是怎么同步数据的?26.主从延迟要怎么解决?27.删除表数据后表的大小却没有变动,这是为什么?28.为什么 VarChar 建议不要超过255?29.分布式式事务怎么实现?30.Mysql 中有哪些锁?31.为什么不要使用长事务?32.说说你的 Sql 调优思路吧 1.说一说三大范式 三范式简介
1NF:字段不可分;原子性,字段不可再分,否则就不上关系数据库
2NF:有主键,非主键字段依赖主键;唯一性,一个表只说明一个事物
3NF:非主键字段不能相互依赖;每列都与主键有直接关系,不存在传递依赖
详解
第一范式(1NF):
即表的列具有原子性,不可再分割,即列的信息,不能分解,只要数据库是关系型数据库(mysql/oracle/db2/informix/sysbase/sql server)就自动的满足1NF。数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项,如果实体中的某个属性有多个值时,必须拆分为不同的属性 。通俗理解即一个字段只存储一项信息。
第二范式(2NF):
第二范式是在第一范式的基础上建立起来的,即满足第二范式一定满足第一范式。第二范式要求数据库表中的每个实例或行必须可以被唯一区分。为实现区分通常需要我们设计一个主键来实现(这里的主键不包含业务逻辑)。
即满足第一范式前提,当存在多个主键的时候,才会发生不符合第二范式的情况。比如有两个主键,不能存在这样的属性,它只依赖于其中一个主键,这就是不符合第二范式。通俗理解是任意一个字段都只依赖表中的同一个字段。(涉及到表的拆分)
第三范式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主键字段。就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放(能尽量外键join就用外键join)。很多时候,我们为了满足第三范式往往会把一张表分成多张表。
即满足第二范式前提,如果某一属性依赖于其他非主键属性,而其他非主键属性又依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。 通俗解释就是一张表最多只存两层同类型信息。
2.MyISAM 与 InnoDB 的区别是什么? InnoDB支持事务,MyISAM不支持InnoDB 支持外键,而 MyISAM 不支持InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和索引绑在一起的,必须要有主键。MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的InnoDB 不保存表的具体行数。MyISAM 用一个变量保存了整个表的行数Innodb 有 redolog 日志文件,MyISAM 没有Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI
(1)Innodb:frm是表定义文件,ibd是数据文件
(2)Myisam:frm是表定义文件,myd是数据文件,myi是索引文件InnoDB 支持表、行锁,而 MyISAM 支持表级锁InnoDB 必须有唯一索引(主键),如果没有指定的话 InnoDB 会自己生成一个隐藏列Row_id来充当默认主键,MyISAM 可以没有 3.
vue2+高德地图web端开发(使用和引入) 前言基础 准备工作高德地图的个人开发者注册高德api网址1.点击进行注册2.注册完之后进入控制台3.创建新应用4.添加 高德 2.0 新增 创建vue2的项目npm 引入高德官方文档1.安装2.进入项目3. NPM 方式安装使用 Loader4.在component目录下新建MapContainer.vue5.编写基础页面结构6. 在< script >中引入AMapLoader6.1 import6.2 引入安全密钥完整代码 7.构建地图7.1data数据声明7.2methods中构建初始化地图方法7.3mouted生命周期中调用方法对页面进行渲染 完整代码 vue使用结果展示 前言 本人非专业前端开发,其实是搞后端的,但是正好接了一个项目需要我负责全栈,所以写了这个系列的文章,如果以后项目可以开源我会放出来的
本次我们要实现的是vue2+高德地图的网页开发
基础 本文需要大家系统学过vue以及初步了解高德地图的情况下理解起来会十分省力
准备工作 高德地图的个人开发者注册 高德api网址 https://lbs.amap.com
1.点击进行注册 2.注册完之后进入控制台 3.创建新应用 4.添加 选择Web端后
高德 2.0 新增 按照步骤全部弄好之后就完成了注册
最后你会获得你注册的key和安全密钥,是我们后面使用的关键
创建vue2的项目 创建项目上我想应该不用怎么交了吧
vue create XXXXxcd XXXXxnpm run serve npm 引入高德 官方文档 https://lbs.amap.com/api/jsapi-v2/guide/webcli/map-vue1
1.安装 打开windows powershell 管理员权限
2.进入项目 3. NPM 方式安装使用 Loader npm i @amap/amap-jsapi-loader --save 4.在component目录下新建MapContainer.vue 5.编写基础页面结构 div的id是你要自定的,叫什么无所谓但是后面地图初始化的时候需要用到,你只要注意一下就可以
<template> <div id="container"></div> </template> <script> export default { } </script> <style lang="
1 简介 介绍了概率神经网络的模型,分析了其特点,并探讨了基于PNN的发动机故障诊断方法.通过MATLAB进行仿真试验,结果表明基于概率神经网络的故障诊断方法可以最大程度地利用故障先验知识,提高发动机故障诊断的准确率.
2 部分代码 % diagnose.m% 柴油机故障诊断%% 清空工作空间clear,clcclose all%% 定义训练样本和测试样本% 故障1pro1 = [1.97,9.5332,1.534,16.7413,12.741,8.3052; 1.234,9.8209,1.531,18.3907,13.988,9.1336]';% 故障2pro2 = [0.7682,9.5489,1.497,14.7612,11.497,7.68; 0.7053,9.5317,1.508,14.3161,11.094,7.3552]';% 故障3pro3 = [0.8116,8.1302,1.482,14.3171,11.1105,7.4967; 0.816,9.0388,1.497,15.0079,11.6242,7.7604]';% 故障4pro4 = [1.4311,8.9071,1.521,15.746,12.0088,7.8909; 1.4136,8.6747,1.53,15.3114,11.6297,7.5984]';% 故障5pro5 = [1.167,8.3504,1.51,12.8119,9.8258,6.506; 1.3392,9.0865,1.493,15.0798,11.6764,7.8209]';% 正常运转normal = [1.1803,10.4502,1.513,20.0887,15.465,10.2193; 1.2016,12.4476,1.555,20.6162,15.755,10.1285]';% 训练样本trainx = [pro1, pro2, pro3, pro4, pro5, normal];% 训练样本的标签trlab = 1:6;trlab = repmat(trlab, 2, 1);trlab = trlab(:)';%% 样本的归一化,s为归一化设置[x0,s] = mapminmax(trainx);%% 显示结果strr = cell(1,6);for i=1:6 if res(i) == testlab(i) strr{i} = '正确'; else strr{i} = '错误'; endenddiagnose_ = {'第一缸喷油压力过大','第一缸喷油压力过小', '第一缸喷油器针阀磨损',.
㈠ 概念
① 物理CPU 实际Server中插槽上的CPU个数
物理cpu数量,可以数不重复的 physical id 有几个 ② 逻辑CPU Linux用户对 /proc/cpuinfo 这个文件肯定不陌生. 它是用来存储cpu硬件信息的
信息内容分别列出了processor 0 – n 的规格。这里需要注意,如果你认为n就是真实的cpu数的话, 就大错特错了
一般情况,我们认为一颗cpu可以有多核,加上intel的超线程技术(HT), 可以在逻辑上再分一倍数量的cpu core出来
逻辑CPU数量=物理cpu数量 x cpu cores 这个规格值 x 2(如果支持并开启ht)
备注一下:Linux下top查看的CPU也是逻辑CPU个数 ③ CPU核数 一块CPU上面能处理数据的芯片组的数量、比如现在的i5 760,是双核心四线程的CPU、而 i5 2250 是四核心四线程的CPU 一般来说,物理CPU个数×每颗核数就应该等于逻辑CPU的个数,如果不相等的话,则表示服务器的CPU支持超线程技术 ㈡ 查看CPU信息 vendor id 如果处理器为英特尔处理器,则字符串是 GenuineIntel。
processor 包括这一逻辑处理器的唯一标识符。
physical id 包括每个物理封装的唯一标识符。
core id 保存每个内核的唯一标识符。
siblings 列出了位于相同物理封装中的逻辑处理器的数量。
cpu cores 包含位于相同物理封装中的内核数量。
1. 拥有相同 physical id 的所有逻辑处理器共享同一个物理插座,每个 physical id 代表一个唯一的物理封装。
2. Siblings 表示位于这一物理封装上的逻辑处理器的数量,它们可能支持也可能不支持超线程(HT)技术。
1 简介 XPC-3399 LVDS显示,使用GM8775C MIPI DSI 转LVDS发送器实现,该收发器特性如下:
GM8775C介绍
1、产品概述
GM8775C 型 DSI 转双通道 LVDS 发送器产品主要实现将 MIPI DSI 转单/双通道 LVDS功能, MIPI 支持 1/2/3/4 通道可选,最大支持 4Gbps 速率。 LVDS 时钟频率最高 154MHz,最大支持视频格式为 FULL HD(1920 x 1200)。
该芯片主要应用于手持设备、双屏显示,大屏幕显示等应用需求。
2、产品特征
a) I/0 电源电压: 1.8V /3.3V;
b) core 电源电压: 1.8V;
c) 支持 MIPI® D-PHY 1.00.00 和 MIPI® DSI 1.02.00。
d) MIPI 支持 1/2/3/4 通道可选的传输方式, 最高速率 1Gbps/通道。
e) MIPI 接收 18bpp RGB666 、 24bpp RGB888 、 16bpp RGB565 的打包格式。
我们都知道,Java对象存储在堆(Heap)内存。那么一个Java对象到底包含什么呢?概括起来分为对象头、对象体和对齐字节。如下图所示:
对象的几个部分的作用:
1.对象头中的Mark Word(标记字)主要用来表示对象的线程锁状态,另外还可以用来配合GC、存放该对象的hashCode;
2.Klass Word是一个指向方法区中Class信息的指针,意味着该对象可随时知道自己是哪个Class的实例;
3.数组长度也是占用64位(8字节)的空间,这是可选的,只有当本对象是一个数组对象时才会有这个部分;
4.对象体是用于保存对象属性和值的主体部分,占用内存空间取决于对象的属性数量和类型;
5.对齐字是为了减少堆内存的碎片空间(不一定准确)。
了解了对象的总体结构,接下来深入地了解对象头的三个部分。
一、Mark Word(标记字)
以上是Java对象处于5种不同状态时,Mark Word中64个位的表现形式,上面每一行代表对象处于某种状态时的样子。其中各部分的含义如下:
lock:2位的锁状态标记位,由于希望用尽可能少的二进制位表示尽可能多的信息,所以设置了lock标记。该标记的值不同,整个Mark Word表示的含义不同。biased_lock和lock一起,表达的锁状态含义如下:
biased_lock:对象是否启用偏向锁标记,只占1个二进制位。为1时表示对象启用偏向锁,为0时表示对象没有偏向锁。lock和biased_lock共同表示对象处于什么锁状态。
age:4位的Java对象年龄。在GC中,如果对象在Survivor区复制一次,年龄增加1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15,这就是-XX:MaxTenuringThreshold选项最大值为15的原因。
identity_hashcode:31位的对象标识hashCode,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。当对象加锁后(偏向、轻量级、重量级),MarkWord的字节没有足够的空间保存hashCode,因此该值会移动到管程Monitor中。
thread:持有偏向锁的线程ID。
epoch:偏向锁的时间戳。
ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针。
ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针。
我们通常说的通过synchronized实现的同步锁,真实名称叫做重量级锁。但是重量级锁会造成线程排队(串行执行),且会使CPU在用户态和核心态之间频繁切换,所以代价高、效率低。为了提高效率,不会一开始就使用重量级锁,JVM在内部会根据需要,按如下步骤进行锁的升级:
**1.初期锁对象刚创建时,还没有任何线程来竞争,对象的Mark Word是下图的第一种情形,这偏向锁标识位是0,锁状态01,说明该对象处于无锁状态(无线程竞争它)。
2.当有一个线程来竞争锁时,先用偏向锁,表示锁对象偏爱这个线程,这个线程要执行这个锁关联的任何代码,不需要再做任何检查和切换,这种竞争不激烈的情况下,效率非常高。这时Mark Word会记录自己偏爱的线程的ID,把该线程当做自己的熟人。如下图第二种情形。
3.当有两个线程开始竞争这个锁对象,情况发生变化了,不再是偏向(独占)锁了,锁会升级为轻量级锁,两个线程公平竞争,哪个线程先占有锁对象并执行代码,锁对象的Mark Word就执行哪个线程的栈帧中的锁记录。如下图第三种情形。
4.如果竞争的这个锁对象的线程更多,导致了更多的切换和等待,JVM会把该锁对象的锁升级为重量级锁,这个就叫做同步锁,这个锁对象Mark Word再次发生变化,会指向一个监视器对象,这个监视器对象用集合的形式,来登记和管理排队的线程。如下图第四种情形。**
二、Klass Word(类指针)
这一部分用于存储对象的类型指针,该指针指向它的类元数据,JVM通过这个指针确定对象是哪个类的实例。该指针的位长度为JVM的一个字大小,即32位的JVM为32位,64位的JVM为64位。
如果应用的对象过多,使用64位的指针将浪费大量内存,统计而言,64位的JVM将会比32位的JVM多耗费50%的内存。为了节约内存可以使用选项+UseCompressedOops开启指针压缩,其中,oop即ordinary object pointer普通对象指针。开启该选项后,下列指针将压缩至32位:
每个Class的属性指针(即静态变量)
每个对象的属性指针(即对象变量)
普通对象数组的每个元素指针
当然,也不是所有的指针都会压缩,一些特殊类型的指针JVM不会优化,比如指向PermGen的Class对象指针(JDK8中指向元空间的Class对象指针)、本地变量、堆栈元素、入参、返回值和NULL指针等。
三、数组长度
如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,这部分数据的长度也随着JVM架构的不同而不同:32位的JVM上,长度为32位;64位JVM则为64位。64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位。
原文链接:[https://newworld.blog.csdn.net/article/details/86491792]
定义 响应式布局需要一个父级作为布局容器,来配合子级元素来实现变化效果。
原理就是在不同的屏幕下,通过媒体查询来改变这个布局容器的大小,在改变里面子元素的排列方式和大小,从 而实现不同屏幕下,看到的不同的布局和样式变化。
平时响应式尺寸的划分: 超小屏幕(手机,小于768px): 设置宽度为100%
小屏幕(平板,大于768px):设置宽度750px
中等屏幕(桌面显示器,大于等于992px):宽度设置为970px
大屏幕(桌面显示器,大于等于1200px):宽度设置为1170px
一般情况下这个布局容器的宽度是定死的。用媒体查询来改变档位的变化。
.container { height: 150px; background-color: pink; margin: 0 auto; } /* 1.超小屏幕 小于768px布局容器的宽度为100%*/ @media screen and (max-width:768px) { .container { width: 100%; } } /* 2.小屏幕 大于768px布局容器的宽度为100%*/ @media screen and (min-width:768px) { .container { width: 750px; } } /* 3.小屏幕 大于992px布局容器的宽度为100%*/ @media screen and (min-width:992px) { .container { width: 970px; } } /* 4.小屏幕 大于1200px布局容器的宽度为100%*/ @media screen and (min-width:1200px) { .
mit6.828的系统启动分为两个部分,分别是BIOS和Boot Loader的启动。主机通电时,首先启动BIOS,BIOS将带领CPU识别并加载主板上的重要硬件和集成元件,如硬盘、显卡、声卡以及各种接口,然后按照预设顺序读取存储器上操作系统的引导文件Boot Loader。在我们的实验中,Boot Loader程序会在编译成可执行文件后被放在模拟硬盘的第一个扇区。
1.BIOS启动流程 BIOS(Basic Input Output System)“基本输入输出系统”,它是一组固化到主板上一个ROM芯片上的程序,使用汇编语言编写。PC通电后,CPU马上就从地址0xFFFF0处开始执行指令,这个地址在系统BIOS的地址范围内,将BIOS程序加载到内存中执行,BIOS接下来的作用包括机器自检,对系统进行初始化,识别并加载主板上的重要硬件和集成元件,如硬盘、显卡、声卡以及各种接口,然后按照预设顺序读取存储器上操作系统的引导文件Boot Loader,储存Boot Loader的存储器可以是软盘、硬盘、CD-ROM甚至是网络输入,可以在BIOS的设置页面更改读取Boot Loader的搜索顺序。
那么在这其中就有一个问题,那就是,BIOS程序是固化到自己的ROM芯片中的,那CPU是如何在刚通电的情况下就能读取到BIOS程序并且运行的?再者,上段的说法也有些问题,“CPU马上就从地址0xFFFF0处开始执行指令,这个地址在系统BIOS的地址范围内”,那地址0xFFFF0指的是什么地址?是外加内存条RAM的内存地址还是储存BIOS程序的ROM地址?这又涉及到现代PC的内存地址是如何编排的。我也是查了很多资料才摸到一些门道,下面的说法糅合了我从网上搜索的资料和自己的整合以及猜测,不保证正确,仅为缕清自己的思路。
在计算机通电完成之后,CPU会自动将其CS寄存器设定为0xFFFF,IP寄存器设定为0x0000。关于CS寄存器和IP寄存器的介绍可以看文末的链接6,简单来说CS是代码段寄存器,IP是指令指针寄存器(相当于偏移地址),而CPU在访问内存的时候访问的是物理内存地址,而这个物理地址就是由CS和IP这两个寄存器中的值合成的(物理地址=段地址X16+偏移地址)。所以如果将CS寄存器设定为0xFFFF,IP寄存器设定为0x0000,那么这时的物理地址就=0xFFFF*16+0x0000=0xFFFF0,而在0xFFFF0存放的是什么呢?其实是一条无条件转移指令JMP,这个JMP会将程序跳转到BIOS真正的入口点。至于跳转到哪里,那么不同的BIOS会有不同的跳转地址。
上图为8086的内存架构,我们来详细讨论一下:早期基于16位英特尔8086处理器的个人电脑,只能寻址1MB的物理内存。因此,早期计算机的物理地址空间将从0x00000000开始,以0x000FFFFF结束。用户能够使用的内存地址只有标记为“低内存”的640KB区域(Low Memory),而之后从0x000A0000到0x00100000的384KB空间则被预留为硬件以及ROM的地址,用户不可用。具体可以看下图:
从上图可以看到,0xF0000到0x100000的地址范围便进入到了真正的BIOS的区域,而在这个区域中,BIOS又是以何种方式存在的呢?我们上面说到,计算机通电后,CPU会到0xFFFF0的位置执行,而0xFFFF0这个位置处在BIOS地址范围中,它只占0xFFFF0到0x100000短短的16B。这个地址处存放的只是一个跳转指令,它会将CPU跳转至真正的BIOS程序开始的位置,这个位置在不同的BIOS中是不同的。这里引用一个比较清晰的描述:
8086是16位的CPU,但是却有20根地址线。也就是说它可以寻址1MB内存空间。这段内存空间由RAM、ROM组成。ROM是随机只读存储器,里面的程序是在计算机出厂的时候直接烧录在里面的,完成一些主机自检等操作,并提供一些访问磁盘等基本输入输出服务,因而这段程序常被称为BIOS(Basic Input/Ouput Service)。由于不同的计算机厂商生产的计算机所带的外设不一样,因此,这段程序大小也限机型的不同而不一样,有可能A厂出产的计算机所带的这段程序的大小为1K,而B厂出产的这段程序的大小为2K。如果将这段程序放在0x0000处,那么用户写的程序就可能从0x0400处开始也可能从0x0800处开始,非常不统一。故而,将此段程序放在1M内存的顶部,那么用户写的程序就都可以从0x0000处开始了。
但将BIOS这段程序放在1M内存的顶部,如果这段程序大小为1K,那么应当从0xFFC00开始放。如果这段程序的大小为2K,那应当从0xFF800开始放,对于CPU而言,到底是应当从0xFFC00开始执行还是应当从0xFF800开始执行呢?为了解决这个问题,8086规定,CPU均从0xFFFF0处开始执行,而在0xFFFF0处,放一条无条件转移指令JMP。如果A厂的BIOS是从0xFFC00开始放的,那么这条转移指令就跳转到0xFFC00处开始执行。如果B厂的BIOS是从0xFF800开始放的,那么这条转移指令就跳转到0xFF800处开始执行,各个厂家可以根据自己所生产的BIOS程序的大小,来决定此转移指令具体跳转到的位置。
这里有一点需要清楚的是,通常认为,内存编址是连续的,不会出现空洞,其实完全不是这样。比如,假设BIOS的编址是从 0xF0000开始,而RAM,即通常讲的内存编址是从0x00000开始,那么,如果用户只安装了32K内存,那么内存的编址范围就是0x00000~0x07FFF,那么从0x08000至0xEFFFF处就没有安装内存,这就是一个内存空洞。
原文在这里
位数,地址总线以及寻址范围 这里还需要解释一下处理器的位数,地址总线以及寻址范围的关系:处理器的位数指的是处理器能够一次性处理的数据大小,比如早期的16位Intel 8086处理器,它能够一次性处理的最大数据为 2 16 = 65536 2^{16} = 65536 216=65536以内的数,而超过这个大小的数则需要分高低位来进行处理。还比如后来的32位Intel Pentium 4处理器,它能够一次性处理的最大数据为 2 32 2^{32} 232以内的数,而现在大多数处理器已经是64位的了,这意味这它们能处理的最大数更大,运行速度更快;而地址总线便决定了寻址范围,比如8086是20位地址总线,则它的最大寻址地址便是 2 20 B = 1 M B 2^{20}B = 1MB 220B=1MB,目前大多数个人电脑的地址总线都是32位的,这意味着它们的最大寻址范围达到了 2 32 B = 4 G B 2^{32}B = 4GB 232B=4GB,下表是这三者之间的关系:
Intel 8086Intel Pentium 4新兴64位处理器字长163264数据总线163264地址总线203232寻址范围1MB4GB4GB 需要清楚的是,不管是8、16、32、64CPU,RAM存储器的地址分配永远是以字节为单位,也就是给每一个字节的存储单元分配一个地址。如果MCU有32条地址线,则最多有 2 32 = 4 G 2^{32} = 4G 232=4G个地址编码,给存储器中的每个字节单元一个地址编码,则最多可以支持 2 32 B y t e = 4 G B 2^{32}Byte=4GB 232Byte=4GB。如果MCU的数据线是32位,则一次读写操作可以同时传送4个字节(一个字,32位机一个字是32位,也就是4个字节),也就是4个连续地址的存储器空间(对齐,4倍数开始的连续的4个地址)。
经过我调查发现,是直接把我的git干掉了,现在我出一个教程用homebrew安装git,希望给大家带来帮助
1、安装homebrew 我还是喜欢国内的镜像安装,官网的感觉我hold不住
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
选择前面三个都可以的
安装好了是这样的
brew的基本用法 // 查询: brew search 软件名 // 安装: brew install 软件名 // 卸载: brew uninstall 软件名 // 更新 Homebrew: brew update // 查看 Homebrew 配置信息: brew config 1、homebrew安装git brew install git
这样就可以了,很简单
在上一篇胖哥和大家共同体验了OAuth2登录流程,直观感受了OAuth2,本篇我们来共同分析一下OAuth2登录的流程,本次分析将严重依赖trace日志。
流程分析 ①访问被拒绝 /foo/hello发起请求后会经过一系列过滤器链的过滤触发访问被拒绝,核心的日志如下:
进入HTTP资源安全处理过滤器FilterSecurityInterceptor。发现本次/foo/hello请求是一个匿名请求。而实际上/foo/hello需要非匿名认证。访问决策投票器WebExpressionVoter做出了拒绝授权投票(Voted to deny authorization)。在基于肯定(AffirmativeBased)的访问策略下本次请求授权失败,抛出AccessDeniedException异常。异常响应过滤器ExceptionTranslationFilter对步骤⑤抛出的异常进行处理。 ②访问拒绝处理 ExceptionTranslationFilter接收到AccessDeniedException异常后会交给handleAccessDeniedException方法处理,该方法的逻辑如图所示:
我们所涉及的逻辑只会有到步骤④,其逻辑为:
上面的逻辑会跳转到登录入口(如果有两个provider的话):
③发起OAuth2登录请求 我们点击gitee选项会向我们的后端服务器发起/oauth2/authorization/gitee请求:
GET /oauth2/authorization/gitee HTTP/1.1 Host: localhost:8082 对应的日志为:
从日志上看请求被OAuth2AuthorizationRequestRedirectFilter拦截,重定向到了Gitee授权服务器登录页面。
重定向的请求为:
GET /oauth/authorize?response_type=code&client_id=40f6a4018837&scope=user_info&state=j_y78k1M4A&redirect_uri=http://localhost:8082/login/oauth2/code/gitee HTTP/1.1 Host: gitee.com 涉及的参数有:response_type、client_id、scope、state、redirect_uri,我们先不管这些参数是干嘛的,有个印象就好。
另外这个请求端点正好是配置中的authorization-uri配置项:
spring: security: oauth2: client: provider: gitee: authorization-uri: https://gitee.com/oauth/authorize OAuth2AuthorizationRequestRedirectFilter的作用就很清晰了:
拦截/oauth2/authorization/{registrationId},这里registrationId=gitee。组装registrationId对应provider的authorization-uri并发起重定向。 关于OAuth2AuthorizationRequestRedirectFilter的细节会在后面进行专门分析。
④用户授权 跳转到Gitee登录页面之后,后面的流程可以从浏览器记录中分析出来。
① 点击login页面的gitee按钮,客户端服务器302重定向到授权服务器发起授权请求。② 授权服务器同意授权后,又302 重定向到了配置中的redirect_uri并附带一个code和state参数。③ redirect_uri发起了请求。 安全起见,redirect_uri应当在授权服务器对应的客户端信息中注册,否则将被视为非法URI。
redirect_uri请求我简化成HTTP脚本以方便加深印象:
GET /login/oauth2/code/gitee?code=a6e4cac6a7e&state=cR4FABTHbHj4ILZ HTTP/1.1 Host: localhost:8082 Referer: https://gitee.com/login 以下是授权服务器(gitee)302重定向/login/oauth2/code/gitee后的日志:
大致步骤为:
redirect_uri请求被过滤器OAuth2LoginAuthenticationFilter拦截处理。向gitee发出/oauth/token请求,该端点对应配置文件中的token-uri。/oauth/token请求的响应被封装为OAuth2AccessTokenResponse对象实例。向gitee发出/v5/user请求,该端点对应配置文件中的user-info-uri。/v5/user请求的响应被封装为Map<String,Object>。根据某些策略对Session会话进行了处理(先了解即可)将OAuth2AuthenticationToken存储到SecurityContextHolder中。最后重定向到/foo/hello。 须知 这个流程并不是标准的OAuth2流程,OAuth2中并不涉及用户登录认证,该登录认证是建立在信任Gitee用户的基础上做的认证,这一点要明白。
关于授权码的详细规范请参阅4.1 Authorization Code Grant,如果遇到疑难杂症,请联系我。
redis的可用性 通过AKF理论构建集群 单机redis的会带来的问题 容量有限,内存有限单点故障,挂机后,导致服务不可用连接压力,I/O压力大,并发压力大 根据AKF理论解决上面的三个问题,分别从X,Y,Z三个方向解决,如下图: 上面通过AKF实现了一边多,实现了高可用,那么怎么保证主机和备机(从机)的数据一致性了? 数据强一致性, 弱一致性,最终一致性 但是主节点依然是单实例, 如果主节点挂了,服务还是不可用,我们应该怎么解决? 分区容忍
返回每行或者每列最大值索引号的函数argmax,类似的还有argsort等
import numpy as np data = np.sin(np.arange(20)).reshape(5,4) print(data) ind = data.argmax(axis=0)#求每列的最大值的索引号[2 0 3 1] inc = data.argmax()#返回的是所有元素最大值的标号14 print( ind) print( inc) data_max = data[ind, range(data.shape[1])]#print(data[[2,0,3,1],[0,1,2,3]]) print(data_max) # all(data_max == data.max(axis=0)) ''' [[ 0. 0.84147098 0.90929743 0.14112001] [-0.7568025 -0.95892427 -0.2794155 0.6569866 ] [ 0.98935825 0.41211849 -0.54402111 -0.99999021] [-0.53657292 0.42016704 0.99060736 0.65028784] [-0.28790332 -0.96139749 -0.75098725 0.14987721]] [2 0 3 1] 14 [0.98935825 0.84147098 0.99060736 0.6569866 ] ''' 如何扩充一个矩阵呢?用tile函数。
a = np.
安装docker #安装yum工具 yum install yum-utils -y #配置yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装docker yum install -y docker-ce-19.03.9 docker-ce-cli-19.03.9 containerd.io 安装成功后,修改docker国内镜像方法 #创建目录: mkdir -p /etc/docker #添加镜像 cat >> /etc/docker/daemon.json << EOF { "registry-mirrors": ["https://xuv622op.mirror.aliyuncs.com"] } EOF 启动docker #加载镜像加速站点: systemctl daemon-reload #启动docker并且设置开机启动 systemctl enable docker && systemctl start docker 查看是否启动
这代表没有启动成功,需要查询原因
这代表启动成功
docker下载redis镜像命令 #pull php-fpm镜像 docker pull w3media/php73-fpm #pull nginx镜像 docker pull nginx 等待下载镜像完后执行镜像查看命令,下图代表下载镜像成功。
docker images 运行php的docker镜像 #启动docker php容器 docker run -itd --name php --privileged=true -v /home/wwwroot:/home/wwwroot w3media/php73-fpm 解析命令
1.AFL模糊测试tiff AFL的安装已经在前文记录过American Fuzzy Lop(AFL)的安装与简单使用,不再赘述。这里主要记录一下在使用AFL时的可以注意的点。
最好选择由C或者C++编写的软件或是项目有可用的示例代码最好能自己编译插桩,Qemu模式比较慢最好有测试用例(语料库) 下面主要记录一下利用 AFL 模糊测试 tiff (一个图像处理软件) 的过程,有源码fuzz。
1.下载解压压缩包 $ wget https://download.osgeo.org/libtiff/tiff-4.3.0.tar.gz # 下载压缩包 $ tar -zxvf tiff-4.3.0.tar.gz $ cd tiff-4.3.0 2.编译插桩 将编译器指定为 afl-gcc,(c++程序需要将编译器指定为afl-g++) --disable-shared 指明构建静态库,查资料显示不加这个参数构建的好像是共享库,fuzz共享库可能需要编写一个简单的demo,所以简单起见,构建静态库。
$ ./configure CC="afl-gcc" CXX="afl-g++" --disable-shared # $ make # 然后再进行编译 $ make install 3.构建语料库,即准备测试用例作为种子文件 从网上找一些图片,AFL官方也给出了测试用例,我并没有采用官方的测试用例,因为后续还试用了一下AFL对测试用例的修剪功能,但官方的测试用例只有一个图片。
$ mkdir in # 该文件夹下存放种子用例 $ cd in $ wget https://dev-www.libreoffice.org/corpus/tiffuzzer_seed_corpus.zip $ unzip tiffuzzer_seed_corpus.zip 4.开始fuzz -i 指定输入用例目录, -o 指定结果输出的目录(会自动创建)。上一步解压出来的测试用例其实是放在 ./in/minimum-set-tif 文件夹下的,但是这里命令语句里写成 ./in 它也能读到测试用例。
$ cd .
provide和inject选项需要一起使用,它允许祖先组件向其所有子孙组件注入依赖,并在其上下游关系成立的时间里始终生效,不论组件层级有多深。
1. 我们简单回顾一下provide/inject的使用方式 如下:
var Provider = { provide: { foo: "bar" } } var Child = { inject: ["foo"], created() { console.log(this.foo); // "bar" } } 如果使用了ES5 Symbol作为key,则使用方式如下:
const s = Symbol(); var Provider = { provide() { return { [s]: "bar" } } } var Child = { inject: { s }, created() { console.log(this.foo); // "bar" } } 可以在data/props中访问注入的值:
var Provider = { provide: { foo: "
1.首先要有
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> 2.配置文件中要有nacos地址ip----name一定要有不然nacos服务列表就没有
nacos: discovery: ser3ver-addr: 192.168.188.129:8848 application: name: gateway #自定义这个就是nacos服务列表显示的名字---如果没有就不显示
在mabatis依赖导入maven项目的时候,出现了无法解析阿里云错误,错误显示如题所示,经过排查,找到maven本地仓库的mabatis目录,删除里面的文件,重新加载即可,原因是maven在下载jar包时,下载的jar包不全导致maven没有再次尝试下载,所以删除mabatis里面已有的jar包,重新下载,问题得到解决
This failure was cached in the local repository
and resolution is not reattempted until the update
简述 近日我们监测到 Vue.js 生态中的 vue-cli 包遭遇供应链投毒,而被投毒的 node-ipc 包在 npm 上每周下载量超百万,影响非常广泛。
被投毒的情况如下:
vue-cli是Vue.js 开发的标准工具,该工具被广泛应用于vue的快速开发其依赖的node-ipc是用于本地和远程进程间通信的一个js模块,也用于支持linux,windows,mac等系统中的socket通信。node-ipc包的作者近期在node-ipc的10.1.1-10.1.2版本添加了恶意JS,该JS会修改俄罗斯和白俄罗斯用户的所有文件为❤️,但不到24小时后又删除该恶意JS,添加会在用户桌面创建反战宣传标语的peacenotwar模块。vuejs的团队在发现node-ipc添加了peacenotwar模块后锁定了vue-cli依赖的node-ipc版本为9.2.1,研究人员随后又发现node-ipc的作者此前添加的恶意JS存在于node-ipc旧版本中。 (问题组件每周下载量截图)
事件时间线 3月7号 开发者RIAEvangelist在node-ipc包中添加名为ssl-geospec.js的恶意JS文件,将node-ipc的版本号更新为10.1.1
3月8号 删除ssl-geospec.js该文件,版本号更新为10.1.3
3月9号 开发者RIAEvangelist在node-ipc包中添加peacenotwar模块,该模块会在桌面静默添加反战宣传文件
3月15号 有开发者在论坛中反馈构建过程中发现被创建反战标语文件
3月15号 Vue-cli发布5.0.3版本,在新版本中锁定vue-cli依赖的node-ipc版本为9.2.1
研究人员分析发现node-ipc的作者不只添加了反战标语,还在旧版本10.1.1-10.1.2中添加了恶意JS文件删除俄罗斯和白俄罗斯用户文件
3月16号 vue的开发者sodatea针对此事件的回应如下:
node-ipc 9.2.2 增加peacenotwar模块,该模块会在未经用户同意的情况下写入WITH-LOVE-FROM-AMERICA.txt用户的Desktop和OneDrive文件夹。vue-cli已经发布了 4.5.16 和 5.0.3 来锁定依赖版本。受影响的用户:在2022-03-15T05:40:26.758Z和2022-03-15T13:17:57.076Z;期间创建的新项目或者更新了项目依赖的人。从俄罗斯和白俄罗斯 IP 删除文件的恶意代码不包含在 9.2.2 版本中 恶意代码分析 我们针对node-ipc包中使用的恶意js文件(node-ipc/ssl-geospec.js at 847047cf7f81ab08352038b2204f0e7633449580 · RIAEvangelist/node-ipc · GitHub)进行分析。
可以看到多处使用base64编码对行为意图进行隐藏
远程API地址解码为
https://api.ipgeolocation.io/ipgeo?apiKey=ae511e1627824a968aaaa758a5309154
使用https加载远程API
解密后的字符串,可以看出c为国家,e为俄罗斯,i为白俄罗斯,其他为文件路径
判断是否为俄罗斯或白俄罗斯,将结果注册为a
如果是则执行h函数
h函数递归爬取指定目录,将所传入的路径中的文件替换为base64编码的4p2k77iP,而其解码后为❤️
针对企业的一点建议 开源不等于可信,企业需要针对软件供应链建立动态管理机制,及时发现并响应其中可能的风险。 漏洞检测及修复 关于该漏洞的检测策略已在墨菲安全的所有工具产品中上线,您可以免费安装使用墨菲安全的JetBrains IDE插件、CLI客户端等对你的项目进行检测,并一键修复。
产品邀请注册: https://www.murphysec.com/register?invite_code=onkXXo开源仓库: https://github.com/murphysecurity 如果你觉得这个工具对你有用,可以star、提issues或者参与贡献,我们会挑选一个参与贡献的用户送出机械键盘一份。
参考链接 https://github.com/vuejs/vue-cli/issues/7054
https://github.com/RIAEvangelist/node-ipc/issues/233
百万周下载量node-ipc包以反战为名进行供应链投毒
作者:wochicheng 日期:2022年3月16日
最近在学习Mysql和表格,今天在创建Object数组时犯了一个很低级的错误分享一下,讲一下我自己的理解,放代码 :
public class sql{ //声明Object二维数组 private Object data[][]; //获取表格 public Object[][] getTable() { String querySql = "SELECT * FROM dormitory"; String querySql_count = "SELECT count(*)Id FROM dormitory"; try { ResultSet result= state.executeQuery(querySql_count); result.next(); int idCount = result.getInt("Id"); result= state.executeQuery(querySql); int i=0; /* 问题出现在这里这里先注释掉然后跑代码 * date = new Object[idCount][]; */ while(result.next()) { data[i] = new Object[2]; data[i][0] = result.getString("Id"); data[i][1] = result.getString("Dong"); i++; } result.close(); } catch (SQLException e) { e.
一、include_directories 该命令用于增加一个编译头文件。其基本语法是:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...]) 目录可以是绝对路径也可以是相对路径,相对路径的基准是CMAKE_CURRENT_SOURCE_DIR,默认情况下,包含目录是从已存在的包含目录列表后追加的,如果你想改变默认行为你可以设置CMAKE_INCLUDE_DIRECTORIES_BEFORE为ON,当然你可以直接通过参数AFTER和BEFORE控制是向后插入(Appending)还是向前插入(Prepending)。
注:相对路径是相对于当前进行的CMakeLists.txt所在目录,如当前CMakeLists下的include文件夹,可以写成:include_directories(include)或者带上符号include_directories(./include)。
二、第一个例子 有如下源文件需要编译,
operation.cpp:
#include "operation.h" int add(int a,int b) { return a+b; } operation.h
#ifndef _OPERTION_H #define _OPERTION_H int add(int a,int b); #endif main.cpp
#include <iostream> #include "operation.h" int main() { int a=1; int b=2; std::cout<<"你好啊,朋友"<<std::endl; std::cout<<"a+b = "<<add(a,b)<<std::endl; } 文件结构如下:
. ├── build ├── CMakeLists.txt ├── main.cpp ├── sayHello.cpp └── sayHello.h 1 directory, 4 files 我们采用Out of source编译,这种编译方式意思是在CMakeLists.txt所在目录外(Out)编译,这样做的好处在于生成的中间文件不会“污染”原有的工程结构。
首先我们增加所有参与编译的源文件main.cpp和operation.cpp:
当处理大量非结构化数据时,我们需要一个存储它的地方。我们选择存储数据的方式有很多,但我们今天将重点关注的是对象存储或基于对象的存储。当处理大量数据时,这是最佳选择,尤其是因为它并不昂贵,并且使管理数据变得更加容易。
如果您不熟悉它,对象存储是一种数据存储体系结构,它使您可以在可伸缩的对象结构中存储大量非结构化数据。它使存储的数据作为具有元数据和唯一标识符的对象,从而更易于访问该数据。现在,有许多平台提供对象存储功能。
因此,在本文中,我们将向您介绍四个有用的开放源代码对象存储平台,这些平台包含健壮的功能,并在2021年成为巨大的投资。
1. LakeFS > ScreenShot from LakeFS.
LakeFS是一个开源数据环境工具,可让您管理基于对象存储的数据湖。这些数据湖是存储库,您可以在其中转储所有结构化和非结构化数据类型。LakeFS还集成了许多工具,并支持Amazon S3和Google Cloud Storage。此外,它可与所有主要数据框架一起使用,例如Hive,Spark,Presto,AWS Athena等。
借助LakeFS,您可以扩展PB级数据,还可以通过其类似Git的分支和版本控制方法来添加数据,这使您可以在不破坏数据的情况下添加更新。这种类似于Git的方法还有助于轻松撤消数据更改,这使得处理数据变得更加轻松和安全。
您还可以通过查看LakeFS文档来了解其他特性。
2. Ceph > ScreenShot from Ceph.
Ceph是对象存储,块存储和文件系统开源平台。它提供了与Amazon的S3 REST API和OpenStack的API Swift完全兼容的对象存储功能。
Ceph的对象存储使您可以使用本地语言绑定和Ceph提供的其他技术轻松访问数据对象。如果您想改变公司的IT基础架构及其管理大量非结构化数据的能力,这是一个很好的解决方案。他们还拥有一些软件库,这些库使使用Java,C,C ++,Python,PHP和其他一些语言编写的软件能够使用本机API的功能访问Ceph的对象存储系统。
3. MinIO > ScreenShot from MinIO.
MinIO是一款开源云存储软件,可为大型数据基础架构提供高性能的分布式对象存储。它与Amazon S3 API兼容,在GitHub上有超过26K颗星,有680多位贡献者在使用它。
MinIO服务器存储所有类型的非结构化数据,例如照片,视频,日志文件等。它也可以在开源Apache V2许可下使用,并且许多最强大的大数据和机器学习应用程序都使用MinIO S3对象存储。您还可以在MinIO网站上查看许多其他功能。
4. OpenIO > ScreenShot from OpenIO.
OpenIO是用于管理和保护大量非结构化数据的开源对象存储解决方案。它使您可以构建和运行有弹性且受保护的大规模存储基础架构。
OpenIO与S3兼容,可以在任何硬件上进行部署或云托管。在添加新硬件时,它也不需要重新分配数据。您可以立即使用自己的额外容量。OpenIO还设计用于大型基础架构和大数据工作负载。除此之外,它还提供了直观的用户界面,以简化存储管理员的日常生活。结果,您的数据变得非常易于访问且易于管理。
结论 您可以使用许多开放源代码对象存储提供程序,这些提供程序提供了我们提到的许多功能中的某些功能。它们为您的所有存储需求提供了一个很好的解决方案,并且避免了高昂的财务成本。因此,选择具有所需功能的对象存储平台非常重要。
其中Synchronized涉及到重量级的锁,重量级的锁就和Monitor有关。
前置知识,JAVA的对象头组成
JAVA对象头 在32位虚拟机中
一个JAVA对象的对象头组成如下所示:
普通对象(总共8个字节,Mark Word占4个字节,Klass Word 占4个字节,Klass Word就是对对象信息的描述):
|-----------------------------------------------------------| | Object Header (64 bits) | |---------------------------------|-------------------------| | Mark Word (32 bits) | Klass Word (32 bits) | |---------------------------------|-------------------------| 数组对象(总共12个字节,Mark Word占4个字节,Klass Word 占4个字节,数组长度占4个字节):
|---------------------------------------------------------------------------------| | Object Header (96 bits) | |--------------------------------|-----------------------|------------------------| | Mark Word(32bits) | Klass Word(32bits) | array length(32bits) | |--------------------------------|-----------------------|------------------------| 在64位虚拟机中
一个JAVA对象的对象头组成如下所示:
普通对象(总共16个字节,Mark Word占8个字节,Klass Word 占8个字节):
|--------------------------------------------------------------| | Object Header (128 bits) | |------------------------------------|-------------------------| | Mark Word (64 bits) | Klass pointer (64 bits) | |------------------------------------|-------------------------| 数组对象(总共24个字节,Mark Word占8个字节,Klass Word 占8个字节,数组长度占8个字节):
1.打开终端:
2.输入命令:【/usr/libexec/java_home -V】,查看默认的jdk下载地址(绿色下划线的就是jdk默认路径)(注意⚠️:命令行终端是区分大小写的【-v 是不对的,必须是大写 -V】)
3.如果是第一次配置环境变量,使用命令:【touch .bash_profile】创建一个.bash_profile隐藏配置文件(如果存在已有配置文件就输入:【open -e .bash_profile】)打开如下
4.输入以下命令:(注意⚠️:红色字体是第2步查出来自己jdk的路径)
【
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home
PATH=$JAVA_HOME/bin:$PATH:.
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
export JAVA_HOME
export PATH
export CLASSPATH
】 5.关闭终端,终端会自动保存
6.输入命令【source .bash_profile】使配置生效 7.输入 【echo $JAVA_HOME】 显示刚才配置的路径
二叉树 树的定义基本术语性质二叉树的类型1、完全二叉树:2、满二叉树: 二叉树的遍历 树的定义 树(tree)是一种抽象数据类型(ADT)或是视作这个数据类型的数据结构,用来模拟拥有树状结构的数据集合
它是由n(n>=1)个有限的结点组成的一个层次关系的集合。
把它叫做树是因为是看起来像树,根在上,而叶朝下的,它具有一下的特点:
1、每个节点都有零个或者多个子节点
2、没有父节点的节点叫做根节点
3、除了根节点之外,每个字节点可以分为多个不想交的子树
4、除了根节点之外,每个节点只有一个父节点
图一
在图1,该树一共有13个节点,其中A是根,其余节点分成3个互不相交的子集:
T1={B,E,F,K,L},T2={C,G},T3={D,H,I,J,M};T1,T2和T3都是根A的子树,且本身也是一棵树。
例如T1,其根为B,其余节点分为两个互不相交的子集;T11={E,K,L},T12={F}。
T11和T12都是B的子树。而在T11中E是根,{K}和{L}是E的两棵互不相交的子树,其本身又是只有一个根节点的树。
上述观察实际上给了我们一种严格的定义方法:
1、树是元素的集合
2、该集合可以为空,这时候树中没有元素,我们成它为空树(empty tree)
3、如果该集合不为空,那么该集合有一个根节点,以及0个或者多个子树,根节点和它的子节点用一条边(edge)连接
上面几点使用的递归定义的树,也就是在定义树的过程中使用了树(子树)本身,由于树的递归特征,许多树的相关操作也可以方便的实现递归实现
基本术语 1、节点的度:一个节点所含有的子树
2、树的度:一棵树的所有节点中最大的度
3、叶节点或终端节点:度为零的节点
4、父亲节点或者父节点:若一个节点含有子节点,就称这个节点为这些子节点的父节点(自身的上一级)
5、孩子节点或子节点:父亲节点的子节点(自身的下一级)
6、兄弟节点:同一个父节点
7、节点的层次:从根开始定义起,根为第一层,根的子节点为第二层,以此类推
8、树的高度或深度:树中节点的最大层次
9、堂兄弟节点:父节点在同一层次的节点
10、节点的祖先:从根节点到该节点分支上的所有节点
11、子孙:自身的所有下一级节点
12、森林:由m(m>=0)棵互不相交的树的集合
性质 1、在二叉树的第i层上至多有2的(k-1) 个节点(i>0)(也就是2的层数-1次方)
2、深度(高度)为k的二叉树至多有2的k次方 -1 个节点 (k >0)(从第一层累加,加到k层)
3、对于任意一棵二叉树,如果其叶节点数位N0,而度数位2的结点总数为N2,则N0=N2+1
4、具有n个结点的完全二叉树的深度必为log2(n+1)
5、
二叉树的类型 1、完全二叉树: 2、满二叉树: ## 3、平衡二叉树
平衡二叉树又被称为AVL树(这里区别于AVL算法),他是一棵二叉排序树,且具有以下性质:他是一棵空树或他的左右两个的子树的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
二叉树的遍历 所谓二叉树的遍历,指的是如何按某种路径巡防树中的每次结点,使得每个结点均被访问一次,而且仅被访问一次。
介绍完了二叉树的定义及基本性质,接下来,我们需要了解二叉树的遍历。所谓二叉树的遍历,指的是如何按某种搜索路径巡防树中的每个结点,使得每个结点均被访问一次,而且仅被访问一次。对于二叉树,常见的遍历方法有:先序遍历,中序遍历,后序遍历,层序遍历。这些遍历方法一般使用递归算法实现。
先序遍历的操作定义为:若二叉树为空,为空操作;否则(1)访问根节点;(2)先序遍历左子树;(3)先序遍历右子树。
中序遍历的操作定义为:若二叉树为空,为空操作;否则(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。
后序遍历的操作定义为:若二叉树为空,为空操作;否则(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。
层序遍历的操作定义为:若二叉树为空,为空操作;否则从上到下、从左到右按层次进行访问。
如对于下图3
其先序遍历、中序遍历、后序遍历、层序遍历的结果为:
先序遍历为: 18 7 3 4 11 5 1 3 6 2 4 中序遍历为: 3 7 4 18 1 5 3 11 2 6 4 后序遍历为: 3 4 7 1 3 5 2 4 6 11 18 层序遍历为: [[18], [7, 11], [3, 4, 5, 6], [1, 3, 2, 4]]
一、CPU飙高产生的原因 1、CAS修改值失败,没有控制自旋次数,导致一直自旋不断重试,非常消耗cpu资源
2、云服务器被黑客攻击,植入了挖矿程序:端口不能够被外网访问
3、程序死循环:控制循环次数
4、服务器被DDOS攻击:限流、ip黑名单、图形验证码
二、模拟生产环境cpu飙高 (1)模拟飙高的代码,该代码不需要包名
public class Test { public static void main(String[] args) { new Thread(()->{ while (true) System.out.println("测试测试"); },"TestThread").start(); } } (2)上传Test.java文件到Linux服务器下,/usr/local
(3)编译Test.java并运行
执行命令:javac Test.java 运行Test.class文件
执行命令:java -cp . Test
三、使用Arthas工具排查 下载arthas-boot.jar,然后用java -jar的方式启动:
执行命令:curl -O https://arthas.aliyun.com/arthas-boot.jar
启动:java -jar arthas-boot.jar
执行命令:dashboard
从图中能很清楚的看到TestThread线程 cpu占比80.22%
也可以用命令:thread -n 3
根据查询出来的线程名称去定位实际业务代码
点击 Arthas命令 查看其他命令。
以上就是Linux环境下排查CPU飙高的方法。
OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performance or cause incorrect results. The best thing to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding static linking of the OpenMP runtime in any library.
org.apache.shiro.session.ExpiredSessionException: Session with id异常排查 系统运行过程中报出异常 Caused by: org.apache.shiro.session.ExpiredSessionException: Session with id [aa21ba8b-7f3a-4236-a2f8-3b440524f55e] has expired. Last access time: 3/14/22 2:55 PM. Current time: 3/14/22 3:26 PM. Session timeout is set to 1800 seconds (30 minutes) at org.apache.shiro.session.mgt.SimpleSession.validate(SimpleSession.java:292) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doValidate(AbstractValidatingSessionManager.java:186) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.validate(AbstractValidatingSessionManager.java:143) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:120) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupRequiredSession(AbstractNativeSessionManager.java:152) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getAttribute(AbstractNativeSessionManager.java:249) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.mgt.DelegatingSession.getAttribute(DelegatingSession.java:141) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.subject.support.DelegatingSubject.getRunAsPrincipalsStack(DelegatingSubject.java:473) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.subject.support.DelegatingSubject.getPrincipals(DelegatingSubject.java:157) ~[shiro-core-1.6.0.jar:1.6.0] at org.apache.shiro.subject.support.DelegatingSubject.getPrincipal(DelegatingSubject.java:153) ~[shiro-core-1.
方法1. 重启Windows资源管理器 一般Win10开始菜单点击无反应都是因为Windows资源管理器所引起的,我们只需重新启动Windows资源管理器即可解决开始菜单点击没反应这一问题。
1. 按键盘上的“Ctrl + Shift + Esc”键,打开任务管理器。
2. 在“进程”选项卡中,找到“Windows资源管理器”,并单击右下角的“重新启动”按钮。
等待重启完成后,您可以再次点击Win10开始菜单查看问题是否解决,若没有您可以继续尝试以下的方法。
方法2. 重新安装开始菜单 若是Win10开始菜单本身的问题,我们可以使用PowerShell重新安装开始菜单。具体操作步骤如下:
1. 按“Windows + X”键,然后单击“Windows PowerShell(管理员)”,再单击“是”。
2. 在弹出的窗口中,输入以下命令并按下回车键。
命令:“Get-AppxPackage -AllUsers| Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml”}”
说明:该命令会将Win10内置的默认应用进行重新安装。如果有错误提示,不必理会,等待执行完成后,再重启电脑即可。
其他方法请参考:
https://www.disktool.cn/content-center/win10-start-menu-click-invalid-2111.html
一、什么是软考? 软考是计算机技术与软件专业技术资格(水平)考试的简称,它是由国家人力资源和社会保障部、工业和信息化部领导下的国家级考试,并且它既是职业资格考试,又是职称资格考试,还是水平考试。
二、软考专业资格考试 计算机软件资格考试设置了27个专业资格,涵盖5个专业领域, 3个级别层次(初级、中级、高级)。
三、软考考试时间 软考一年有两次考试时间,分别是5月底和11月初,但有部分考试时间只有一次,下图是我总结的只有一次考试时间的软考科目,此外其他的科目都是有两次考试机会的。如果有报图中科目的小伙伴,要注意考试时间哦!
四、软考的作用 软考证书的含金量很高,其主要有以下5个作用:
1.个税抵扣
这是最直接的作用,考完后在个人所得税APP就可直接申请了。按相关规定,拿到软考证书的那一年,可以扣除3600元内的个税。
2.评职称
在国企和体制内工作可评职称,中级评中级职称,高级就可以评副高级职称。例如:高项(信息系统项目管理师)考出来则直接可以评副高职称。
3.积分落户
根据城市而定,有些城市落户是需要满足多少积分的,一般只在一线城市有用。而软考过了则可以加分。以上海为例,中级证书可以加100分,而高级职称则可以加140分。
4.公司招投标
现在公司想要有项目,就离不开招投标,例如此项目需满足高级工程师3名、中级工程师5名类似,职称人员数量会影响投标结果,这里也涉及到一个灰色地带,则是挂K,有些公司对于技术人才不满足条件,则会开出高价收资质,但这项目前也算wf的,建议不要轻易尝试,挂给自己所在公司,否则项目出问题要负责任的。所以很多公司会鼓励自己员工参加相关考证考试,有利于公司招投标,公司也会个个人一定的现金奖励的。
5.个人能力的提升
不管考证是因为什么原因,在备考学习的过程中自己会学到很多专业知识,对自己的能力有一定的提升,可以提高在个人的核心竞争力。
ICLR 2022的spotlight。
原论文地址:https://arxiv.org/abs/2202.06709
你懂的VIT吗?
论文的核心是在证明VIT的优化曲面对比ResNet要好很多。
Abstract 1、注意力机制有助于提升泛化能力,因为会使损失函数平滑化。
2、VIT的进步是因为数据特异度(specificity)高,不是因为长距离依赖性。(当前很多人认为VIT work的原因是因为VIT的距离比较长,不像CNN只有一个短局部的信息建模)
3、VIT会受非突的损失函数的影响。(受到非突的损失函数影响很多模型都有,但VIT受到的影响比较大)
4、大数据集和损失函数平滑技术可以缓解非突损失函数的问题。(VIT适用大数据集)
5、MSA和CNN会有不同的表现,MSA更像是低通滤波器,所以MSA和CNN可以互补。
6、多阶段神经网络的结尾可以放MSA,提出了AlterNet。
Introduction There is limited understanding of multi-head self-attentions (MSAs), although they are now ubiquitous in computer vision. The most widely accepted explanation for the success of MSAs is their weak inductive bias and capture of long-range dependencies (See, e.g., (Dosovitskiy et al., 2021; Naseer et al., 2021; Tuli et al., 2021; Yu et al., 2021a; Mao et al.