C++第一部分介绍基础:c++:-0,本节介绍C++中函数使用。
函数 函数调用 调用函数需要先声明函数原型 嵌套调用: 参数传递 在函数被调用时才分配形参的存储单元 实参可以是常量、变量或表达式 实参类型必须与形参相符 值传递是传递参数值,即单向传递 引用传递可以实现双向传递 常引用作参数可以保障实参数据的安全 传引用比传对象计算消耗小
可变参数 C++中提供了两种方法:
如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型; 如果实参的类型不同,我们可以编写可变参数的模板。 initializer_list initializer_list是一种标准库类型,用于表示某种特定类型的值的数组,该类型定义在同名的头文件中 使用:
使用模板时,我们需要在模板名字后面跟一对尖括号,括号内给出类型参数。例如: initializer_list ls; // initializer_list的元素类型是string initializer_list li; // initializer_list的元素类型是int initializer_list比较特殊的一点是,其对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。 含有initializer_list形参的函数也可以同时拥有其他形参 应用:
在编写代码输出程序产生的错误信息时,最好统一用一个函数实现该功能,使得对所有错误的处理能够整齐划一。然而错误信息的种类不同,调用错误信息输出函数时传递的参数也会各不相同。 使用initializer_list编写一个错误信息输出函数,使其可以作用于可变数量的形参。 内联函数 作用:编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。
声明时使用关键字: inline 注意:
内联函数体内不能有循环语句和switch语句; 内联函数的定义必须出现在内联函数第一次被调用之前; 对内联函数不能进行异常接口声明。 常量表达式 C++-11中新增,用于初始化常量表达式。 (1)constexpr函数语法规定
constexpr修饰的函数在其所有参数都是constexpr时,一定返回constexpr; 函数体中必须有且仅有一条return语句。 (2)constexpr函数举例
constexpr int get_size() { return 20; } constexpr int foo = get_size(); //正确:foo是一个常量表达式 函数默认参数值 (1)默认参数值的说明次序
最近在学习华为的数据库,在学习如何用python来连接数据的时候,一直连接失败,然后官方文档也没有具体说明如何用python来连接,然后被这个东西困扰了我好几天。在网上找了很多资料,终于成功用python连接上了OpenGauss数据库。
在OpenGauss的官方文档中,找到了用于连接OpenGauss数据库的库,Psycopg。(官方文档链接)
首先得安装Psycopg2,直接在命令输入以下命令
pip install psycopg2 切换omm用户 su - omm 添加放行ip 我们需要修改pg_hba.conf文件,具体路径每个人可能不一样。
我的路径在/gaussdb/data/ecs-8eb2里面,然后我们修改文件pg_hba.conf
vim /gaussdb/data/ecs-8eb2/pg_hba.conf 根据上图修改文件增加
host all all 0.0.0.0/0 sha256 修改加密方式 接下来修改文件postgresql.conf
vim /gaussdb/data/ecs-8eb2/postgresql.conf 将password_encryption_type取消注释,并修改为零
我们也可看以下注释
Password storage type, 0 is md5 for PG, 1 is sha256 + md5, 2 is sha256 only 0的时候为md5加密,1为sha256+md5混合加密,2为sha256加密
重启openGauss服务 我们下面一次执行以下指令
gs_ctl reload ,datadir is -D /gaussdb/data/ecs-8eb2 gs_om -t stop gs_om -t start 执行完成后,我们创建一个用户。用户名自行修改,注意不能用omm用户远程登录。
CREATE USER jacky PASSWORD 'Bigdata@123'; 接下来我们要给用户赋予权限(不赋予权限在操作时可能会报错)
简单的说一下伪内存共享是什么: cpu读取数据的顺序:cpu->寄存器->1级缓存->2级缓存->3级缓存(3级缓存开始是CPU共享的)->主内存->硬盘,读取数据不是一个对象或者一个字节为单位读取的,而已一缓存行为单位,CPU 不同缓存行的大小也不同,一般为32-256个字节,最常见的缓存行大小是64个字节。如果一个缓存行存了多个对象,两个cpu 分别都加载了其中的一个对象( 比如cpu1 加载 了A,cpu2 加载了B ),然后如果cpu1频繁的修改A,那么cpu2即便只是读取B对象,会因为cpu1修改了A对象,使A对象所在的缓存行失效,cpu2就需要频繁的从3级缓存中加载失效的缓存行。上面描述的不是必须竞争修改,cpu1,cpu2 没有同时修改同一份数据,这种不以必要但是又真是存在的缓存行失效问题叫做伪内存共享。
伪内存共享问题解决办法: 填充缓存行,使整个Java对象占满整个缓存行。不同Java版本不一样,比如开启指针压缩的情况下,对象头标记8字节,对象类型指针4字节就是12 字节,如果我们只有一个long 类型的字段(8字节),然后Java对象是8字节对齐的,我们填充5个long 类型(40),这时候就是60字节,然后由padding 区域填满剩下的4字节。这样就占了整个缓存行。
JDK7中填充空的属性部分版本会失效,这时候可以通过在父类中添加属性来填充。
JDK8以后官方给出解决缓存行填充的注解@Contended,来使对象填充缓存行。但是默认情况加了也无效,需要 指定jvm 参数,使它生效需要同时开启 JVM 参数:-XX:-RestrictContended=false(这个参数的意思禁用Java类库以外的缓存行填充,这个参数默认是true),如果想Java自带类库缓存行填充都禁用 –XX: EnableContented=false就可以(默认是true)。
另外在说说,缓存行填充不应该随意使用,除非你确定你需要它,测试,普通Java对象填充和不填充效果基本没区别(没区别是应为出现的概率比较小,并不是真的没区别),但是被volatile修饰的对象效率 差10倍,所以volatile的对象可能更加需要填充。volatile关键字也不应该乱用,用了它会大大的降低效率,除非你真的需要它带来的内存可见性和禁用指令重排序。
目录成员内部类静态内部类局部内部类匿名内部类
成员内部类 public class InnerTest { class Inner{ } } public class Main { public static void main(String[] args) { InnerTest innerTest = new InnerTest(); InnerTest.Inner inner = innerTest.new Inner(); } } 静态内部类 public class InnerTest { static class Inner{ } } public class Main { public static void main(String[] args) { InnerTest.Inner inner = new InnerTest.Inner(); } } 局部内部类 //和局部变量一样 public class Main { public static void main(String[] args) { class Inner{ public void a() { System.
java的Base64加密与解密 import java.util.Base64; public class Hello { public static void main(String[] args){ String name = 哈喽啊; //base64,加密 Base64.Encoder encoder = Base64.getEncoder(); String res = encoder.encodeToString(name.getBytes()); System.out.println(res); // 5ZOI5Za95ZWK // base64,解密 Base64.Decoder decoder = Base64.getDecoder(); byte[] origin = decoder.decode(res); String data = new String(origin); System.out.println(data); } } python的Base64加密与解密: import base64 name = 哈喽啊 #加密 res = base64.b64encode(name.encode('utf-8')) print(res) #将res以utf-8方式解密成字节的形式 data = base64.b64decode(res.decode('utf-8')) #再将data以utf-8的方式解码成字符串的数据 origin = data.decode('utf-8') print(origin)
一、前言
本次博客是主要针对在java学习第二阶段中的PTA作业的总结性博客,第二阶段的作业的难度与第一次阶段相比有所提高,对java的知识点的考察主要集中在正则表达式的运用、类的继承、多态,以及数据结构中的一系列知识。
二、题目分析
1、期中考试题
这次考试我是在最后几分钟内才做完了题目,说实话,我最大的缺点就是没有认真审题,导致我浪费了许多时间,继而导致我最后的代码有很多瑕疵。在display类中我应该在第二题中就改为所有的输出,而我还在主函数里输出,导致虽然测试结果与答案一致,但是一直只有16分,直到我在做最后一题时才幡然醒悟,将display类给改正。所有我下次做题一定要认真仔细审题。还有我在第三题上还有许多瑕疵,我在考后对Main方法进行了一些修改,代码如下:
public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); GeometryObject geometryObject =new GeometryObject(); int choice = in.nextInt(); while(choice != 0) { switch(choice) { case 1: double x1=in.nextDouble(); double y1=in.nextDouble(); Point point=new Point(x1,y1); geometryObject.add(point); break; case 2: double x2=in.nextDouble(); double y2=in.nextDouble(); double x3=in.nextDouble(); double y3=in.nextDouble(); String color1=in.next(); Point point1=new Point(x2,y2); Point point2=new Point(x3,y3); Line line=new Line(point1,point2,color1); geometryObject.add(line); break; case 3: String color2=in.next(); Plane plane=new Plane(color2); geometryObject.
MySQL架构 1_逻辑架构 1.1.连接层 系统(客户端)访问MySQL服务器前,做的第一件事就是建立TCP连接。 经过三次握手建立连接成功后,必须要分配给一个线程去执行后序流程。 每一个连接`从线程池中获取线程, 省去了创建和销毁线程的开销。
MySQL服务器对TCP传输过来的账号密码做身份认证、权限获取。
用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行
用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依 赖于此时读到的权限
1.2.服务层 1.SQL Interface 接收用户的SQL命令,并且返回用户需要查询的结果。
MySQL支持DDL(数据定义语言)、DML(数据操作语言)、存储过程、视图、触发器、自定义函数等
多种SQL语言接口。
2.Parser 在解析器中对SQL语句进行语法分析、语义分析。
在SQL命令传递到解析器的时候会被解析器验证和解析
将SQL语句分解成数据结构--语法树,并根据数据字典丰富查询语法树,后续步骤SQL语句的传递
和处理就是基于这个结构的。如果在分解构成中遇到错误,那么就说明这个SQL语句是不合理的。
会验证该客户端是否具有执行该查询的权限。
3.Optimizer SQL语句在语法解析之后、查询之前会使用查询优化器确定SQL语句的执行路径,生成一个执行计划。
这个执行计划表明应该使用哪些索引进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,
最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将查询结果返回给用户。
它使用“ 选取-投影-连接 ”策略进行查询。
4.Caches&Buffers MySQL内部维持着一些Cache和Buffer,比如Query Cache用来缓存一条SELECT语句的执行结 果,如果能够在其中找到对应的查询结果,那么就不必再进行查询解析、优化和执行的整个过 程了,直接将结果反馈给客户端。
这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。 这个查询缓存可以在不同客户端之间共享。
注意:从MySQL 5.7.20开始,不推荐使用查询缓存,并在MySQL 8.0中删除。
1.3.引擎层 真正的负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作
服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要
进行选取。
2_SQL执行流程 2.1.执行流程 SQL 语句在 MySQL 中的流程是: SQL语句→查询缓存→解析器→优化器→执行器
1.查询缓存 Server如果在查询缓存中发现了这条SQL语句,就会直接将结果返回给客户端;如果没有,就进入到解析器阶段。
def add(a, b): return a + b partial function application
def add1(num): return add(1, num)print(add1:, add1(1)) # add1: 2from functools import partialadd2 = partial(add, 1)print(add2:, add2(1)) # add2: 2 currying
def curried_add(a): def inner(b): return add(a, b) return innerprint(curried_add(1)(2))from toolz import curryadd2 = curry(add)print(add2(1, 2)) map
map(f, iter)[f(el) for el in seq] filter
filter(p, seq)[el for el in seq if p(el)] reduce
from functools import reducefor el in seq: result = f(result, el) function composition
Java Script百炼成仙笔记 一.基础部分 1.1直接量 数值、逻辑值、字符串、null、undefined对象和函数都是直接量。字符串需要有双引号或单引号包裹,数字不需要。
Hello World;'Hello World' 但是数据产生后不能直接保存。
1.2变量的声明 如要保存数据,需用var定义一个变量再将它指向直接量。(var是定义变量的工具)
var a;a=Hello World 也可合并为
var a=Hello World 1.3数据类型 在JavaScript中数据分为两大类别,分别是原生数据类型也叫原始值(primitive type)和对象数据类型也叫引用值(object type)。 原生数据类型包括:数字、字符串、布尔值(逻辑值)和特殊类型null、undefined。 布尔值只有两个类型,true(翻译为事实)或false(翻译为虚假),他们也叫逻辑值。 null和undefined表示直接量的空缺,如果直接量指向了他们都代表false的含义,也表示没有或空。null表示没有值,undefined更高级,表示某个变量未定义。
1.4对象数据类型 对象数据类型是一种复合数据类型(也叫对象),可以把多个数据放在一起,在其中的数据每个都可以看做是一个单元,都有自己的名字和值。
var container={} 这是对象数据类型最常用的一种创建方式(container翻译为容器)
var container={ caoyao:草药} 在这个对象数据中caoyao叫做键,草药叫做值,写在一起是一种键值对的形式。 键值对中间用冒号连接。 如需添加多个键值对只需要用(,)连接。
var container={ caoyao:解毒草, feijian:乌木剑} 也可在外面对变量进行操作,写作:
var container={}container.caoyao=解毒草;container.feijian=乌木剑; 其中(.)是对象访问属性的意思,因为caoyao是container的属性,所以container才可以用(.)。对象中包含若干数据,每个数据都是一个键值对,这些数据也叫对象的属性。键值对中的键就是属性名称,值就是属性值。 上例中,对象包含的属性caoyao是一组数据也是对象中的属性,这组数据是一个键值对,caoyao是这个属性的名字,解毒草是这个属性的实际值也就是值。(对象⊆属性=这组数据=这组键值对,仅在此例中)
var container={}container.caoyao=解毒草;container.feijian=乌木剑;console.log(container.danyao);//注意:丹药这个属性是不存在的 如果使用工具访问一个根本不存在的属性,因为danyao这个属性是不存在于container对象中的,因此它是未定义的,得到的结果是undefined。
1.5对象的取值 上单元例中用属性的名字可以直接调用属性值。
container.caoyao; 如果事先不知道调用的属性叫什么名字,如何定义一个变量。
var container={ caoyao:解毒草, feijian:乌木剑}var prop=caoyao; 如直接prop只能显示undefined 这时需要:
var container={ caoyao:解毒草, feijian:乌木剑}var prop=caoyao;console.log(container.[prop]) 或者
console.log(container.[caoyao]) 来得到结果即解毒草
对象中不仅可以用(.)来访问它的一个属性,也可以用([])。如果使用中括号 里面就允许在写一个变量,或是字符串。也就是在事先属性的名称为止,或者调用的属性是动态变化的,就不能用点好了。使用中括号可以最大程度地提升对象调用属性的灵活度。
class Dog{ //利用封装的方法,定义 size 变量,使得 size 变量的值始终大于 10 /*编写 bark方法,size值 > 60的时候输出“Woof!”;size值 > 40的时候输出“Ruff!”; 其他取值时输出“Yip!”。*/ } public class DogTestDrive{ public static void main(String[] args){ //创建至少三个 Dog 对象 //为每个对象设定或输入 size 的大小 //输出每个 Dog 对象的 size 大小 //调用 bark 方法输出不同 size 大小的叫声 } import java.util.*; public class Main{ public static void main(String[] args) { Dog a=new Dog(); Dog b=new Dog(); Dog c=new Dog(); Scanner scanner=new Scanner(System.in); a.setSize(scanner.nextInt()); a.bark(); b.