关于c:喝饮料问题饮料价格1元瓶两瓶饮料空瓶可以重新兑换一瓶饮料问20元可以喝多少瓶饮料

办法1: int main()//办法一{ int money = 0;//手上的钱,即用钱买回来的汽水数量 int total = 0;//买的+兑的 int empty = 0;//手里的空瓶 scanf_s("%d", &money); int sum = totalsum(money); printf("sum=%d\n", sum); total = money;//用钱买回来的汽水数量 empty = money;//喝完用钱买的汽水后手里的空瓶数量 while (empty>=2)//只有空瓶不低于两瓶就能够换汽水 { total += empty / 2; empty = empty / 2 + empty % 2;//空瓶的数量为换回来的空瓶+手里余下的空瓶 } printf("total=%d\n", total);}办法2: 办法2,因为两个空瓶换一瓶饮料,一瓶饮料1块钱,相当于1个空瓶等于0.5元,20块钱能够换40个空瓶,相当于喝了40瓶汽水,但因为最初手里留了一个空瓶,所以只能换来39个空瓶,即喝了39瓶汽水int totalsum(int money){ int sum = 0; if (money== 0)//手里没钱就不能喝饮料 { return 0; } else { sum = money * 2 - 1; return sum; } //}

July 29, 2021 · 1 min · jiezi

关于c:c指针面试题相关问题1

1. 只有在sizeof(arr),&arr这两种状况下,arr示意的整个数组,而sizeof()计算传入元素类型的大小2. strlen函数的形参为一个常量指针,即const char*str,这示意传入strlen中的应该是某个地址,且strlen在计算长度时3. char*p=“abcdef”,实际上p寄存的是a的地址,即字符串首元素的地址 注:p+0x1是构造体指针+1,跳过一个构造体,所以地址+20,又因为是16进制,所以,地址为0x00100014** (unsigned long)p+0x1,首先把指针p强转为无符号整型,所以P+0x1就相当于是一个无符号整数+1 (unsigned int*)p+0x1先把p强转成无符号整型指针,所以p+0x1相当于跳过一个整型8.注:零碎采纳小端存储模式,&a+1跳过了整个数组,如图,指针ptr指向数组开端前面的空间,再再将其强转成int的指阵类型,所以ptr[-1]等价于*(ptr-1)即向前跳了一个整型,再解援用(int)a+1将数组首元素地址转化为一个整型,假如数组首元素的地址为0x00 00 00 05,强转为整型后+1相当于5+1=6,再把6强转成地址,即0x00 00 00 06即向前跳过一个字节,再解援用*ptr为00 00 00 02,计算机打印时按高地址到低地址打印,所以%x为0x 2 00 00 00 9.注:逗号表达式,在(x,y)示意的最初一个y 10.注:p的类型为int(*)[4] a的类型为int(*)[5],&p[4][2] 等价于*(*(p+4)+2),即为第19个存储空间,同理*(*(a+4)+2)为第23个存储空间,而地址-地址=元素个数,所以,&p[4][2]-&a[4][2]=-4,当-4以地址的模式打印的时候,间接打印其补码11111111111111111111111111111100转化为16进制为FFFFFFFC11.正文:后果为at,char**pa二级指针,寄存的是一级指针的地址 12. 注:char***cp是一个三级指针,寄存的是数组cp的首元素的地址,cp是一个寄存指针地址的数组,每个数组元素寄存的是指针数组c的每个元素的地址,而数组c又别离寄存了四个字符串的首元素的地址,并将其作为元素存储。存储示意图如上图所示,1.**++cpp,此时指针cpp会指向cp数组的第二个元素,即c+2,再通过两次解援用找到了字符串“POINT”的首地址,以%s的模式打印,便打印整个“POINT”字符串2.*--*++cpp,首先指针cpp自增1,持续向数组cp的下一个元素挪动,即指向了c+1元素,解援用,即找到了c+1寄存的地址,即找到了数组c的第二个指针元素。接着--操作符,使得找到了c数组的第一个指针元素,再解援用,失去了"ENTER"的首元素地址,再+3即第四个字符E打印字符串,所以后果为“ER”。3.*cpp[-2]+3等价于**(cpp-2)+3,此时cpp自身并不挪动,但cpp-2找到了cp数组的c+3元素,解援用,失去c+3指向的元素的地址,即数组c的最初一个元素的地址,再次解援用,失去了c数组最初一个指针寄存的字符串元素的首地址,最初+3,即从S开始打印字符串,后果为“ST”4.cpp[-1][-1]等价于*(*(cpp-1)-1),cpp-1找到了C+2,解援用找到了对应的c数组第三个元素的地址,-1,找向c数组上一个元素,再解援用,失去了“NEW”的首元素地址,+1,向后找到了“E”,从此处开始打印字符串,所以后果为“EW”

July 29, 2021 · 1 min · jiezi

关于c++:mongoose

mongoose的源码地址:https://github.com/cesanta/mo... mongoose的用户手册:https://www.cesanta.com/devel...

July 29, 2021 · 1 min · jiezi

关于c:杨氏矩阵查找问题

杨氏矩阵阐明:即一个n*n的矩阵,从左往右顺次递增,从上往下顺次递增例如: 就是一个简略的杨氏矩阵当初要查找一个数字是否在该矩阵外部,并且工夫复杂度要小于O(N),即不能程序查找首先察看杨氏矩阵的法则,右上角的元素是本列最小,本行最大。因而只有和右上角的元素进行比拟,若被查找元素小于右上角元素,则阐明该元素看到不在右上角元素对应的列,则矩阵能够向左缩减列,若被查找元素大于右上角元素,则阐明该元素不在右上角元素的同一行,则矩阵能够向下缩减一行,依照这个思路迭代的去比拟被查找元素与右上角元素的关系,若在某一次二者相等,则在杨氏矩阵中存在该元素,若找到左下角的元素依然没有找到该元素,则阐明该元素不存在于杨氏矩阵中。同样的思路可用于左下角的元素代码实现:int Find_Num(int arr[3][3], int k, int* row, int* col)//传入一个3*3的矩阵,并传入被查找元素k以及行数的指针,列数的指针{ int x = 0; int y = *col - 1; while (x <= *row - 1 && y >= 0)//循环终止条件,找到了左下角元素 { if (arr[x][y] > k) { y--;//若右上角元素大于被查找元素,则向左列查找 } if (arr[x][y] < k) { x++;//若右上角元素小于被查找元素,则向下行查找 } else { *row = x;//若二者相等,则将该元素的坐标地位返回 *col = y; return 1; } } return 0;}注:传入指针的目标是不便扭转内部实参的值,使得内部实参能够获取被查找元素的坐标值

July 27, 2021 · 1 min · jiezi

关于c:实现将一个数组中的所有奇数放到数组前部分偶数放到数组后部分

如题:利用数组的左右指针,从两端往两头遍历数组,若左指针遇到偶数,右指针遇到奇数则奇偶替换,晓得左右指针不能挪动地位 #include<stdio.h>#include<string.h>void swap(int* left, int* right)//办法一{ while (left < right) { if ((*left) % 2 == 1) { left++; } if ((*right) % 2 == 0) { right--; } else { int temp = 0; temp = *left; *left = *right; *right = temp; } }}void swap1(int* left, int* right)//办法二{ while (left < right) { while ((*left) % 2 == 1) { left++; } while ((*right) % 2 == 0) { right--; } while (left < right) { int temp = 0; temp = *left; *left = *right; *right = temp; } }}void print(int* arr,int len){ int i = 0; for ( i = 0; i < len; i++) { printf("%3d", arr[i]); }}int main(){ int arr[] = { 1,6,5,2,7,8,10,4,9 }; int len = sizeof(arr) / sizeof(arr[0]); //swap(arr, arr + len - 1); swap1(arr, arr + len - 1); print(arr, len);}正文:当数组全为奇数或偶数时,应加上约束条件left<right避免指针越界拜访数组元素

July 27, 2021 · 1 min · jiezi

关于c:C入门11自定义数据类型

Summary1)typedef并不是创立了一个新类型,而是给一个已有类型创立了一个新的名字 2)typedef次要用来简化类型名和对立定义变量的形式(重命名函数和数组) 3)struct用于自定义新类型,可能将不同数据类型的变量组成一个汇合。struct创立新类型是一条非法的语句,因而要以分号;完结,外面的每个定义变量的语句,也都是以分号;完结。 4)stuct构造体类型能够先申明再定义(申明只是通知编译器构造体类型的新名字是什么,所以不定义也能够)。如果只是前置类型申明,然而还没有定义,这时候只能定义指针(因为在定义变量的时候须要分配内存,只有类型无奈确定变量大小;但能够定义指针,因为指针固定大小4字节或8字节)。 5)struct构造体类型能够省略类型名,匿名构造体。两个匿名构造体的类型即便看起来一样,但依然是不同的两个构造体类型。 6)struct构造体变量的实质是变量的汇合,外面的成员占用独立的内存。 7)union联合体也是C语言中用于自定义类型的一个关键字,用法和struct很像。union与struct的不同之处在于: 不论union XX{}; 中有几个变量,所有的成员都共享一段内存,所有成员的起始地址都是雷同的union XX{}; 占用的内存大小取决于成员的最大类型union XX{}; 类型的变量只能以第一个成员类型的有效值进行初始化当取不同联合体里不同变量的值时,要以相应的类型去解读这一段内存8)小端系统:低地址内存存储低位数据;大端系统:低地址处存储高位数据;union联合体能够用于判断零碎的大小端: int isLittleEndian(){ union { int i; char c; } test = {0}; test.i = 1; // 如果是小端系统,低地址就存低位数据,1就会存在低地址处 return (test.c == 1); // c只占一个字节,从低地址处取一个字节,应该失去1}9)enum是C语言中的自定义类型关键字,可能定义整形常量的汇合类型。特点:第一个枚举常量的默认值为0;能够对任意枚举常量指定值(只能指定为整形);后续常量的值默认在前一个值的根底上+1;enum类型的变量的实质依然是一个整形变量。所以enum类型变量的大小为4。C语言中能够用任意一个整形值去初始化枚举变量(在C++中就必须用枚举值进行初始化,强类型) 10)古代程序设计中,内存应用的最小单元是字节;有一些特定场合,能够将比特位作为最小单元应用内存:位域可能指定成员变量占用内存的比特位宽度 11)深刻位域:位域的实质依然是一个构造体类型 位域成员必须是整型,默认状况下成员顺次排列 struct Bits1{ int a : 16; short b : 8; char c : 8; // float f : 16; // error, bit-field ‘f’ has invalid type'位域的成员必须是整型!' float f; // 如果不应用 : 指定位域宽度,那么f就是一个非法的构造体成员};sizeof(Bits1) = 8; // a:2, b:1, c:1, f:4位域成员占用的位数不能超过类型宽度 ...

July 26, 2021 · 3 min · jiezi

关于c:C入门10指针

Summary1)指针的实质是变量,非凡之处在于指针存储的值是内存地址(内存中每个存储单元的编号:计算机中的最小存储单元是1byte ,即每个字节的编号都是一个内存地址) 2)程序中的所有元素都存在于内存中,因而能够通过内存地址拜访程序元素 3)内存地址的实质是一个无符号整数(4字节或8字节);4字节和8字节别离对应于32位和64位,所以咱们常说的32位和64位零碎指的就是可拜访的最大内存地址是多少。因为64位零碎能反对更大的内存寻址,所以64位零碎会比32位零碎能同时运行的程序要多。 4)只有通过内存地址+长度能力确定一个变量中保留的值。内存地址只是一个起始值,只有依据类型信息,晓得占多少内存、解读形式,才能够精确的读出变量里保留的值。 5)函数参数是指针时(传址调用),能够实现在函数外部批改函数内部变量的值;应用指针作为参数,能够作为一个传出参数,使得函数能返回多个值。 6)对于数组int a[5],a和&a的关系: a能够看做一个常量指针,示意数组首元素的地址,值是0xA,类型是int*,即内存长度为4&a是数组的地址,值是0xA,类型是int(*)[5],即内存长度为20。指向数组的指针:int(*pArr)[5] = &a;7)指针与数组的等价用法: int a = {1, 2, 3, 4, 5};int* p = a;a[i] <--> *(a + i) <--> *(p + i) <--> p[i]8)C语言中,字符串常量的类型是char*(c++里则是const char*);int v = *p++;等价于int v = *p; p++;因为(*)的优先级和(++)雷同 9)函数的实质是一段内存中的代码,占用一段间断的内存。函数名就是函数的入口地址(函数体代码的起始地址)。通过函数名调用函数,实质为指定具体地址的跳转执行。因而能够定义指针,保留函数的入口地址:type (*pFunc)(param) = funcName; 10)问:既然通过函数名能够间接调用函数,那么为什么还须要函数指针呢?答:能够定义函数指针参数。应用雷同的代码,实现不同的性能。主调函数只晓得函数原型是这样,但不晓得具体会调用哪个函数。函数指针是回调函数的实现机制:函数作为参数应用时,就形成了callback; 11)堆空间的实质是程序备用的“内存仓库”,以字节为单位预留的可用内存 12)在C语言中,void*指针能够和其余类型的指针type*进行互相赋值,因为C语言对指针的查看并不严格。然而在应用时肯定要留神操作的数据类型,void*仅仅是一个初始地址,不蕴含长度信息。 13)malloc用于向堆空间中以字节为单位申请内存;free用于偿还堆空间的内存,malloc而不free,内存泄露;屡次free,解体。 14)指针是一个变量,那么天然也就会有指向指针的指针,即多级指针。之前变量能够应用指针进行传址调用,那么也能够通过多级指针实现对指针的传址调用,在函数外部扭转内部的指针的值。 15)二维数组的实质是一维数组,所以二维数组名a示意的是数组的首元素,即a[0]示意的是一个一维数组;a的类型是type (*)[size2] int arr[2] = {0};int* pa = arr;int (*pArr)[2] = &arr;int bArr[2][2] = {0};int (*pb)[2] = bArr;typedef int (oneDimension)[2];oneDimension (*pbArr)[2] = &bArr;16)禁止返回局部变量的地址,因为局部变量在函数调用完结后,生命期就完结了。此时返回的是个野指针。 ...

July 25, 2021 · 2 min · jiezi

关于c:C入门9宏定义

Summary1)C语言中,实参和函数的形参之间仅仅是值传递,因而在函数外部无奈扭转实参的值。 2)函数是一种代码复用的伎俩 3)宏是C语言中代码复用的补充形式,是对函数的一种补充;函数和宏的关系,相似于生存中演员和替身的关系,只是用于某些非凡场景。在大部分状况依然优先思考函数。 4)宏没有函数调用的开销,函数调用须要在栈上保护流动记录;宏只是简略的文本替换,因而代码块会收缩,函数只会应用同一段函数体;宏替换不会对类型进行查看,当宏和运算符联合在一起时,会呈现意想不到的谬误,函数会进行类型查看,也不会呈现二义性; 5)编译器组成简介: 预处理模块:解决所有#结尾的语句(复制粘贴替换 --> 两头文件.i)编译模块:将C程序翻译成二进制程序(两头文件.i --> 汇编文件.s --> 二进制文件.o)链接模块:将二进制程序组合成可执行程序(.o --> .out)宏定义问题:以下代码输入什么?为什么? void swap(int a, int b){ int t = a; a = b; b = t;}int main(){ int x = 1; int y = 2; swap(x, y); x = ? y = ?}以上代码输入为x = 1, y = 2;尽管咱们进行了替换,然而x和y的值依然没变,起因在于:实参和形参之间仅仅是值传递,所有函数中无奈间接扭转实参的值。 再次了解函数:函数是一种代码复用的伎俩 把实现某个性能的代码片进行封装(当做一个整体)给这个代码片段一个适合的名字(通过名字来应用代码)定义参数(定义代码片段须要解决的问题)C语言中的的宏,是对函数“缺点”的补充 宏是C语言中代码复用的补充形式宏定义的语法:#define MACRO(param) code_segment宏应用语法:MACRO(num); #define ADD(a, b) a + bint z = ADD(1, 2);宏与函数的不同: 宏不是函数,没有函数调用的过程(不须要在栈上保护函数调用的记录);函数调用会先传递参数值,而后跳转执行函数体,而后返回应用宏只是单纯“代码复制粘贴”,而后替换参数同一个函数,无论调用多少次,都只有一份函数体代码;同一个宏,每次都会“复制粘贴”雷同代码编译器组成简介: 预处理模块:解决所有#结尾的语句(复制粘贴替换 --> 两头文件.i)编译模块:将C程序翻译成二进制程序(两头文件.i --> 汇编文件.s --> 二进制文件.o)链接模块:将二进制程序组合成可执行程序(.o --> .out)再论宏常量:#define NAME value ...

July 25, 2021 · 1 min · jiezi

关于c:C入门8函数

Summary1)C语言中的函数次要有2种类型: Function:数据处理(数据 --> 数据),通过某种规定由输出的数据失去输入数据Procedure:过程定义(数据 --> 性能),(依据数据)执行一系列动作,进而实现某种性能2)应用程序必须依附操作系统能力运行,应用程序承受操作系统的治理。当操作系统运行程序时,首先调用的就是main()函数。)(main()函数个别是第一个被调用的函数,也有其余办法能够让其余函数先于main执行) 3)应用程序执行的过程:(后续补上时序图) 用户双击.exe,或者在命令行中间接运行.exeOS把应用程序加载到内存中:Load()OS找到应用程序的main()函数执行main()函数敞开应用程序时,main()函数执行完结,返回一个值给操作系统(在windows中,能够在命令行,应用echo %errorlevel%命令查看刚刚命令执行的exe的返回值)4) 函数的调用过程: 暂停主调函数跳转到被调函数,执行被调“函数体”被调函数返回,复原执行主调函数5)工具包就是一个函数集,蕴含了一系列定义好的函数。#inlude语句用于申明,要应用工具包中的函数。 6)void是C语言中的一个根本类型,但void不是根底数据类型,不能够用来定义具体变量。 7)C语言中如果想定义一个无参函数,必须应用void申明!如果函数参数列表什么都不写,示意承受任意多的参数。即:void f(void) --> 不承受参数;void f() --> 几个参数都能够; 8)对于void f()无返回值函数,能够间接应用 return; 语句使函数间接返回 9)形参:函数定义时的参数列表;实参:函数调用时指定的具体值;实参用来初始化形参(将实参的值赋值给形参),所以形参相当于一个函数外部的变量(函数参数的实质是变量) 10)C语言中,当数组作为参数时,数组参数会进化为指针,数组大小无奈传递;此时批改数组形参,会同时扭转数组实参的值。 11)排序的要害操作:比拟和替换 12)全局变量不同同名,会产生命名抵触,报重定义的谬误;就近准则,存在多个同名变量时,优先应用最近定义的变量。 13)变量的作用域指的是变量定义后的可拜访范畴;在重叠作用域中,优先应用最近定义的变量。 14)代码块指的是从 { 开始到 } 完结的一段代码;局部变量的作用域从定义开始,到以后代码块完结; 15)对于全局变量,存在两个作用域全局作用域和文件作用域。全局作用域指的是在程序的各个角落都能够拜访到;文件作用域则只能在以后代码文件中拜访并应用; 16)计算机中,物理内存被分为不同区域,不同区域有不同的用处。全局数据区用于寄存全局变量和动态变量;栈区用于寄存局部变量和函数参数;堆空间用于动态创建变量; 17)生命期:变量从创立到销毁的工夫(非法可用的工夫)。全局数据区的变量:生命期从程序开始到程序完结;栈区的变量:生命期从进入作用域开始,到作用域完结; 18)作用域和生命期没有实质分割:作用域是语法层面上对变量是否可拜访的规定(空间上);生命期是二进制层面上变量存在于内存中的工夫(工夫上) 19)static润饰的变量位于全局数据区;static润饰的全局变量只有文件作用域;static局部变量只会初始化一次,作用域依然是所在代码块。 20)变量的生命期由存储地位决定。如果变量未初始化,存储地位决定了变量的初始值是多少:全局数据区的变量如果未初始,值为0(.bss段);栈区的变量如果未初始化,值为随机值;寄存器里的值未初始化为随机值。 -staticauto(默认)register局部变量全局数据区栈空间寄存器(可能)全局变量全局数据区----------------------------------21)C语言中,如果函数不写返回值类型,则默认返回类型是int;对于一个有返回值的函数,如果不写返回值,会返回一个随机值。 22)当参数只是一个字符串,且没提供长度的时候。能够应用while循环来遍历字符串,判断根据是字符串的最初一个字符是0元素'\0'。 23)在写递归函数的时候,首先要先把函数的递归模型画进去,而后去编写递归函数。编写时候要留神:n-1和边界。在了解递归函数的时候,不要想着去执行递归的细节,而是从递归模型来了解。递归模型的个别表示法: 1、函数的概念函数是具备特定性能的程序组件(能够看做黑盒:不须要晓得外面怎么实现的,只晓得怎么用)函数有明确的应用形式(固定输出对应固定输入)函数在程序中能够重复使用(程序中的工具)1.1 函数的类型C语言中的函数次要有2种类型: Function:数据处理(数据 --> 数据),通过某种规定由输出的数据失去输入数据Procedure:过程定义(数据 --> 性能),(依据数据)执行一系列动作,进而实现某种性能1.2 函数的组成部分函数名:函数的惟一标识函数参数:数据输出(数据 --> 数据, 数据 --> 动作)函数返回类型: 数据输入(数据 --> 数据)无返回值(数据 --> 动作)形如: 返回类型 函数名(参数1,参数2){ 程序语句1; ... 程序语句1;}2、函数的调用通过函数名调用曾经定义好的函数函数调用时须要顺次指定函数参数的具体值函数调用的后果(返回值)可保留在同类型的变量中 int r1 = func_name(5);int r2 = func_name(10);2.1 深刻了解main()个别状况下,C语言程序都是从main()开始执行的,那么main()是什么呢? ...

July 24, 2021 · 1 min · jiezi

关于c++:C-C-入门教程九通讯录管理系统

9 通讯录管理系统咱们要用之前学的所有常识做一个通讯录管理系统。须要实现上面几个性能: 增加通讯录显示通讯录删除通讯录查找通讯录批改通讯录清空通讯录退出通讯录我决定分两层来写,一层 Manager 用来治理和主界面交互的性能,另一层 AddressBook 用来管制底层的存储逻辑。 底层的头文件和源文件如下: //AddressBook.h#pragma once#include<iostream>#include<string>#define MAX 1000using namespace std;struct Node { string name; bool gender; int year; string phone; string address;};struct Book { Node nodes[MAX]{}; int size = 0;};void addBook(Book&, string, bool, int, string, string);void delByNum(Book&, int);void getBook(const Book&);void findBookByName(const Book&, string);void setBookByName(Book&, string, bool, int, string, string);void delAll(Book&);这个头文件定义了一个 node 构造,负责存储每一个具体的人的信息。又定义了一个 Book 构造,存储了一个 node 数组用来存储整个通讯录,并且存储了一个 size 变量用于存储通讯录中有多少集体的信息。并且咱们定义了减少、删除、显示、查找、设置、清空这六项性能。 咱们在源文件中实现了这些性能: //AddressBook.cpp#include"AddressBook.h"void addBook(Book& book, string name, bool gender, int year, string phone, string address) { book.nodes[book.size] = { name,gender,year,phone,address }; book.size++;}void delByNum(Book& book, int num) { for (int i = num - 1; i < book.size - 1; i++) { book.nodes[i] = book.nodes[i + 1]; } book.size--;}void getBook(const Book& book) { for (int i = 0; i < book.size; i++) { cout << '|' << i + 1 << '\t'; cout << '|' << book.nodes[i].name << '\t' << '|'; if (book.nodes[i].gender) { cout << "Male"; } else { cout << "Female"; } cout << '\t' << '|' << book.nodes[i].year << '\t' << '|' << book.nodes[i].phone << '\t' << '|' << book.nodes[i].address << '\t' << '|' << endl; }}void findBookByName(const Book& book, string name) { for (int i = 0; i < book.size; i++) { if (book.nodes[i].name == name) { cout << '|' << i + 1 << '\t'; cout << '|' << book.nodes[i].name << '\t' << '|'; if (book.nodes[i].gender) { cout << "Male"; } else { cout << "Female"; } cout << '\t' << '|' << book.nodes[i].year << '\t' << '|' << book.nodes[i].phone << '\t' << '|' << book.nodes[i].address << '\t' << '|' << endl; goto FLAG; } } cout << "no founding." << endl;FLAG: cout << endl;}void setBookByName(Book& book, string name, bool gender, int year, string phone, string address) { for (int i = 0; i < book.size; i++) { if (book.nodes[i].name == name) { book.nodes[i].gender = gender; book.nodes[i].year = year; book.nodes[i].phone = phone; book.nodes[i].address = address; goto FLAG; } } cout << "no founding." << endl;FLAG: cout << endl;}void delAll(Book& book) { book.size = 0;}然而这些性能只是负责底层交互的,然而这些函数都须要很多的参数,调用的时候如果还要写很多的语句来补充参数代码看起来就很简单。所以咱们须要再封装一层,把取得参数的这些语句也封装起来。 ...

July 22, 2021 · 4 min · jiezi

关于c++:C-C-入门教程八结构体

8 构造体8.1 构造体基本概念构造体属于用户自定义的数据类型,容许用户存储不同的数据类型 8.2 构造体定义和应用定义语法:struct structureName{ memberList }; 创立语法: struct StructureName variableName;struct StructureName variableName{ member1, member2…… };定义时创立struct StructureName{ memberList }variableName;通过语法veriable.member来拜访构造成员 8.3 构造体数组作用:将自定义的构造体放入数组中保护 语法:StructureName variableName[ dataNum ]{{},{}……}; 8.4 构造体指针作用:通过指针拜访构造体中的成员 利用操作符->来通过指针拜访构造体的属性 8.5 构造体作为参数构造体也是分为传值和传址的。和数组不同,数组自身就能够作为一个指针,然而构造体不行,构造体自身是一种变量,所以必须应用传址的办法能力扭转构造自身。 留神:这一点和 Python, Java 都不一样,须要独自记忆一下。 8.6 构造体中 const 实用场景传值尽管好用(哪里好用?)然而每一次传值,形参到实参都必须复制一次,十分占用资源。而如果咱们传址的话,就只须要四个字节,能够缩小对内存数据的占用。 然而指针拜访数据会有隐患,在函数中就能批改数值了。 因而,咱们为了爱护实参的内容,不容许扭转,因而咱们应用常量指针const structName* variableName作为参数传入。

July 22, 2021 · 1 min · jiezi

关于c++:C-C-入门教程七指针

7 指针7.1 指针的基本概念作用:通过指针间接拜访内存 内存编号是从0开始的,个别是十六进制示意的(具体几个字节应该是看零碎的)能够利用指针变量来存变量的地址7.2 指针变量的定义和应用语法:dataType * pointVariableName = &variableName &是一个取地址符号。 你能够用解援用符号*来拜访指针拜访的内存。 *pointVariableName就示意variableName这一块内存里的存储的变量 7.3 指针所占内存空间指针也是一种数据类型,那么这种类型占多少空间呢? 猜想,和零碎相干。64位的零碎的内存地址可能是64位,而32位零碎可能是32位。在32位零碎下占用4个字节。而64位零碎占8个字节。然而大多数开发环境都是32位。(此处也能够抉择x64编译环境来切换。 7.4 空指针和野指针空指针:指针变量指向内存中编号为 0 的空间 用处:初始化 留神:空指针指向的内存是不能拜访的 语法:dataType* pointVariableName = NULL; 野指针:指针指向了非法的内存空间 这是一种谬误,在程序中要尽量避免呈现野指针 语法:int* p = (int*) 0x1100; 然而实际上 0x1100 这块空间是没有申请的。这块空间上没有申明任何的变量,也就没有被零碎调配一块内存。因而是没有权限拜访的。这样的程序是有谬误的。 7.5 const 润饰指针const 润饰指针有三种状况: const 润饰指针:常量指针const dataType* pointVariableName 指针自身能够扭转,然而指针指向的值不能通过指针扭转。 const 润饰变量:指针常量dataType* const pointVariableName 指针自身不能够改,然而指针指向的值可扭转。 const 即润饰指针又润饰变量 用两个 const 就能够了const dataType* const pointVariableName7.6 传址指针能够作为参数传入函数。这种过程咱们成为址传递,又称为传址。传址后就能够批改实参具体的值。 如果抉择将数组作为参数传入函数,有两种传法,一个是int arr[],而数组能够看做是一个指针,因而也能够抉择用int* arr的办法传入,这样他就作为一个指针传入了。

July 22, 2021 · 1 min · jiezi

关于c:调用一个函数之后发生了什么

假如: AMD64 LinuxC/C++首先,咱们不须要讲太多的概念。只须要回顾几个根本的寄存器: %rsp:保留栈顶指针%rbp:保留栈底指针%rbp~%rsp 这一段向下舒展的区域,就是栈帧。%rip:保留下条指令的地址%rdi:保留函数的第一个参数%rsi:保留函数的第二个参数%rax:保留返回值而后,间接看代码吧! 样例程序假如有程序如下: int sum(int x, int y){ return a + b;}int main(int argc, char const *argv[]){ int a = 1, b = 2; int c = sum(a, b); return 0;}应用 gcc -g prog.c -o prog 进行编译。其汇编代码如下: int sum(int x, int y){ 1125: 55 push %rbp 1126: 48 89 e5 mov %rsp,%rbp 1129: 89 7d fc mov %edi,-0x4(%rbp) 112c: 89 75 f8 mov %esi,-0x8(%rbp) return a + b; 112f: 8b 55 fc mov -0x4(%rbp),%edx 1132: 8b 45 f8 mov -0x8(%rbp),%eax 1135: 01 d0 add %edx,%eax} 1137: 5d pop %rbp 1138: c3 retq0000000000001139 <main>:int main(int argc, char const *argv[]){ 1139: 55 push %rbp 113a: 48 89 e5 mov %rsp,%rbp 113d: 48 83 ec 20 sub $0x20,%rsp 1141: 89 7d ec mov %edi,-0x14(%rbp) 1144: 48 89 75 e0 mov %rsi,-0x20(%rbp) int a = 1; 1148: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp) int b = 2; 114f: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) int c = sum(a, b); 1156: 8b 55 f8 mov -0x8(%rbp),%edx 1159: 8b 45 fc mov -0x4(%rbp),%eax 115c: 89 d6 mov %edx,%esi 115e: 89 c7 mov %eax,%edi 1160: e8 c0 ff ff ff callq 1125 <sum> 1165: 89 45 f4 mov %eax,-0xc(%rbp) return 0; 1168: b8 00 00 00 00 mov $0x0,%eax}执行流程咱们间接从 main 读起。请务必认真关注调用栈的变动。 ...

July 22, 2021 · 4 min · jiezi

关于c++:C-C-入门教程六-函数

6 函数6.1 概述作用:将一段常常应用的代码封装起来,缩小重置的代码 一个较大的程序,个别能够分为很多的程序块,每个模块都能够封装起来作为一个函数性能。 6.2 函数的定义定义函数: 返回值类型函数名参数列表函数体return 表达式6.3 函数的调用语法:functionName( peremeterList ) 函数中的参数,咱们成为形式参数,简称形参。 而咱们调用参数的时候传入的参数为理论参数,简称实参。 调用函数的时候,实参的值会传递给形参,这种值传递也成为传值。 6.4 值传递函数调用时,会将实参的值传入函数的形参,这个过程称为值传递,又称为传值。 因而,传值时,如果形参产生扭转,不会影响实参自身的值。只有传址或者传援用能够扭转实参的值。 6.5 函数的申明作用:通知编译器函数名称以及如何调用函数,函数的理论主体能够在前面独自定义。 函数能够申明很屡次,然而只能定义一次。 函数申明自身对于开发者的意义更多是提前就能晓得这个程序中的局部函数是怎么运行的,而后能够间接去看主函数。而对于编译器来说,理论就相当于把函数的定义间接写在了申明的中央了。编译器发现函数申明之后,就会间接去寻找绝对应的函数定义,并且把函数编译进来。 不过函数申明有一个长处。当函数须要调用另一个函数的时候,函数的定义是有先后的。必须要先定义被调用的函数,再定义调用函数的函数。然而如果在文件头一起申明的话,就不会有这个问题了。而且申明是不须要留神程序的。 6.6 函数的分文件编写作用:让函数构造更加清晰 步骤: 创立后缀名为.h的头文件创立后缀名为.cpp的源文件在头文件中写函数的申明在源文件中写函数的定义做一个简略的替换两个数的函数,把函数独自放在程序中。 先写函数自身的源文件 //swap.cpp#include"swap.h"void swap(int& a, int& b) { int space; space = a; a = b; b = space;}而后写这个函数的申明,放在一个头文件中 #pragma oncevoid swap(int&, int&);其中#pragma once作用和上面的代码差不多: #ifndef A_H#define A_H……#endifpragma 是编译附注,这句话示意这个头文件只能被编译一次。整个编译过程中只能关上文件一次。 拓展: 办法一:pragma once 办法二:ifndef A_H 这两个办法没有太大的区别。细节上说,办法二的可移植性更高,有些编译器不反对办法一。另一方面,办法一是物理层面上一个文件不会被编译两次。然而如果一个文件有多份拷贝,就会都关上。 而办法二重视的则是文件名。只有文件一样,多少拷贝都只会编译一次。然而如果多个头文件是一个名字的话,也有可能导致剩下的几个不被编译了。 最初咱们编写主函数: //main.cpp#include<iostream>#include"swap.h"using namespace std;int main() { int a = 10, b = 20; cout << "替换前:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; swap(a, b); cout << "替换后:" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl;}留神一下:本人编写的头文件蕴含用双引号"",而零碎提供的头文件则用尖括号<>。 ...

July 21, 2021 · 1 min · jiezi

关于c++:C-C入门教程五-数组

5 数组5.1 概述所谓数组,就是一个汇合,外面寄存了雷同类型的数据元素 特点1:同一个类型 特点2:存储空间间断 5.2 一位数组5.2.1 一位数组的定义形式三种定义形式: 数据类型 数组名[ 数组长度 ];数据类型 数组名[ 数组长度 ] = { 值1, 值2,……};数据类型 数组名[] = { 值1, 值2,……};第三种定义方法并不是没有数组长度,而是编译器会依据你前面的值的数量主动生成一个长度。 5.2.2 数组名的用处能够统计数组在内存中的长度 能够获取数组在内存中的首地址 思考: 我当初有一个数组int arr[10]此时,arr代表的是第一个元素的地址 那么,arr+1 应该和 &arr[1] 一样,代表的是第二个元素的地址 如果是 &arr[0] + 1呢,代表的是第一个元素的第二个字节的地址么? 对于数组名的几种应用,对于数组名的意义,我做了一个试验,写了代码如下: #include<iostream>using namespace std;int main() { int arr[7]{ 5,2,0,1,3,1,4 }; cout << "&arr[0] = " << (int)&arr[0] << endl; cout << "arr = " << (int)arr << endl; cout << "&arr[1] = " << (int)&arr[1] << endl; cout << "arr + 1 = " << (int)(arr + 1) << endl; cout << "&arr[0] +1 = " << (int)(&arr[0] + 1) << endl; cout << "&arr + 1 = " << (int)(&arr + 1) << endl; cin.get(); return 0;}别离对应几种组合,最初输入如下: ...

July 20, 2021 · 1 min · jiezi

关于c++:C-C入门教程四-程序流程结构

4 程序流程构造C++反对最根本的三种程序运行构造: 程序构造抉择构造循环构造4.1 抉择构造4.1.1 if 语句作用:执行满足条件的语句 if 语句能够嵌套叠加 单行格局 if 语句if(条件){条件满足需要执行的语句;} 多行格局 if 语句if(条件){条件满足执行的语句}else{条件不满足执行的语句} 多条件 if 语句if(条件){满足的语句}else if(条件2){满足条件1但不满足条件2的语句}…else{都不满足的语句};练习案例 有三只小猪ABC,请别离输出三只小猪的体重,并判断谁最重。 #include<iostream>#include<string>using namespace std;class Pig { string name; int weight;public: Pig() { cout << "Pig constructed." << endl; } ~Pig() { cout << "Pig disconstructed." << endl; } void setName(string n) { name = n; } void setWeight(int w) { weight = w; } int getWeight() { return weight; } string getName() { return name; }};int main() { string name; int weight; Pig pigA; cout << "Please enter the name of pig A: "; cin >> name; pigA.setName(name); cout << "Please enter the weight of pig A: "; cin >> weight; pigA.setWeight(weight); Pig pigB; cout << "Please enter the name of pig B: "; cin >> name; pigB.setName(name); cout << "Please enter the weight of pig B: "; cin >> weight; pigB.setWeight(weight); Pig pigC; cout << "Please enter the name of pig C: "; cin >> name; pigC.setName(name); cout << "Please enter the weight of pig C: "; cin >> weight; pigC.setWeight(weight); if (pigA.getWeight() >= pigB.getWeight() && pigA.getWeight() >= pigC.getWeight()){ cout << pigA.getName() << " is the heavieat." << endl; } else if (pigB.getWeight() >= pigA.getWeight() && pigB.getWeight() >= pigC.getWeight()){ cout << pigB.getName() << " is the heavieat." << endl; } else{ cout << pigC.getName() << " is the heavieat." << endl; } cin.get(); return 0;}我在构造函数和解析函数中增加了输入语句。因而能够看出,如果不必new和delete的话,编译器也会主动地开释空间。 ...

July 20, 2021 · 2 min · jiezi

关于c++:C-入门教程三-运算符

3 运算符作用:用于执行代码的运算 3.1 算术运算符作用:用于解决加减乘除 + - * / 加减乘除 / 除法:两个整数相除的时候,后果仍然是整数,小数局部将会被去除 % 取模(又称取余):只能是两个整数取余 ++ 递增 --递加:让变量自加1,或自减1 前置递增(递加):递增(递加)运算符放变量后面,会先增后算。相同则会先算后增。 int main(){ using namespace std; //前置运算,最初会失去a=3, b=3 int a=2; int b=++a; cout<<b<<endl; //后置运算,最初会失去a=3, b=2 int c=2; int d=c++; cout<<d<<endl; return 0;}3.2 赋值运算符作用:把左边的值赋给右边 = 赋值运算 +=, -=, *=, /= 加等于,建等于,乘等于,除等于:这些符号一种简化,示意将右边对右做运算后将后果赋给右边。 3.3 比拟运算符作用:用于表达式的比拟,并返回一个布尔值。 == 等于 != 不等于 < 小于 \> 大于 <= 小于等于 \>= 大于等于 3.4 逻辑运算符作用:对值进行逻辑解决 ! 逻辑非运算 && 逻辑与运算 || 逻辑或运算 3.5 操作符优先级小结(补充)3.5.1 优先级1(优先级由高到低)从左到右联合最高优先级:括号 () 所有优先级都能够被括号突破 ...

July 20, 2021 · 1 min · jiezi

关于c++:C-C-入门教程二基本数据类型

2 数据类型2.1 整型C++ 中可能示意整型的类型有大略四种,区别在于所占空间的不同: 数据类型占用空间(单位:字节)short2int4longWindows(4), Linux(4), 64位零碎(8)long long8尽管我的零碎是64位的,然而试验了一下,可能是因为 VS 的起因,导致我写进去的 long 类型只有 4 个字节。这个其实不是特地的稳固,所以之后还是尽量少用 long 类型。 2.2 sizeof 关键字作用:能够统计一个数据类型占用的空间大小。 语法:sizeof(数据类型/变量) 单位:字节 依据之前的试验,sizeof 关键字不仅能够统计根本数据类型所占的空间大小,构造体、类都是能够通过 sizeof 来进行断定的。至于对于类中的动态对象、办法等占用空间是怎么计算的。能够先留一下,之后再看。2.3 浮点型浮点型变量分为两种:float, double 数据类型占用空间(单位:字节)有效数字范畴float47位double815-16位默认状况下,编译器会把一个小数当成一个双精度浮点数 double 类型,咱们在创立一个单精度变量的时候,能够通过加 'f' 后缀来间接失去一个单精度的常数。 默认状况下,输入一个小数,会显示六位有效数字。 示意小数的两种形式: 小数点计数法:即应用小数点来示意,相似于3.14159之类的。迷信计数法:相似于3e2,通过 e 来宰割。e 的后面是有效数字,前面是2.4 字符型作用:显示单个的字符。 我的了解是,尽管 char 类型中存储的数据实质是 ASCII 码,然而在进行输入的时候,一旦计算机辨认进去这个数据是 char 类型,则会把他当成字符自身进行输入。所以 char 自身是能够像个别的数据一样加减的。语法:char ch = 'a'; 有两点留神:一是字符须要用单引号 '' 扩起来,二则是单引号中只能放进一个字符。 通过强制转换,能够输出 ASCII 码,或者输入 ASCII 码。 输入 ASCII 码能够将须要输入 ASCII 码的字符转换为整型,而后输入。 int main() { char ch = 'A'; cout << (int)ch << endl; return 0;}输出 ASCII 码ASCII 码是能够间接输入的,像这样: ...

July 20, 2021 · 1 min · jiezi

关于c++:C-入门教程一-C初识

1 C++ 初识1.1 第一个 C++ 程序1.2 正文单行正文:// 多行正文:/**/ 1.3 变量变量存在的意义:不便咱们治理内存空间 每一块内存都有一个十六位的地址码 然而如果咱们用了变量的名字,咱们就能够不必地址码就能间接能调用这个数据了。 变量创立的办法: 数据类型 变量名称 = 变量的初始值;1.4 常量用来记录不能够批改的数据。 C++ 定义常量有两种办法: 1、#define 宏常量 #define 常量名 常量值通常在文件上方定义,用来示意一个常量。 2、const 润饰变量 const 数据类型 变量名称 = 常量值在变量的定义前增加const,则这个数据不能够被批改。 1.5 关键字在定义常量或变量时,不能够用关键字的名字,不然会产生歧义。 1.6 标识符命名规定不能够是关键字由字母、数字、下划线形成数字不能够是第一个字符标识符明明辨别大小写给变量取名字的时候尽量做到见量知意。

July 20, 2021 · 1 min · jiezi

关于c:C入门C语言中的数组

Summary1)数组是雷同数据类型变量的有序汇合 2)如果未给定数组元素大小,编译器会依据数组元素的个数主动推断数组的大小;数组中前面未被初始化的元素会被主动初始化为0。 3)数组的实质是一段间断的内存,用于存储数组元素;数组的大小能够通过sizeof获取,单位:字节;sizeof(arrName)。数组的元素个数:sizeof(arrName) / sizeof(arrName[0]) 4)数组的类型由元素类型和元素个数决定,示意为type [N] 5)多维数组的实质依然是一维数组,数组里的每一个元素是数组 6)字符串的实质是一个字符数组 7)C语言中对字符串或者字符数组的操作,肯定要关注0元素('\0'结束符);如果应用字符数组来模仿字符串变量,肯定记得在最初一个元素后加上结束符'\0' 8)字符串字面量的长度strLen:结束符'\0'之前的所有字符;字符串字面量占用的内存大小strSize:包含'\0'的所有字符。即strSize = strLen + 1; 9)char strcpy(char dst, const char *src);留神strcpy的第二个参数必须是一个字符串 1、一维数组1.1 数组的概念数组是雷同数据类型变量的有序汇合。 数组作为整体须要一个非法的命名(数组名)数组中的变量没有独立命名,只有在数组中的编号数组中的变量数量是固定不变的(数组大小固定)1.2 数组的定义语法:type Name[size]; int arr[10]; // 定义名为arr的数组 // 数组中一共有10个元素(变量) // 每个元素的类型为int1.3 数组的拜访通过数组名[下标]的形式拜访数组数组是一个有序的汇合,每个元素都有固定的下标数组元素下标固定从0开始(能够应用变量作为下标)int arr1[3];arr1[-1] = 0; // error,数组下标从0开始arr1[0] = 1; // okarr1[3] = 4; // error,数组中一共有3个元素,最初一个元素下标为2,下标3越界了 留神: 只有整型数能力作为下标来拜访数组元素下标越界是十分重大的谬误下标越界造成的严重后果可能不会立即体现进去1.4 数组的初始化语法:type Name[N] = {v0, v1, ..., vN-1};意义:将数组中的元素别离初始化为v0, v1, ... int main(){ int arr[5] = {2, 4, 6, 8, 10}; // 定义数组arr并初始化 int i = 0; for(i=0; i<5; i++) { printf("arr[%d] = %d\n", i, arr[i]); } return 0;}数组初始化技巧: ...

July 17, 2021 · 4 min · jiezi

关于c++:关于持久内存你了解多少

你说不定在不同的渠道曾经据说过一些相似的让人一头雾水的技术名词,比方非易失性存储,长久内存,傲腾长久内存,甚至英文的名词 Optane SSD, Optane persistent memory, PMem, DCPMM, AEP 等等…… 这些名词到底是什么?有什么分割?有什么用途?本文从科普的角度,帮你答复这些问题。心愿你看了本文当前,不论你是程序员还是相干行业从业者,至多都能明确什么是长久内存,它到底能施展什么样的作用。 长久内存到底是什么?首先答复一下凌乱的命名问题,咱们临时不纠结于这些名字之间的演变关系了,简略来说能够认为大部分都是指的同一个货色(当然不是严格正确)。目前Intel中文官网命名为“英特尔傲腾长久内存”,简称为“长久内存”。英文官网名为 Intel Optane Persistent Memory,简称为 PMem。因而在本篇文章中,对立应用“长久内存”或者“PMem”进行指代。那么正式开始……说到底,长久内存其实是一种新型的内存条,咱们能够先来看一下,它长这个样子,和一般内存条其实没啥特地大差别,而且它就是插在服务器的内存插槽里的。所以简略来说,你能够自行购买,而后插到你的服务器上的内存插槽上,你就能够应用长久内存啦。当然,长久内存对于硬件是有肯定的要求的,AMD的CPU就不必想了,长久内存属于 Intel 的独家法宝,天然不会留给竞争对手做反对。具体CPU的反对型号能够自行查找,这里不多赘述。当然如果想要施展长久内存的最大劣势,其在硬件配置插法上是有肯定的考究的,前面将会具体开展。而后咱们钻研下长久内存在整个计算机体系架构中的地位。学过计算机的同学,肯定对计算机的存储金字塔的架构十分相熟,那么如果咱们把长久内存也放到这个金字塔里,会是在什么地位呢?咱们具体来看一下。如下图所示的存储金字塔中,咱们能够看到长久内存处于外存(HDD或者SSD)以及内存DRAM之间,其不管在容量、性能、价格上都是处于两者的两头地位。除此以外,在性能上,它齐全就是个DRAM和外存的混血儿(所以为什么在图上PMEM标记为一半是淡水,个别是火焰)。也就是说,它即能够当做内存应用,也能够当做长久化外存设施应用,当然也能够两者兼顾,齐全取决于你如何应用长久内存。如果你还是不太能了解我形容的是什么,那么最间接的,通知你长久内存三个最重要的特色:大, 快,持久性: 大:目前长久内存单条内存容量最大能够达到 512 GB,而目前服务器单条内存个别最多到 32/64 GB。也就是说,单台服务器应用长久内存能够轻松达到 TB 级别的内存容量。另一方面,单位价格来说,长久内存为一般内存的一半左右。快:既然也号称为内存,那必然不能慢。能够看到,长久内存相比拟于一般 SSD 有1-2个数量级的提早性能劣势,相比拟于硬盘劣势更加微小。当然比照与DRAM,其会有肯定的性能差距。然而理论应用中因为性能瓶颈不肯定在内存上,所以个别不会有特地显著的差距(个别性能消退在一倍以内)。持久性:艰深来说,就是长久内存有跟硬盘一样的个性,断电当前重启,内存中的数据仍然存在。此项个性能够说是秒杀内存,内存中的数据咱们都晓得断电或者程序以外退出当前就不复存在。此项个性使得长久内存即能够当做一个高速长久化设施应用,也能够满足内存利用某些场景下的疾速复原的需要。如下表格总结了对于数据中心单台服务器上的典型配置,以及相应的大抵的性能数字作为参考。 常见内存和长久化设施在单台服务器上的大抵性能体现长久内存次要劣势场景是什么?说完了长久内存的个性,大家肯定也能设想出它在某些利用场景下具备得天独厚的劣势。具体来说,长久内存在理论落地中可能有以下几种玩法。以下从几个具体场景举例登程,并且辩证的给出应用长久内存带来的劣势,以及可能引入的问题。场景1:大内存低成本解决方案如果你的利用内存消耗量是要害,是整个零碎的资源瓶颈,那么应用长久内存将会是你降低成本的最佳解决方案。你的零碎个别在两种状况下对于大内存有特地的需要基于内存性能的考量,你必须应用基于内存的解决方案,而不可能应用基于磁盘的计划,比方内存数据库(Redis, MemSQL)。尽管你的利用能够承受基于磁盘而带来的性能损耗,然而显然如果内存扩充,你的利用能够跑得更快更加节省时间,比方基于 Spark 搭建的利用。此种场景下,你能够思考应用长久内存来提供一个大内存低成本的解决方案。劣势:长久内存在单位价格上约为一般内存的一半,并且能够在单台机器上轻松达到 1.5 TB,甚至 3 TB 的内存大小。因而比方你指标须要 20 TB 的总内存容量,长久内存可能只须要10台机器即可满足,然而基于DDR内存的集群可能须要40台甚至更多。思考机器投入以及经营上带来的老本,长久内存所带来的低成本解决方案的劣势是不言而喻的。可能的问题:当然引入长久内存,相比拟于内存可能会带来肯定的性能消退,消退的起因可能是长久内存自身所引起的,也可能是因为机器台数缩小,其余硬件资源(比方CPU核数或者网络带宽)缩小所引起的。所以理论我的项目落地中,作为决策者,肯定须要进行审慎评估,来量化长久内存带来的利害关系。场景2:高性能长久化需要的利用长久内存作为一个内存和外存的混合体,其高速长久化的个性在某些磁盘 IO 作为性能瓶颈的场景下是一个破局的解法。尽管 SSD 肯定水平上也能够缓解磁盘 IO 性能瓶颈,然而相比拟于 PMem 这种能够实现两个数量级的吞吐和提早改良的长久化设施来说,PMem 无疑是具备革命性的意义的。以下抛砖引玉举几个磁盘IO作为性能瓶颈的场景。音讯队列:大家相熟的开源音讯队列 Kafka,因为其音讯长久化逻辑的存在,其吞吐最终会卡在硬盘 IO 上。目前的解法是一直堆机器来扩大整个 Kafka 集群的吞吐。搜寻零碎:相似于 Kafka,风行的开源搜寻零碎 Elasticsearch,也将局部的数据结构寄存在磁盘上。那么最终影响整体提早和吞吐的将会是磁盘 IO 的性能。数据库或者KV存储引擎:比方 MySQL 或者 RocksDB,都具备重要的面向外存的数据长久化逻辑。分布式文件系统:在人工智能场景中,经常会有大量的小文件存在。比方在 Ceph 的文件系统中,在 metadata server 上对大量小文件的治理经常因为大量随机读写的存在而产生性能问题。劣势:显然,对于有高速长久化读写需要的场景,长久内存引入间接有了数量级的性能晋升。在吞吐方面,因为单机吞吐晋升,因而总的机器数量规模能够大量缩小,在提早方面则是提供了另一给维度的劣势。具体性能比对能够参照上一节开端给出的性能比对表格。可能的问题:PMem 作为纯正的长久化设施可能是把双刃剑,最次要的问题是其容量相比拟于传统硬盘来说还是偏小,同时单位成本也高。因而对于某些场景下如果除了对于性能,对于容量也有较高的要求,那么应用 PMem 带来性能的晋升,然而也可能会造成老本的回升。场景3:内存数据持久性的利用这种场景下,实质上还是把 PMem 当做一个内存来应用,和上一个高性能长久化的场景有所类似有所区别。上一个场景次要是针对原本软件架构设计就有长久化逻辑(比方文件系统原本就须要存在硬盘上),而后咱们把长久化逻辑搬移到PMem上就能够。其自身可能并不波及到简单的数据结构的批改,因为其原本的设计就曾经带有了长久化逻辑。然而在场景 3 这种内存数据长久化场景中,软件自身的内存数据结构的设计是没有思考到长久化逻辑的。因而你须要针对内存中的数据结构从新设计长久化数据结构和逻辑。这一类利用对开发的要求是最高的,同时也是最能齐全施展 PMem 的特点。此种场景往往是原本就是基于纯内存的利用,然而心愿减少数据长久的个性,最常见的需要是因为要疾速数据恢复。此种需要个别来自线上服务零碎(比方数据库 Redis,或者人工智能场景下的参数服务器、特色工程数据库等),线上服务一旦节点离线,都会造成服务质量的影响。因为零碎是基于内存数据结构,离线当前的数据恢复往往须要小时级别的工夫来从新抓取数据,并且从新构建内存中的数据结构。如果有了长久内存,此类服务不仅可能通过大内存降低成本,而且能够减少疾速复原性能,保障线上服务质量。劣势:如上所述,此种模式下,能够把长久内存的劣势充分发挥进去。首先大内存带来硬件老本的降落,其次,通过持久性,赋予了原本的内存利用的新的长久化个性,能够反对数据疾速回复,保障线上服务质量。可能的问题:此种利用惟一的问题可能是带来比拟多的额定的开发工作量。个别的内存数据结构都没有长久化逻辑,个别要求程序员通过 PMDK 从新设计长久化数据结构和逻辑,实现冀望中的内存数据长久化。如何做做长久内存的开发?首先必须弄明确,如果memory mode这种低成本扩大内存容量的形式能够满足你的业务需要,那么你基本不须要开发成本。然而如果不能满足你的需要,存在以下几种问题,那么你可能得动脑子想想须要如何对现有场景进行革新。• 内存模式性能消退过于显著,心愿应用大容量内存的同时,放弃和DRAM靠近的性能• 想利用长久内存来代替(或者一部分代替)传统外存设施,利用其高速长久化个性• 心愿对内存数据做长久化,提供离线当前的疾速复原性能长久内存的开发会是一个十分大的topic,而且依据你想要达到的目标不同,思路会齐全不一样,咱们这里不做开展。较量邀请基于以上介绍,置信你曾经对长久内存有了初步的理解。那么你想理解更多吗?你想切身感受这项技术吗?如果你想体验长久内存在AI利用上进一步的摸索的话,咱们为你提供了良好的机会!第四范式联结英特尔独特举办了【AI利用与异构内存编程挑战赛】,此次较量基于人工智能利用,以异构内存架构为硬件底座,基于英特尔® 傲腾™ 长久内存的前沿利用摸索及硬核编程挑战赛。通过较量你将会对人工智能如何在异构内存架构上受害有全新的意识,步入技术新境界。大赛会有技术专家亲自领导及解说。同时还设有高达20万元的赛道处分,以及为高校学生提供了Intel&第四范式联结实验室实习机会。欢送所有技术背景或对此项技术感兴趣的人群报名。高处分、双赛道、低门槛、良好的体验环境及技术支持,还不赶快报名!大赛官网:https://opensource.4paradigm....报名注册链接:http://openaios.4paradigm.com ...

July 16, 2021 · 1 min · jiezi

关于c:CC如何只保留4位有效数字

文章原文:https://tlanyan.pp.ua/c-cpp-keep-significant-figures/问题敌人要用数值算例验证舍入误差对算法稳定性的影响,实际中遇到的第一个问题是:C/C++如何只保留4位有效数字(significant figures)? 如果接触过Java/JS等语言,保留小数点后几位是非常容易的,调用setScale、toFixed等函数就能够,还能指定舍入模式。然而对于C/C++,如何保留指定有效位数呢? C/C++保留指定有效数字在C/C++语言中,精度的概念只在输入(流)中呈现,因而实现的一个思路是:依照指定精度输入字符串,再转换成数字。 C语言指定有效数字位数先看C语言的解决方案。 C语言的printf系列函数能够指定输入格局,打印成字符串后可用atof转换成数字。于是指定有效数字的C语言实现版本如下: include <stdio.h>include <stdlib.h>double convert1(int precision, double val) { char buffer\[128\];sprintf(buffer, "%.*g", precision, val);return atof(buffer);} 应用代码验证: int main(int argc, char* argv[]) { double f1 = 1235.46698;printf("origin: %.12f, converted: %.12f\\n", f1, convert1(4, f1));double f2 = 1.23546698;printf("origin: %.12f, converted: %.12f\\n", f2, convert1(4, f2));double f3 = 0.00123546698;printf("origin: %.12f, converted: %.12f\\n", f3, convert1(4, f3));double f4 = 0.0000123546698;printf("origin: %.12f, converted: %.12f\\n", f4, convert1(4, f4));return 0;} 输入后果如下: origin: 1235.466980000000, converted: 1235.000000000000origin: 1.235466980000, converted: 1.235000000000origin: 0.001235466980, converted: 0.001235000000origin: 0.000012354670, converted: 0.000012350000 ...

July 15, 2021 · 1 min · jiezi

关于c++:招募ACM世界冠军ACM杰出科学家强烈推荐第四范式x英特尔AI应用与异构内存编程挑战赛

2021年7月8日,由第四范式与英特尔独特主办的“AI利用与异构内存编程挑战赛”正式开赛!大赛基于人工智能利用、英特尔® 傲腾™ 长久内存,以异构内存架构为硬件底座,进行两者联合的前沿利用摸索及硬核编程挑战赛。大赛失去了ACM世界冠军、ACM年度卓越科学家、Intel首席长久内存架构师的统一举荐与认可。欢送宽广IT 行业开发人员,高校计算机相关业余同学,及对异构内存感兴趣的人群参赛。 【大赛主席团寄语】“这是咱们首次举办基于第四范式开源技术组件的AI开发者大赛。通过较量能够让选手们体验到工业界最先进的技术,将技术境界拓展到新的维度和高度。”——大赛主席【郑曌】、第四范式技术副总裁,根底技术研发负责人(郑曌,2010年ACM世界总冠军,曾在硅谷工作多年、先后就任于 Google 展现广告架构团队,Pinterest 搜寻团队并负责 Pinterest 搜寻架构与 个性化团队负责人,领有丰盛的大规模搜寻架构、个性化举荐架构、机器学习零碎架构教训和技术团队治理教训。) “本次较量使用到了咱们去年在VLDB上发表论文(http://vldb.org/pvldb/vol14/p...)的关键技术点。让选手们切实体验如何利用新兴硬件来进步零碎性能。我强烈建议大家加入此次较量。”——大赛联结主席【Dr. He Bingsheng】,ACM卓越科学家,加坡国立大学计算机学院首席副教授、副校长(Dr. Bingsheng,曾负责数据库、云计算、并行和分布式系统国内会议的评委会成员,并负责VLDB 2017的演示联结主席,IEEE CloudCom 2014/2015的评委会联结主席,2020年被评为ACM卓越科学家,在国内出名会议和期刊上取得多个论文奖和荣誉称号。) “此次较量波及到了英特尔与第四范式在顶级数据库会议上发表的钻研论文以及相干白皮书中(https://www.intel.cn/content/...)的内容。为了帮忙更多的开发者体验先进的内存技术、理解它的价值、学习这种编程模式,我诚挚的邀请大家加入本次较量。”——大赛联结主席【Andy Ruodff】,Intel首席长久内存架构师、非易失性存储编程先驱(Andy Ruodff,英特尔傲腾数据中心及长久内存首席架构师,PMDK PMC核心成员。) 【大赛详情】赛道处分总价值高达20万!低门槛、处分高,欢送前来报名!报名链接:https://openaios.4paradigm.com/官网链接: https://opensource.4paradigm....

July 14, 2021 · 1 min · jiezi

关于c:memmove-和-memcpy的区别

memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝肯定长度的内存的内容,原型别离如下:void memcpy(void dst, const void *src, size_t count); void memmove(void dst, const void *src, size_t count); 他们的作用是一样的,惟一的区别是,当内存产生部分重叠的时候,memmove保障拷贝的后果是正确的,memcpy不保障拷贝的后果的正确。 第一种状况下,拷贝重叠的区域不会呈现问题,内容均能够正确的被拷贝。第二种状况下,问题呈现在左边的两个字节,这两个字节的原来的内容首先就被笼罩了,而且没有保留。所以接下来拷贝的时候,拷贝的是曾经被笼罩的内容,显然这是有问题的。实际上,memcpy只是memmove的一个子集。 二者的c语言实现很简略,有趣味的敌人能够去看看。在理论状况下,这两个函数都是用汇编实现的。 memmove在copy两个有重叠区域的内存时能够保障copy的正确,而memcopy就不行了,但memcopy比memmove的速度要快一些,如:char s[] = "1234567890";char* p1 = s;char* p2 = s+2;memcpy(p2, p1, 5)与memmove(p2, p1, 5)的后果就可能是不同的,memmove()能够将p1的头5个字符"12345"正确拷贝至p2,而memcpy()的后果就不肯定正确了 变态的命名 咱们在写程序时,个别考究见到变量的命名,就能让他人根本晓得该变量的含意。memcpy内存拷贝,没有问题;memmove,内存挪动?错,如果这样了解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝。那么既然memcpy和memmove二者都是内存拷贝,那二者到底有什么区别呢? 先说memcpy 你有没有好好的加入过一场C++口试。让你写出memcpy的实现,这是如许常见的口试题啊。当初,拿起你的演算纸和笔;是的,是笔和纸,不是让你在你的IDE上写。写不进去?看上面吧: void *memcpy(void *dest, const void *src, size_t count){assert(dest != NULL || src != NULL);char *tmp = (char *)dest;char *p = (char *)src;while (count--){*tmp++ = *p++;}return dest;}memcpy的实现很简略,个别在口试时,呈现写源码的题目,无非就是须要留神以下几点: 1.确定函数原型;2.判断参数合法性;3.逻辑实现(思考各种状况,统称逻辑实现);4.错误处理。 当然了,我的这个没有错误处理,也不须要错误处理。下面,我写出了memcpy的实现源码,实现原理如下图所示: 这样上来,下面的代码会运行的很好,如果呈现上面的状况呢? i、n、k的内存和J、e、l的内存地址重合了,当初再应用下面的代码进行copy时,会呈现什么问题呢?你有没有想过这个问题。如果没有,那就当初想想,不急着浏览上面的内容。 ...

July 13, 2021 · 1 min · jiezi

关于c++:LP102-2019

LP102 2019 SpringHomework 1AbstractWrite a C [1] program that can play the games of Go and GoBan.1 Introduction of Go and GobanGo (called WeiQi in China) and Goban (called WuZiQi in China) are ancientboard games. The board is marked by horizontal and vertical lines. Stones,white or black, will be placed on the intersections of lines. Two players willuse different colors of stone, and put their stones in turn on the board. Goand Gomoku have different rules of winning. The rules of the two games aresimple. We can find online documents for their rules.Rules of Go:The picture above is from https://tromp.github.io/go/le...1https://en.wikipedia.org/wiki...https://senseis.xmp.net/?Basi...Rules of Goban:https://en.wikipedia.org/wiki...2 Gaming data storage2.1 Board and stoneA 2–dimentional array of integers is used to record the stones on the board.If the board has 19 × 19 lines, then we can use an 19 × 19 board. At aline interscetion on the board, there are 3 possible stone occurrences there:Empty, Black, White. We can use 3 different integers of represent the 3stones, such as 0, 1, 2. Initially, the board is empty, which means each itemin the 2D arrary of the board is Empty. When a user pick a coordinate, sayE 6, to place a stone, say a black stone, if Black is represented as 1, thenthe corresponding update of the board can be represented as the followingassignment statement:board4 = 12.2 Game play history recordWe can use a 3D integer array to record the history of a game, which isa sequence the positions where stones are put during the game. We don’tneed to remember which position is black or white in the history, since weassume a black stone is always put first. This history array will be saved toa file on a hard drive, or be loaded from a hard drive to memory.3 Display of gaming dataThe board and stones can be printed using ASCII characters at the commandline. Here is some screen record of playing GNU Go:White (O) has captured 0 piecesBlack (X) has captured 0 piecesA B C D E F G H J K L M N O P Q R S T Last move: White C519 . . . . . . . . . . . . . . . . . . . 19218 . . . . . . . . . . . . . . . . . . . 1817 . . . . . . . . . . . . . . . . O . . 1716 . . . + . . . . . + . . . . . O X . . 1615 . . . . . . . . . . . . . . . . O . . 1514 . . . . . . . . . . . . . . . X . . . 1413 . . . . . . . . . . . . . . . . . . . 1312 . . . . . . . . . . . . . . . . . . . 1211 . . . . . . . . . . . . . . . . . . . 1110 . . . + . . . . . + . . . . . X . . . 109 . . . . . . . . . . . . . . . . . . . 98 . . . . . . . . . . . . . . . . . . . 87 . . . . . . . . . . . . . . . . . . . 76 . . . . . . . . . . . . . . . . . . . 65 . .(O). . . . . . . . . . . . . . . . 54 . . . + . . . . . + . . . . . + . . . 43 . . . X . . . . . . . . . . . . . . . 32 . . . . . . . . . . . . . . . . . . . 21 . . . . . . . . . . . . . . . . . . . 1A B C D E F G H J K L M N O P Q R S Tblack(9): o2White (O) has captured 0 piecesBlack (X) has captured 0 piecesA B C D E F G H J K L M N O P Q R S T Last move: Black O219 . . . . . . . . . . . . . . . . . . . 1918 . . . . . . . . . . . . . . . . . . . 1817 . . . . . . . . . . . . . . . . O . . 1716 . . . + . . . . . + . . . . . O X . . 1615 . . . . . . . . . . . . . . . . O . . 1514 . . . . . . . . . . . . . . . X . . . 1413 . . . . . . . . . . . . . . . . . . . 1312 . . . . . . . . . . . . . . . . . . . 1211 . . . . . . . . . . . . . . . . . . . 1110 . . . + . . . . . + . . . . . X . . . 109 . . . . . . . . . . . . . . . . . . . 98 . . . . . . . . . . . . . . . . . . . 87 . . . . . . . . . . . . . . . . . . . 76 . . . . . . . . . . . . . . . . . . . 635 . . O . . . . . . . . . . . . . . . . 54 . . . + . . . . . + . . . . . + . . . 43 . . . X . . . . . . . . . . . . . . . 32 . . . . . . . . . . . . .(X). . . . . 21 . . . . . . . . . . . . . . . . . . . 1A B C D E F G H J K L M N O P Q R S TGNU Go is thinking...white(10): E4Here is the screen shot of playing Goban using with another board design:This the game setting:board-size: 13; win-size: 5; lines-on-board: YesEnter to continue!!!!!!! Welcome to Dragon Go !!!!!!A B C D E F G H J K L M N13 +---+---+---+---+---+---+---+---+---+---+---+---+ 13| | | | | | | | | | | | |12 +---+---+---+---+---+---+---+---+---+---+---+---+ 12| | | | | | | | | | | | |11 +---+---+---+---+---+---+---+---+---+---+---+---+ 11| | | | | | | | | | | | |10 +---+---+---+---+---+---+---+---+---+---+---+---+ 10| | | | | | | | | | | | |9 +---+---+---+---+---+---+---+---+---+---+---+---+ 9| | | | | | | | | | | | |8 +---+---+---+---+---+---+---+---+---+---+---+---+ 8| | | | | | | | | | | | |7 +---+---+---+---+---+---+---+---+---+---+---+---+ 7| | | | | | | | | | | | |6 +---+---+---+---+---+---+---+---+---+---+---+---+ 6| | | | | | | | | | | | |5 +---+---+---+---+---+---+---+---+---+---+---+---+ 5| | | | | | | | | | | | |44 +---+---+---+---+---+---+---+---+---+---+---+---+ 4| | | | | | | | | | | | |3 +---+---+---+---+---+---+---+---+---+---+---+---+ 3| | | | | | | | | | | | |2 +---+---+---+---+---+---+---+---+---+---+---+---+ 2| | | | | | | | | | | | |1 +---+---+---+---+---+---+---+---+---+---+---+---+ 1 ...

July 13, 2021 · 15 min · jiezi

关于c:那些年写过的bug0

在此记录一下本人写过的那些bug owo。 1)指向数组的指针在malloc前遗记初始化(赋值为NULL) 2) some_struct * ptr = A;array[1] = *A;而后就忘了开释ptr... 3) char * buffer = NULL;size_t sz = 0;while(getline(&buffer, &sz, file) > 0){ ...}而后遗记开释buffer... 4)假如line是一个字符串(比方"apple")。 line[2] = '\0';而后 strchr(line, 'e');就返回NULL了。因为当初的line是"ap"; 5) int* array = malloc(5 * sizeof(*array));for (int i = 0; i < 5; i++){ free(array + i);}反复开释内存了。

July 12, 2021 · 1 min · jiezi

关于c#:毕业四年我当初是如何走上编程这条路的

题记感慨万千,毕业已达4年之久。 想起在大学期间学习编程的事件,感觉很有意义,在此记录回顾一下。 心愿本人初心未变,勇往向前 现状与过来20210706 目前的我是在天津一家公司做软件开发,次要做C#桌面端开发,有时还写点Android,但主技还是C#、ASP.NET。 从毕业实习到当初始终在这家公司,是不是很吃惊。 毕竟在我同学都曾经换了不下3个单位的时候我还在刚开始的这家公司里,他特比吃惊,感觉不堪设想。 17年在大四第二学期时,咱们班很多同学都曾经离校,这也是学校过后默认的事件。 其实也就是为了进步入职率,让不考研和考公的同学尽早的找工作,尽早的进入职场。 我很感激学校有这样的政策,解决了我大四第二学期在外实习无奈不上课的难题。其实我也很费解,大四为什么还要排课,基本上一天也就一节课,而且很多同学都不在校,每次上课就只剩下考研和考公的同学在,也就不到15人。 可能每所大学在排大四课程的时候,都比拟两难。 我是复读一年才勉强考上大学(中央二本院校)的,高三第一年根本是在网吧打游戏度过的,基本不晓得学习,也没有要为本人未来做打算的信心,每天糊里糊涂的,度日如年。当初回想起来,真想使劲抽本人几个巴掌,那么好的资源,那么多工夫就那样被本人节约掉了。 复读那一年,堪称是惜时如金,晓得了学习,也戒掉了游戏。根本全年都在学习,因为晓得本人和他人的差距。 其实特别感谢我的妈妈和舅舅(还有其余的亲戚),没有她们我是无论如何也不会去复读的。过后考完试我就筹备报考一个大专,学习汽车培修,本人构想当前开一个汽修厂。我感觉本人轻易干些什么都能够,为什么非得去复读,再去学习,还要去考大学呢。(不晓得本人过后哪来那样的自信,再次想抽本人几个巴掌) 高考第一年我考了369分,过后陕西的二本分数线是461。如同刚好能上个三本院校,然而我不想让家外面多花钱就想间接去上大专,学个技能傍身。可是扭不过爸妈和亲戚的相劝,他们语重心长的劝我,劝我去复读,给我列举了各种复读的益处,最初我去复读了。 其实过后本人心里面分明,本人底子太差,即便复读一年也未必能考上二本。次要是差的太多,就拿过后考得问题来说,还差90分呢。 复读那一年,根本没咋劳动过,始终都在学习,记得过后还和几个敌人一起组织建设了学习小组,每天早出晚归的结伴学习。这一年兴许是运气比拟好,兴许是致力有了功效。第二年二本的分数线竟然降到了435分,我也好运的考了455分,比二本分数线高了20分(其实放眼到当初来看和他人比,差距还是特地特地大的,可是对于过后的本人来说,还是比拟侥幸的)。那可是足足进步了86分(替本人快乐)。 填报意愿时,本人特地想去成都,第一意愿就报了成都的一个学校。 对于填报的业余,其实对于过后的本人来说,基本不晓得未来要学什么,可能当初的高中生比拟有主意,网络这么发达,学习路径很多,可能早就确定了本人要学习的业余,可是对于过后的我来说,能想到的就是学机械制造,过后很粗略的理解机械制造具体是干什么的,就报了。其余的几个意愿都报的是陕西省内的,也根本都是机械制造为首的。 我依稀记得过后还特意报了物联网工程这个业余,理解的过程中感觉当前可能会大火(2021年也没火起来,其实也算火了,鸿蒙分布式系统火了)。这个业余是13年新开设的,在全国很火,每个学校都在开设物联网工程,我过后轻易理解了下,就把它填写在了最初一个意愿的第一个业余中。想着反正也不可能录入,毕竟我后面还有4个意愿,那么多业余呢,怎么能到最初一个意愿来呢(啪啪打脸)。 往往造化弄人,最初还是被不经意间抉择的物联网工程业余录取了。(甚是快慰呀,差点滑档了) 咱们学校物联网工程是被调配到计算机系的,因为是学校新开设的业余,没有什么以往教训,大学四年的课程安顿既有软件也有硬件。也就是说毕业后的咱们:既能熬夜加班敲得起代码,也能跃跃欲试焊的起板子。 可是对于本科生的咱们来说,样样通,不如一样精。 从13年刚入校我就理解到过后学校有个政策,大四那年院系会组织学生去西安加入培训,大略破费在2w元左右(达内,传智博播客,华清远见等),经过培训后的学生找工作都特地好,根本不必学校过多放心。 在过后大一的时候,我心里就默默使劲,阿辉呀你这四年可要好好致力,可别到了大四找工作的时候还要再去问家里要2w元来加入培训。 这不起初我的确没有加入培训,凭借本人大学四年在实验室外面学习到的编程技能,也还算顺利的找到了一份对口的工作。(文章前面能够看到过后本人的简历)。 我是17年2月来的天津,没有加入培训,间接进去工作,也算运气比拟好,单位也刚好是做C#方面的开发,也就牵强附会的留了下来,尽管其中也有一些别的起因,也算对口也算不对口(之前在学校次要做BS,来到公司后做CS)。然而也算持续走上了技术这条路,根本和本人在大三时给本人布局的职业门路一样,不一样的是本人来到了天津,而没有去上海(大学期间特地想去上海,感觉只有上海能力干出一番天地)。 我的大学大学四年,我给同学的感觉应该是很怪的,根本没事的时候都泡在实验室里(既有Wifi又有妹子),在宿舍基本看不到人,只有找我在我的项目实验室相对能找到。 我记得过后是大一下学期面试进的我的项目实验室,刚进来的时候感觉B格特地高,我的项目实验室牵头的是咱们信工院的一个日本求学归来的海龟博士申请创立的(很感激徐老师)。次要目地就是想开办一个连贯校外单位和学校学生之间的媒介,让学生通过接触真正落地的我的项目来感触理解里面单位真正须要哪种人才,让学生能够提前的进行筹备学习,为本人当前找工作早做打算。 B格高的起因:徐老师早晨也会偶然给咱们组织培训,平时根本的输入都是日语和国语混合,特地有意思。而且经常性的请大家喝咖啡(我当初爱喝咖啡的习惯可能就是那时候养成的) 刚开始的时候也就是个小罗罗,给搬电脑,打扫卫生,举办活动修电脑等,根本都是这样的活。前面到了大二,大三才缓缓的跟着实验室的室长开始做我的项目,保护学校官网微信(过后官微是室长借助盛派的SDK开发的),加入学校,市区等举办的大学生三创大赛,其中的作品也有获奖的,也有没获奖的,然而过后失去的我的项目教训的确实实在在是属于我的。 其实过后之所以进入实验室目标很单纯,就是想着毕业后不去培训。本人在大学期间多自主学习下,等到了大四简历下面就有我的项目可写了。可是待的工夫越久,越发现自己想做的事件越多,到最初来到时,本人也被老师提拔为实验室室长之一,也率领着学弟学妹们一起加入大创我的项目,带着大家一起学习编程常识。 上面图片是过后我的项目实验室的环境,很适宜学习,而且网速特快,又有空调,偶然老师还给大家说几句日语,请大家喝喝咖啡。 大学四年至今最让我回味无穷的是,学校旁边的鸡肉焖饺子,几乎一绝,每次宿舍聚餐都会去,越看越有感觉。 我是如何走上编程这条路的其实学习编程次要有以下几个方面的起因: 目标过后在大学努力学习编程的目地就只有一个,那就是不想大四毕业时去培训,想着在大学就把技术学好,所以才很致力的学习。(相比于其余同学而言,只是早早的晓得了本人该干什么而已,但和那些一流大学毕业后面试进大厂的同学比起来差的不是一丁半点,差距太大了,还得好好致力)。 趣味专业课程安顿有JAVA、C语言、Android,然而老师上课讲的也都是书本下面最最根本的知识点,实践层面并重,达不到学完后立马能上手做我的项目的水平。 尽管说业余外面学习JAVA和C语言,然而让我感兴趣的却是C#。在过后学完JAVA后,特地不喜爱配置环境,记得应用的IDE还是Eclipse,在环境配置这块就卡了良久才配置好。比照之下简略、疾速上手的C#,还是感觉JAVA太麻烦,过后感觉好简单,缓缓的就对其丢失了趣味,就始终和实验室老师和学长学习C#开发,用C#做我的项目,加入各种较量(当初反过来想,如果当初立志学JAVA,可能本人会走一条不一样的路,毕竟当初最火的是JAVA开发)。 金钱报酬过后做我的项目加入较量是能够挣到钱,尽管不多,但对于过后学生身份的我来说,1000~3000的,也是不错的经济起源,能够买一些本人之前始终舍不得买的货色或者说和舍友们进来大吃一顿好的(鸡肉焖饺子走起)。 鲜为人知的、少一些为什么的保持过后大一下学期和我一起报名在实验室上夜课(老师解说学习C#)的同学很多,可是等到大四快毕业时,还在做C#的就我和隔壁宿舍的哥们(李乾龙)。在一起学习的过程中,有些同学就因为或多或少各种各样的起因缓缓的早晨就不来了,放弃了。其实这都是很失常的,当有些事件得不到反馈或者说短时间内看不到回报时,大家都会有这种情绪呈现的。 也不晓得为什么,我和乾龙就保持了下来,基本上,每天只有没有大课安顿,咱们俩就背着电脑和键盘待在实验室外面学习(看视频、看书、敲代码),当初忽然想起还挺思念过后和好友一起努力奋斗的时光。 如何学习编程其实说起如何学习编程这个话题,本人或多或少还能说点话,毕竟本人也算靠着趣味和致力闯入了编程这道大门,然而也深知功力不是很深,在各个方面的能力还都有待晋升,所以上面就只是总结下过后本人如何去学习编程,可能适宜你也可能不适宜你,毕竟每个人的学习、排汇、总结能力都不一样。 看书和官网文档先看入门书籍,让本人能看懂语法,看懂他人写的代码。 依照编程语言的语法,能写一些简略正确的逻辑代码。比方排序,数组的应用,循环,递归等。这里要留神,刚开始先看那些比拟薄一点,知识点比较简单的书籍,别一上来就整什么红宝石书籍,特地特地厚的,先让本人能对其编程产生趣味,不然刚开始就整厚书籍、难懂的点,可能学上3~5天本人就放弃了,没了当初的趣味。(切记学习须要循序渐进,不可急于求成。) 看官网文档,对于一些编程语言,官方网站都会有系列的入门教程,这个是很重要的,官网出的货色都是知识面很广,而且受众整体比拟广,所以很容易看懂和上手。 不论是看书还是官网教程都要及时的被动敲代码,对于书中的例子或官网教程中的案例,刚开始都须要本人在本地敲一篇,你能够先间接对照着实现,看本人是否胜利运行,之后在缓缓的了解和批改。在你实现的过程中你会发现,这个过程就是一个正反馈的过程。你会领会到当你把一个我的项目,一点一滴的敲进编译器,能胜利运行后果时那种骄傲,满足的情绪(要常常这么做,这一点一滴胜利就是你坚持下去的能源)。 看视频第二阶段能够看一些网上的编程视频,比方B站外面的教程或某些培训班的培训教程(网上能够找到)。目前很多程序员都在B站制作品质一流的编程系列教程,这些教程只有你用心去找,都能找到。 看视频的作用,能够增强你对知识点的了解,看他人是如何制作,解释一个知识点的,是否和你刚开始看书或看官网教程了解的一样。 看视频的过程中,你也须要对照着作者的实现办法本人在本地实现,有时候你会发现看作者实现立马就懂了,可是当你本人在本地实现的时候就会遇到各种各样的问题,兴许你可能破费1终日都无奈解决(哈哈哈,别丢失斗志,这很失常)。 过后我学习C#的时候,看的是黑马程序员的培训教材,有好几个G呢,过后如同是学长在淘宝购买的,咱们就一起看、了解、学习,不懂的中央就一起探讨,剖析。 做我的项目做我的项目是终极目标,只有做我的项目能力将那些零散的知识点汇总起来,造成一条线。做我的项目也能让本人有成就感,看到本人通过几个月一点一滴保持做进去的货色,就特地满足。 在学校的话,能够加入一些较量,比方大学生三创(翻新、创意、守业)较量,和同学一起依照一个ID来构思,实现一个我的项目。 在参加的过程中,你会发现以前学习的货色可能都或多或少有点用途,当你们一起拿着本人做的我的项目来加入较量,西装革履的给各级领导解说,展现的时候你会发现那是如许的骄傲与满足。 还有就是有些我的项目可能挣到外快,比方给学校某些院系做官网、和老师一起做课题钻研等。 写博客写博客,你可能会很纳闷,为什么我会把写博客独自放在这里。 上面的地址和截图是我过后学习C#时在博客园创立的博客,次要写一些知识点和汇总在编程过程中遇到的各种问题。 博客园:https://www.cnblogs.com/netxi... 当初回过头让我去看当初写的货色,感觉好童稚呀,都写的是些什么,如果让我当初从新些,我感觉能写出比那时好几万倍的博客,可是当初是当初,当初是当初。那些货色就在那里,它能证实我的学习过程,它能让我看到本人的以前。 写博客的益处特地多,如果你用心去注意,很多大佬都有写博客的习惯。 写博客它能让你整顿本人的思维,能够把想到的知识点条理化。能够记录重要的知识点,不便回顾。能够帮忙他人,当他人遇到和你一样的问题时,他就能参考你的解决办法。能够帮忙你找工作(简历中能够放本人博客的地址,面试官看到后会对你另眼相看)。取得心理成就,让本人更自信(博客就相当于本人的学习经验,越多本人的信息越足)。上面是我过后大三时候的简历,当初看来技能点还是满满的。 给大学生的寄语在这里,我以还算过来人的身份想给大学生们说说本人的心里话,你们目前真的能够说是比任何时候都有劣势,有工夫,有前景。 确立指标你首先须要找到本人的趣味点所在,目前你有机会和试错的老本去尝试各种各样你感觉本人想干的事件,你能够在不影响学习的状况下,尽可能多的让本人接触到各行各业。确定好本人未来想从事的事件后,提前去理解,筹备。 抓住工夫在大学你会领有大把大把的工夫,你能够打游戏,能够和舍友通宵开黑,能够去各个中央逛。然而你得放弃头脑清醒,你得把工夫也调配在你未来从事的事件上,你得提前去布局,你得让本人去成长。这里援用股神巴菲特说的一句话:"人生就像滚雪球,最重要之事是发现湿雪和长长的山坡。"。 ...

July 12, 2021 · 1 min · jiezi

关于c++:PapaMelon-2-AB-注意整形溢出

题目链接A+B题解这道题次要是用于相熟 OJ 的输入输出输出的两个整数范畴都在 int32 范畴内,但相加后可不肯定了 :),留神溢出的问题#include <iostream>using namespace std;int main() { int a, b; while (cin >> a >> b) { cout << 0LL + a + b << endl; } return 0;}

July 12, 2021 · 1 min · jiezi

关于c++:EEE102-软件设计

EEE102 Assessment 31EEE102 C++ Programming and Software Engineering IIAssessment 3Assessment Number 3Contribution to Overall Marks 35%Submission Deadline Wednesday, 01-May-2019, 23:59How the work should be submitted?SOFT COPY ONLY !(MUST be submitted through ICE so that the TAs can run your programs during marking.)Make sure your name and ID are printed on the cover page of your report.Assessment OverviewThis assessment aims at testing some basic concepts of C++ programming and initiates the routine ofcode development using the software development process (SDP), namely the five main steps of thesoftware development process: ...

July 12, 2021 · 4 min · jiezi

关于c++:STLvector内部实现原理及基本用法

1.vector类的实现重要构造定义: template<class T>class myVector{public: typedef T value_type;//元素类型 起别名 typedef value_type* pointer;// typedef value_type* iterator;//迭代器 typedef value_type& reference;//援用 typedef const value_type* const_pointer;//常量指针 typedef const value_type& const_reference;//常量援用 typedef size_t size_type;//数据类型根本尺寸大小private: iterator start; iterator finish; iterator end_of_storage;供类外部以及派生类应用: protected://调配空间并填充初始值, 不返回任何值void __allocate_add_fill(size_type n, const T& value){ iterator result = (iterator)malloc(n*sizeof(T)); if (result){//result!=0 申请内存胜利,在失去的内存上创建对象 start = result; end_of_storage = start + n; finish = end_of_storage; while (n--){ //指针偏移,进行赋值 construct(result, value);//在内存上,一个个的进行结构对象 ++result; } } else{ cout << "内存不足,程序终止!" << endl; exit(0); } }//调配空间 从first开始复制n个值到新空间中, 并返回新开拓的空间的首地址 iterator __allocate_and_copy(iterator first, size_type n){ //内存申请 iterator result = (iterator)malloc(n*sizeof(T)); iterator _start = result; if (0 != result){ while(n--){ construct(result, *first); ++result; ++first; } cout << endl; } else{ cout << "内存不足,程序终止!" << endl; exit(0); } return _start; }//将first到last迭代器之间(first,last)的元素拷贝到_start开始的内存中, 并返回 指向 拷贝完所有数据之后最初一个数据的下一个地位的指针 iterator __copy(iterator first, iterator last, iterator _start){ while (first < last){ *_start++ = *first++; } return _start; }//将first到last迭代器之间(first,last)的元素从新赋值iterator __fill(iterator first, iterator last, const T& value){ while (first < last){ *first++ = value; } return first;}//本人写的 从迭代器first开始填充n个值为value的元素iterator __fill_n(iterator first, size_type n, const T& value){ while (n--){ *first++ = value; } return first;}//本人写的 将从 [first,last)所有元素 一一顺次后移, 最初的一个元素移到end的地位void __backCopy(iterator first, iterator last, iterator end){ while (last >= first){ // *end-- = *last--; }}供内部应用的接口: ...

July 11, 2021 · 6 min · jiezi

关于c#:KIT305KIT607

KIT305/KIT607Assignment 2Implementation and Evaluation of a Mobile ApplicationJournal and Mood Tracking ApplicationDue DateThe assignment has three assessable components: The application code (worth 50%; pair-based work), due on Monday 20th May 2019 23:55 (week 12).A report (worth 40%; pair-based work), due on Monday 27th May 2019 23:55 (week 13).A demonstration (worth 10%; pair-based work), due in your scheduled tutorial (week 13).BackgroundIn assignment 1, your task was to design and prototype a native mobile application that allowed a user to create andmodify journal entries and track their mood.Your task for this assignment 2 is to now implement and evaluate a mobile Android or iOS application that providesthe functionality. An updated list of requirements and additional requirements is provided in this document.In the week 7 tutorial and in your own time, you will evaluate your different prototypes from assignment 1, todetermine which ones meet the usability goals discussed in this unit, and which should form the basis of yourassignment 2 code. Note that you are not required to match all of the functionality or visual style from assignment 1,but you should aim for some similarity between your assignment 1 and assignment 2 work. Functionality fromassignment 1 which is not specified in the “Code” section of this document is not required to be complete (forexample, if your assignment 1 featured a login page, you are not expected to make this function, but you areencouraged to include a non-functional version of this in the app if you have time).The goal of this assignment is to assess your ability to implement and evaluate mobile applications, and todemonstrate your understanding of the fundamentals of mobile device programming when applied to a practicalcontext.Group WorkThis is a pair-based assignment. Group members will need to agree on a target mobile OS (Android or iOS), and - aftersome usability think-aloud testing of the available prototypes – agree on the design that is to be implemented in code.You MUST have a partner chosen by your week 7 tutorial. If you have difficulties finding a partner, use thediscussion board on MyLO, and speak to other students looking for partners. You will be assigned to a group in week7.Use the following link to register your group (only one group member needs to do this):https://forms.gle/srcK1HwaHD6...Changes to group members MUST be approved by the Unit Coordinator. Late changes may not be approved.Group members should contribute equally to ALL components of the assignment (report, code, demonstration). Thisassignment will be subject to peer assessment, further details will be provided on MyLO. Code (50%)When you create your application, please use the following bundle identifier:au.edu.utas.username.assignment2(replace username with the username of one of the group members)The Android or iOS application that you are to implement must consist of at least:A way of entering a new journal entry and saving it.o At a minimum, journals should consist of a title, text, and a date of when the journal entry is saved. Extra meta-data such as location or tagged friends is not required to function correctly. Storing an image is considered an additional requirement (see below), not a core requirementfor this assignment.A way of showing a user’s past journal entries, and seeing more information about them.A way of editing and deleting previous journal entries.A way of selecting a current mood (this can be separate to creating journal entries or integrated into creating ajournal entry).A way of seeing how a user’s mood has changed in the past.o As a core requirement, this needs only to list past moods. Displaying a graph is considered anadditional requirement (see below).Data entered by the user should persist between runs of the application. You can use any data persistence methodtaught in this unit to accomplish this (e.g. SQLite, file writing, or SharedPreferences/UserPreferences). You should not“pre-fill” the database with user-entered information (such as existing journal entries), as the application shouldfunction (not crash) when the user has just opened the application for the first time. Remember that any testing datayou enter while developing your application will not be visible to your marker, as they will be installing a freshversion of your application on their emulator.An important feature of your application will be its usability, i.e. learnable, memorable, efficient, failure-resistant,forgiving, and satisfying. For the purpose of this assignment, particular emphasis will be placed on the “efficiency”aspect of usability. This means that if users choose to, they can create a short journal entry quickly, without too manyadditional steps.Aside from checking for functionality, your program will be assessed on its robustness (i.e. does the applicationcrash), usability, and aesthetics. You will not be assessed on your coding style, commenting, or indentation, howevergiven the scale of this application, you are advised to do this to assist in development.Remember to leave enough time to test your application on the School Mac computers. There may be some problemswhen you transfer a project from a personal laptop, so you need to leave enough time to solve these.When transferring an Android Studio project between computers, use the File -> Export to Zip… option to avoid errors.Additional requirementsTo gain higher marks, additional functionality should be added based upon the list below. Use the CRA below towork out how many marks you will get for completing these additional requirements.The user can store an image in their journal by taking a picture using the phone.The user can share a journal entry to another application (such as email, chat program). The shared data,should just be a plain-text version of the journal entry (you do not need to implement user accounts or a server forthis, see the lecture slides for information on sharing).The history of the user’s mood over time is shown using a graph.o You are allowed to use a 3rd-party plugin for drawing a graph for this part of the assignment (as longas you cite the author).If your assignment 1 prototype doesn’t include functionality for these requirements, you can still implement this byadding this to your application.Check the CRA at the end of this document to see the weighting of each component.Report (40%)You will have been reading many articles throughout the semester that report on the design, iterative refinement, andevaluation of new mobile and ubiquitous computing applications. Your readings have also been complemented byarticles on interaction design and discount usability methods. Accompanying the implementation of your applicationwill be a report outlining how you were able to apply the process of usability testing (and specifically think-aloudevaluation) to iteratively improve the design and usability of your application.You must write a report that is up to six (6) pages long (single-spaced, 10pt Times font). This page count includes figuresand tables, but excludes references.Your report should include the following sections:Introduction;Description of Application (including selected screenshots of lo-fi prototype and final application);(Usability) Methodology;Results;Discussion;Conclusions; andReferences.The Methodology section will outline the usability testing that was employed. It will also include details on how thetesting was conducted, including a description of the user participants and the test-tasks that were chosen for thethink-aloud evaluation (with a table showing tasks in rows and requirements in columns; see week 02 lecture). It isexpected that for a HD-level assignment, that you conduct iterative testing across at least three different prototypes.Check the CRA for what is required.The Results section will report the results of the usability testing. You should present a table of results, however onlysimple summary statistics are necessary; you are NOT expected to conduct accurate statistical analysis such as t-Tests,ANOVAs, or correlation). The purpose of this section is to show that you understand the testing process and haveconducted testing, not to get perfect usability scores. You will not be assessed on whether or not your results werepositive or not.The Discussion section will provide a self-assessment critique of performance on all of the above criteria, and willinclude a summary of the strengths and weaknesses of the application. You should refer to your results section toback up your statements with data.The report will also reference the set readings, lecture slides, and other literature and resources as appropriate tojustify decisions and provide background information. Demonstration (10%)In addition, you are required to demonstrate your application during the week 13 tutorial timeslot. Thedemonstrations will be limited to four (4) minutes total. All group members must participate in the demonstrations,and the 4-minute timeslots will be strictly enforced to ensure that all presentations are completed within the tutorialsession. The group demonstrations will need to:State the goals of the work for a broad public;Outline the design and testing that was conducted;Provide a convincing example of how a person would use the prototype (using either the emulator, a series ofscreenshots, or a physical device); andProvide convincing evidence that the application meets its goals.You may choose to create a PowerPoint presentation, but this is not necessary. You choose how to best communicatethe information above.If you choose to use a physical device for your demonstration, you must ensure you have tested your applicationthoroughly on the device prior to the demonstration. There will be no time during the tutorial to deploy to the device,you must do that at well before your allocated time.Assignment SubmissionThe following files must be submitted via MyLO before 23:55 on Monday 20th May (Week 12):One zip file, containing the project files. The zip filename should start with your UTAS account name (eithermembers’ name is fine).o For Android, you should create this ZIP file using the File -> Export to Zip option. Submit the ZIP filewhich is created.o For iOS, you need to find your .xcodeproj file and project folder in Finder, select them both, right-clickand choose “Compress”. Submit the ZIP file which is created.A group assignment coversheet (available from the ICT website):http://www.utas.edu.au/__data...The following files must be submitted via MyLO before 23:55 on Monday 27th May (Week 13):The group report, in PDF format, with a filename that starts with your UTAS account name (either members’name is fine).A group assignment coversheet (available from the ICT website):http://www.utas.edu.au/__data...Only one group member needs to submit these deliverables.Peer assessment submission items are to be announced on MyLO, and will be due in Week 13.Make sure to test your application on the University Mac machines in UC215 before submitting your assignment.Unzip your application to the desktop of a lab machine you haven’t used before. Test that application opens andcompiles in Android Studio/XCode, and runs in the emulator. Android applications will be tested using a Nexus 5Xemulator. iOS applications will be tested on an iPhone X simulator. (If you have errors attempting to run your project,be sure to try Build -> Clean Project, and running again). Plagiarism and Cheating:Practical assignments are used by the Discipline of ICT for students to both reinforce and demonstrate theirunderstanding of material which has been presented in class. They have a role both for assessment and for learning. Itis a requirement that work you hand in for assessment is your own.Working with othersOne effective way to grasp principles and concepts is to discuss the issues with your peers and/or friends. You areencouraged to do this. We also encourage you to discuss aspects of practical assignments with others. However, onceyou have clarified the principles of the problem, you must develop a solution entirely by yourself in your pair. Inother words; you and your partner must develop the application yourselves. You can discuss problems, but not sharesolutions. Assistance with solutions should be provided by staff.Cheating Cheating occurs if you claim work as your own when it is substantially the work of someone else.o This includes the use of third-party code from online resources. Cheating is an offence under the Ordinance of Student Discipline within the University. Furthermore, the ICTprofession has ethical standards in which cheating has no place. Cheating involves two or more parties.o If you allow written work, computer listings, or electronic versions of your code to be viewed,borrowed or copied by another student you are an equal partner in the act of cheating.o You should be careful to ensure that your work is not left in a situation where it may be used/stolenby others.Where there is a reasonable cause to believe that a case of cheating has occurred, this will be brought to the attentionof the unit lecturer. If the lecturer considers that there is evidence of cheating, then no marks will be given to any ofthe students involved and the case will be referred to the Head of Discipline for consideration of further action.Note: You are allowed to use a 3rd-party plugin for drawing a graph for the “mood tracking graph” part of thisassignment, and you may use the built-in SQLite implementation provided in tutorials. You may not use any other3rd-party plugin for any other part of this assignment.KIT305/KIT607 Assignment 2, Semester 1, 2019: Implementation and Evaluation of a Mobile ApplicationCriterion High Distinction (HD) Distinction (DN) Credit (CR) Pass (PP) Fail (NN)Code (50%; ILO2)Students are to produce a journal and mood trackingapplicationFunctionality – Journal List (30%):The application should have a way of showing auser’s past journal entries, and seeing moreinformation about them.The application should have a way of editing anddeleting previous journal entries.A custom layout/view for each entry is used,showing appropriate detail for a summaryscreen.The user can delete entries from the journal.The user can modify entries in the journalwithout needing to delete and re-add the items.The user can see more detail about a journalentry by navigating to a journal page andsensible choices were made for this.The interface for this part is highly intuitive;provides a consistent look and feel and usageacross all screens and is aesthetically pleasing.Application never crashes and has been testedthoroughly to avoid the existence of bugs.The journal can be filtered or searched in someway.A custom layout/view for each entry isused, showing appropriate detail for asummary screen.The user can delete entries from thejournal.The user can see the quantity required foreach item.The user can modify items in the listwithout needing to delete and re-add theitems.The user can see more detail about ajournal entry by navigating to a journalpage and sensible choices were made forthis.The interface for this part is intuitive andaesthetically pleasing.Application never crashes. There are onlyvery minor bugs (if any).A custom layout/view for each entry isused, showing details of each journalentry.The user can delete entries from thejournal.The user can see more detail about ajournal entry by navigating to a journalpage.The interface for this part is somewhatintuitive.There are only some bugs (if any) in theapplication and/or very rarely crashes.The title of each journalentry is listed.The user can deleteentries from the journal.A basic list view isprovided.The user can see moredetail about a journalentry by navigating to ajournal page.There are only somebugs (if any) in theapplication and/or rarelycrashes.The application does notcompile OR crashes onstart-up OR crashesfrequently.The user is unable to viewall journal entries or isunable to delete items.Functionality – Add Entry (15%):The application should have a way of entering anew journal entry and saving it.At a minimum, journals should consist of atitle, text, and a date of when the journal entryis saved.Users can add journal entries with a title, text,date, and sensibly-chosen additional metadata.The interface for this part is intuitive andaesthetically pleasing.Users can add journal entries with a title,text, and a custom date, and additionalmeta-data.The interface for this part is intuitive andaesthetically pleasing.Users can add journal entries with a title,text, and a custom date and time.The interface for this part is somewhatintuitive.There are only a few bugs (if any) in thispart of the app.Users can add journalentries with a title, text,and the current dateand time.There are only a fewbugs (if any) in this partof the app.The application does notcontain functionality to addjournal entries.Crashes prevent the userfrom adding journalentries.Functionality – Mood Tracking (15%):The application should have a way of selecting acurrent mood (this can be separate to creatingjournal entries or integrated into creating a journalentry).The application should have a way of seeing howa user’s mood has changed in the past.Users can enter their mood without having tocreate a journal entry. Users can select acustom mood (if appropriate to design of app).Users are able to see a history of their moods.Sensible choices are made for this display.The interface for this part is intuitive andaesthetically pleasing.Users can enter their mood without havingto create a journal entry.Users are able to see a history of theirmoods.The interface for this part is intuitive.Users can enter their mood without havingto create a journal entry.Users are able to see a history of theirmoods.The interface for this part is somewhatintuitive.There are only a few bugs (if any) in thispart of the app.Users can select amood when creating ajournal entry.There are only a fewbugs (if any) in thisscreen.The application providesno functionality forentering a mood, orcrashes prevent this partof the assignment beingassessed.Functionality – Data Persistence (15%):Data entered by the user should persist betweenruns of the application. You can use any datapersistence method taught in this unit toaccomplish this (e.g. SQLite, file writing, orSharedPreferences/UserPreferences).All data entered by the user persists betweenruns of the application.There are no noticeable bugs with thepersistence.The application functions when there is no datain the database.All data entered by the user persists between runs of the application.There are only some bugs (if any) with the persistence.The application functions when there is no data in the database.Most data entered bythe user persistsbetween runs of theapplication.There are only somebugs (if any) wheresome data does notsave.The applicationfunctions when there isno data in the database.Data does not persistwhen the application isclosed and re-opened. Usability - Efficiency (5%):The application should make it easy for user toquickly create short journal entries.The interface provides well-thought outfunctionality for making creation of journalentries a quick process.Basic functionality for making the creation of journal entries quickly is provided.There are no noticeable bugs with this implementation.Basic functionality formaking the creation ofjournal entries quickly isprovided.There are only somebugs with thisimplementation.The application does nothave any design decisionsthat make creating ajournal entry a quickprocess.Additional Functionality – Camera (10%):The application should allow the user to addimages to their journal entries.The application allows you to choose a photofrom the phone’s image gallery or camera andadd it to a journal entry.The image is displayed on the screen after theuser selected the image and throughout therest of the app.The image is saved to the database (either fileURL or image data is fine).There are no bugs with the camerafunctionality.The application allows you to choose a photo from the phone’s image gallery or cameraand add it to a journal entry.The image is displayed on the screen after the user selected the image and throughoutthe rest of the app.The image is saved to the database (either file URL or image data is fine).The application allowsyou to choose a photofrom the phone’s imagegallery or camera andadd it to a journal entry.The image is displayedon the screen after theuser selected theimage, but the imagedoes not persist onconsecutive runs.The application featuresno camera functionality orthe camera functionalitycrashes the app whentriggered.Additional Functionality – Sharing (5%):The application should allow the user to sharea journal entry to another application on thephone (such as email, chat program).The application allows you to use the OS’ builtinsharing functionality to share a text version ofa journal entry with all details (title, text, date,mood).Bonus (difficult): The user can share the text,AND image attached to the journal entry.The application allows you to use the OS’ built-in sharing functionality to share a textversion of a journal entry with most details.The application allowsyou to use the OS’ builtinsharing functionalityto share the title of thejournal entry.The application featuresno sharing functionality orthe sharing functionalitycrashes the app whentriggered.Additional Functionality – Mood Graph (5%):The application should display a graph toshowing the history of the user’s mood.The application shows a visually pleasing graphwhich uses data from the database (or otherdata persistence method).The graph can be filtered by different timeperiods.There are only a few bugs (if any) with thegraph functionality.The application shows a simple graphwhich uses data from the database (orother data persistence method).The graph can be filtered by different timeperiods.There are only some bugs (if any) with thegraph functionality.The application shows a simple graphwhich uses data from the database (orother data persistence method) but doesn’tchange when the user selects differenttime periods (but options still visually existto select a time period).There are only some bugs (if any) with thegraph functionality.The application shows asimple graph (that is notsimply a static image).The graph uses datafrom the database (orother data persistencemethod).The application does notfeature a graph or thegraph crashes the appwhen displayed or a staticimage is shown for thegraph. Report (40%; ILOs 1,3,4)Student is to create a report up to 6 pages long.Description of Application (25%; ILO3)The report will describe the functionality that hasbeen implemented; including images of the low-fiprototype and final application.All core functionality is explained in a concise,and well-written manner.Screenshots are clear and show the corefunctionality of the app.A reasoned description of how the finalapplication and lo-fi prototype differ isprovided.All core functionality is explained in awell-written manner.Screenshots are clear and show the corefunctionality of the app.A description of how the final applicationand lo-fi prototype differ is provided.All core functionality is explained.Screenshots show the core functionalityof the app.Report contains anoverview of thefunctionality and somescreenshots.Fails to provide adescription section.Methodology (25%; ILO4)The report will outline the usability testing thatwas conducted and the procedure in which itwas conducted.The employed usability testing is welldescribedand well founded; and accompaniedby clear usability test tasks and successrequirements.Choice of methodology is well-justified.At least three prototypes are evaluated overmultiple rounds of testing (i.e. iterative testing isconducted).The employed usability testing is welldescribed;and accompanied by clearusability test tasks and successrequirements.At least three prototypes are evaluated.The employed usability testing is welldescribed. ...

July 11, 2021 · 19 min · jiezi

关于c++:C仅根据函数返回值类型不能实现重载

函数的两个因素:参数与返回值。 如果同名函数的参数不同(包含类型、程序不同),那么容易区别出它们是不同的函数。 如果同名函数仅仅是返回值类型不同,有时能够辨别,有时却不能。例如: void Function(void);int Function (void);上述两个函数,第一个没有返回值,第二个的返回值是int 类型。如果这样调用函数:int x = Function (); 则能够判断出Function 是第二个函数。问题是在C++/C 程序中,咱们能够疏忽函数的返回值。在这种状况下,编译器和程序员都不晓得哪个Function 函数被调用。所以只能靠参数而不能靠返回值类型的不同来辨别重载函数。编译器依据参数为每个重载函数产生不同的外部标识符。 void Function(void){};int Function(void){};注:仅仅依据函数返回值不能重载函数,仅能依据不同的形参列表,包含参数个数和类型;仅仅依据参数返回类型编译器会收回谬误正告,在编译期间就提醒谬误

July 11, 2021 · 1 min · jiezi

关于c++:C-Primer-Plus-第01章-预备知识-学习笔记

第一章 准备常识1、C++简介C++交融了3种不同的编程形式: C语言代表的过程性语言C++在C语言根底上增加了类代表的面向对象语言C++模板反对的泛型编程C++继承C语言高效、简洁、疾速和可移植性的传统。 2、C++简史2.1 C语言编程:过程性语言Bell实验室的Dennis Ritchie为了设计开发UNIX的通用性、可移植性等,在旧语言的根底上开发了C语言。 汇编语言依赖于计算机的外部机器语言,间接对硬件进行操作。 数据:程序应用和解决的信息。 算法:程序应用的办法。 C语言是 过程性语言 ,强调编程的算法方面。一种结构化的编程形式。 C语言的新准则:自顶向下设计,现实:将大型程序拆分小型、便于管理的工作。 2.2 面向对象编程过程性语言(C语言)强调算法,OOP(C++、Java等)强调数据 。 OOP不像过程性编程,其理念是设计与问题的实质个性绝对应的数据格式。区别如下: 过程性语言(让问题来满足语言)OOP编程(让语言来满足问题)在C++中,类是一种标准,形容了新型数据格式,对象则依据类标准结构的特定数据结构。 类规定了可应用哪些数据来示意对象以及能够对这些数据执行哪些操作。 OOP程序设计办法:先设计类(能够明确示意程序要解决的货色),而后设计应用类的对象的程序。 从低级组织(如类)到高级组织(如程序)的处理过程叫作 自下而上 的编程思维。 类定义 = 数据 + 办法 OOP能够创立可重用的代码,缩小大量的工作,信息暗藏能够爱护数据,使其免遭不适当的拜访。 不同的环境(Windows和Macintosh)下提供编程的类库,能够不便地重用和批改现有的、通过认真测试的代码。 2.3 C++和泛型编程泛型编程(generic programming)是C++反对的另一种编程模式。与OOP指标零碎。 术语:泛型(指创立独立于类型的代码)。 OOP与泛型编程的区别: OOP强调编程的数据方面,是治理大型项目的工具泛型编程强调独立于特定数据类型,提供执行常见工作(如对数据排序或合并链表)的工具。C++泛型编程须要对语言进行扩大,以便于能够只编写一个泛型(即不是特定类型的)函数,并将其用于各种理论类型。 3、可移植性和规范C++是C语言的超集,任何无效的C程序都是无效的C++程序。 3.1 可移植性的两个阻碍硬件:分块搁置模块,通过重写模块,最大限度升高可移植性问题。语言上的差异性:国内组织定义了C语言规范、定义了C++99、C++11、C++14等规范。3.2 C++的二重性OOP提供了高级形象C提供了低级硬件拜访 C++既能够通过OOP进行形象,也可实现相似C一样的对硬件拜访的操作。 4、程序创立的技巧4.1 编程步骤更多编译细节请浏览【编译原理】 4.2 常见的编译器Linux/UNIX : GNU gcc/g++Windows :软件IDEMac OS : Xcode自带g++和clangGitHub地址:https://github.com/SolerHo/cp...

July 10, 2021 · 1 min · jiezi

关于c++:C-Primer-Plus-第02章-开始学习C-学习笔记

第二章 开始学习C++1. 进入C++/*第一个C++程序*/#include <iostream>using namespace std; /*定义一个可视化*/int main(void){ cout<<"Come up an C++"<<endl; cout<<"You won't regret it"<<endl; return 0;}对于一个C++ 程序次要蕴含以下元素: 正文:由前缀// 或者是 /* */ 标识预处理器编译指令#include函数头:int main() 编译指令:using namespace函数体:用{ } 括起来应用C++ 的cout工具显示音讯的语句完结main()函数的return语句1.1、main()函数头main() 被启动代码调用,而启动代码是编译器增加到程序中。 函数头形容 main() 和OS(UNIX/Linux、Windows、mac os等)间接的接口。空括号的main() 不承受任何参数。 int main(void){ statement return 0;}main()函数形容了函数的行为。同时也形成了两局部的 函数定义(function definition) :第一行int main()函数叫做 函数头(function heading),花括号({和})中包含的局部叫 函数体。 函数体:指出函数应做什么的计算机指令。 在C++中,每条残缺的指令叫做语句。所有的语句都是以 分号完结。 main()中最初一条语句叫做 返回语句(return statement),完结main()函数。 ⚠️留神:C++程序通常是以main() 函数开始执行,如果没有,程序不残缺,则编译器会指出未定义main()函数。 大小写都必须精确 不须要main()函数的非凡状况: Windows中的动静链接(DLL)模块。单片机或机器人芯片1.2、C++正文C++中的正文以 双斜杠(//) 打头。以行尾作为完结。 正文的作用:为程序提供解释阐明,使得程序通俗易懂。 通常标识程序的一部分或者是标识代码的某个方面。 留神点:编译器不会运行,会间接疏忽正文。 C++也能够辨认C语言的正文 C语言格调的正文 多行正文:符号/* 和 */ 之间,以 */ 作为正文的完结。单行正文:以 双斜杠(//) 开始,行尾作为完结。1.3、预处理器和头文件如果程序要应用C++输出或输入工具时,必须应用两行代码: ...

July 10, 2021 · 2 min · jiezi

关于c:C入门6C语言中的常量

Summary1)常量是绝对于变量的一个概念;变量的值随时能够扭转,常量的值是不能够扭转的。 2)C语言中的常量类型包含: 字面量:间接示意值含意的符号,如:5, 'a', "Delphi"宏常量:通过#define定义,间接示意值的符号,如:#define FIVE 5枚举常量:通过enum定义,间接示意值的符号,如:First -> 13)C语言中定义常量的形式: 通过#define定义宏常量通过enum定义枚举常量4)C语言中定义常量的语法: 宏常量:#define NAME Value 示例1: #define MyString"Bryson"示例2:#define MyId 1枚举常量:#define NAME Value 示例: enum { ThirdValue = 333, FourthValue = 444, }5)常量的类型: 字面量有默认类型,如“1”的默认类型为int,"Hello world"的类型为const char*#define定义的宏常量能够是任意类型enum定义的枚举常量只能整形6)C语言中的只读变量 C语言中提供了const关键字,用于润饰一个变量被const润饰的变量只能作为右值应用 无奈间接通过赋值操作符扭转const变量的值const润饰的变量并不是真正意义上的常量C语言中,const润饰变量,看起来像常量,用起来像常量,但实质是只读变量。无奈间接扭转(通过"="进行赋值扭转),但能够间接扭转(用指针取到地址进行扭转)。再次留神,实质是只读变量,占用内存的。如下: const int a = 1;a = 2; // error, assignment of read-only variable 'a'int* p = (int*)&a; // 取地址*p = 2; // 间接批改printf("%d\n", a); // 2另: 在C语言中,gcc编译器下,如上代码中a的值被批改为2。阐明const定义了个只读变量。在C++语言中,g++编译器下,如上代码a的值依然为1。因为C++中const定义的是一个常量!a被放到了符号表中。指针p批改的,实际上是内存中的一段空间,把那段空间的值批改为了2,因而打印a的值为1,*p的值为2。(详见后续C++)本文总结自“狄泰软件学院”唐佐林老师《C语言入门课程》。如有错漏之处,恳请斧正。

July 10, 2021 · 1 min · jiezi

关于c:C入门5程序中的辅助语句

Summary1)C语言中分为单行正文和多行正文:单行正文 以 // 开始的这一行文本,可能不被编译器所反对;多行正文从 /* 到 */之间的所有文本,不反对嵌套; 2)逗号表达式的优先级是最低的;逗号表达式从左向右开始执行语句;逗号表达式的值就是最左边语句的值 3)前置++,先自增,再取值;后置++,先取值,再自增;--运算符同++。++和--运算符的联合方向是从左向右 1、正文C语言中的正文分为“单行正文”和“多行正文”;单行正文:(单行正文可能不被编译器反对)以 **//** 开始的这一行文本多行正文:(多行正文不反对嵌套)从 /* 到 */之间的所有文本 2、逗号表达式逗号(,)是一种非凡的运算符逗号能够将多个语句连接起来变成一条语句语法:语句1,语句2,语句3, ... ,语句n留神: 逗号表达式的优先级是最低的逗号表达式从左向右开始执行语句逗号表达式的值就是最左边语句的值3、自增++与自减--运算符3.1 前置前置++(--):先自增(自减),再取值应用逗号表达式能够示意如下: ++v; <-> (v = v + 1, v)--v; <-> (v = v - 1, v)3.2 后置后置++(--):先取值),再自增(自减)应用逗号表达式能够示意如下: v++; <-> (v = v + 1, v - 1)--v; <-> (v = v - 1, v + 1)本文总结自“狄泰软件学院”唐佐林老师《C语言入门课程》。如有错漏之处,恳请斧正。

July 10, 2021 · 1 min · jiezi

关于c++:C-new和delete运算符

一、前言学习过C语言会晓得,在C语言中,动静分配内存用malloc()函数,开释内存用free()函数。在C++中这2个函数还是能够应用的,然而C++新增了2个关键字:new和delete。new 用来动静分配内存,delete 用来开释内存。咱们能够这样应用: int* p = new int;delete p;或int* pArray= new int[20];delete[] pArray;new 操作符会依据前面的数据类型来推断所需空间的大小。由上可知,应用new调配的内存用delete开释,应用new[]调配的内存用delete[]开释,它们是一一对应的。new申请空间时会多申请4个字节,用于寄存对象的个数,在返回地址时则会向后偏移4个字节,在delete时则会查看内存上对象的个数,依据个数确定调用几次析构函数,这样能力齐全清理所有对象占用的内存,因而对于内置类型若new[],应用delete开释,没有影响;但若是自定义类型,应用delete开释时只会调用一次析构函数,就会存在有对象没有被析构的状况。 new是在自在存储区上分配内存(能够在堆上,也能够在动态存储区上,取决于operator new实现细节,取决与它在哪里为对象调配空间),必须手动开释,否则只能等到程序运行完结由操作系统回收。为了防止内存透露,new 和 delete、new[] 和 delete[] 操作符应该成对呈现,并且不要和C语言中 malloc()、free() 一起混用。在C++中最好应用new和delete治理内存,比C语言的malloc和free多了能够主动调用构造函数和析构函数,这样在程序运行完结时能够开释内存。 二、new、delete和malloc、free的区别1、new和deletenew在操作时,内存通过 operator new 函数被调配,而且会为被调配的内存调用一个或多个构造函数构建对象;new内置了sizeof、类型转换和类型安全检查性能,对于非外部数据类型的对象而言,new 在创立动静对象的同时实现了初始化工作。如果对象有多个构造函数,那么new 的语句也能够有多种形式。如: int *p= new int[100](1);// 创立100 个动静对象的同时赋初值1 delete时,会为将被开释的内存调用一个或多个析构函数,还会通过 operator delete 函数开释内存。 2、malloc和freemalloc的函数原型为 void *malloc(long NumBytes)由原型可知,调用malloc时须要指定分配内存的字节数,胜利调配的话就返回对应的指针,指向被调配的内存块起始地位;否则返回空指针。 free的函数原型为: void free(void *p)将之前用malloc调配的空间还给程序或者操作系统,即对malloc申请的内存空间进行开释。free函数开释的是指针指向的内存(不是开释的指针自身,不会删除指针自身), 其中指针必须指向所开释内存空间的首地址。如果p 不是NULL 指针,那么free 对p间断操作两次就会导致程序运行谬误。 3、本质区别1)malloc/free是C/C++语言的规范库函数,new/delete是C++的运算符2)new能够主动分配内存空间,malloc须要指定申请空间的大小3)对于用户自定义的对象而言,malloc/free无奈满足动静治理对象的要求。因为malloc/free是库函数而不是运算符,不再编译器管制权限之内,不可能把执行构造函数和析构函数的工作强加于malloc/free。 new/delete能够被重载,malloc/free不能够;new/delete底层是基于malloc/free实现的;malloc分配内存之后发现不够,可通过realloc函数对其进行裁减或放大; malloc申请内存时返回内存地址要查看判空,因为申请失败时返回NULL;new不必判断,在内存调配失败时会抛出异样bac_alloc,因而可在new时加上异样解决机制,如: int* p = new(std::nothrow) int[10];为什么还保留了malloc和free?C++程序常常要调用C函数,而C程序 只能用malloc/free治理动态内存。若应用free开释new创立的动静对象,对象会因无奈执行析构函数而导致程序出错。若delete开释malloc申请的动态内存,可能不会出错,但程序的可读性差。

July 10, 2021 · 1 min · jiezi

关于c:C入门4程序中的执行结构

Summary1)程序执行的根本构造包含:程序构造、循环构造、抉择构造 2)if实用于简单逻辑判断,“按片”判断;switch实用于对离散值进行判断,按多个分支判断 3)switch中的var仅能实用于整数值(离散型变量或者值) 4)switch语句中的每个case,个别都要加上break(除非非凡须要),如果不加break,会从以后case始终执行到下一个break,即便var不合乎前面的case条件。 5)循环构造的三要素: 初始化循环变量在循环体中扭转循环变量判断循环条件6)判断质数的办法:[2,x)之间的数没有任何一个整数能够除尽x(x % i == 0),则x为质数 1、抉择构造1.1 if ... else ...if语句用于依据条件抉择执行语句else不能独立存在且总是与离他最近的if相匹配else语句之后能够连贯其余if语句if(condition1){ // statement1}else if(condition2){ // statement2 }else{ // statement3}1.2 switch ... case ...switch是一种更简洁的多分支抉择构造switch的入参var仅能是整数值!须要留神break的应用多个case能够合并在一起,执行雷同的语句 2、循环构造循环构造次要有while循环、for循环、do while循环。在循环中,能够应用break关键字跳出循环;应用continue,终止本次循环,立刻进去下一次循环。 2.1 do ... whiledo是循环的开始,while是循环的完结do...while();能够看做一条语句,所以要以分号完结do...while至多执行一次循环体 2.2 while循环构造的三要素: 初始化循环变量在循环体中扭转循环变量判断循环条件 2.3 forfor循环是一种更简洁的循环构造: int i = 0;int sum = 0;for(i=0; i<=100; i++){ sum += i;}2.4 应用循环判断一个数是否为质数质数x的定义:x只能被1和x整除判断质数的办法:[2,x)之间的数没有任何一个整数能够除尽x(x % i == 0),则x为质数 bool isPrimeNumber(int x){ bool ret = true; int i = 0; for(i=2; i<x; i++) { if(x % i == 0) { ret = false; break; } } return ret;}本文总结自“狄泰软件学院”唐佐林老师《C语言入门课程》。如有错漏之处,恳请斧正。 ...

July 10, 2021 · 1 min · jiezi

关于c++:CSE-230难点分析

CSE 230 Project 4: Pardon the InterruptionLearning Objectives:● Implement an interrupt service routine in a program containing existing functionalityThe TaskIn this project, you will be adding an interrupt service routine (ISR) to an existing program. The program isalready fully functional hexadecimal counter that shows the current counter value on the seven-segmentdisplay. You will use the timer to generate an interrupt every x cycles (where x can be between 100 and 200cycles). Your ISR needs to do the following things: ...

July 10, 2021 · 1 min · jiezi

关于c++:C-STL-multiset容器

一、前言multiset容器和set容器惟一的差异在于:multiset容器容许存储多个值雷同的元素,而set容器中只能存储互不雷同的元素。 multiset容器类模板定义: template < class T, // 存储元素的类型 class Compare = less<T>, // 指定容器外部的排序规定 class Alloc = allocator<T> > // 指定分配器对象的类型> class multiset;multiset 类模板有3个参数,其中后2个参数自带有默认值。在理论应用中,咱们最多只须要应用前2个参数即可,第3个参数不会用到。 二、创立multiset容器multiset 类模板提供的构造函数,和 set 类模板中提供创立 set 容器的构造函数,是完全相同的。因而创立set容器的形式实用于创立multiset容器。具体的办法参考set容器:https://segmentfault.com/a/11... 三、办法办法阐明begin()返回指向容器中第一个(留神,是已排好序的第一个)元素的双向迭代器。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的双向迭代器end()返回指向容器最初一个元素(留神,是已排好序的最初一个)所在位置后一个地位的双向迭代器,通常和 begin() 联合应用。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的双向迭代器rbegin()返回指向最初一个(留神,是已排好序的最初一个)元素的反向双向迭代器。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的反向双向迭代器。rend()返回指向第一个(留神,是已排好序的第一个)元素所在位置前一个地位的反向双向迭代器。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的反向双向迭代器。cbegin()和 begin() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改容器内存储的元素值cend()和 end() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改容器内存储的元素值。crbegin()和 rbegin() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改容器内存储的元素值crend()和 rend() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改容器内存储的元素值find(val)在 multiset 容器中查找值为 val 的元素,如果胜利找到,则返回指向该元素的双向迭代器;反之,则返回和 end() 办法一样的迭代器。另外,如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的双向迭代器lower_bound(val)返回一个指向以后 multiset 容器中第一个小于或等于 val 的元素的双向迭代器。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的双向迭代器upper_bound(val)返回一个指向以后 multiset 容器中第一个大于 val 的元素的迭代器。如果 multiset 容器用 const 限定,则该办法返回的是 const 类型的双向迭代器equal_range(val)该办法返回一个 pair 对象(蕴含 2 个双向迭代器),其中 pair.first 和 lower_bound() 办法的返回值等价,pair.second 和 upper_bound() 办法的返回值等价。也就是说,该办法将返回一个范畴,该范畴中蕴含所有值为 val 的元素empty()若容器为空,则返回 true;否则 falsesize()返回以后 multiset 容器中存有元素的个数max_size()返回 multiset 容器所能包容元素的最大个数,不同的操作系统,其返回值亦不雷同insert()向 multiset 容器中插入元素erase()删除 multiset 容器中存储的指定元素swap()替换 2 个 multiset 容器中存储的所有元素。这意味着,操作的 2 个 multiset 容器的类型必须雷同clear()清空 multiset 容器中所有的元素,即令 multiset 容器的 size() 为 0emplace()在以后 multiset 容器中的指定地位间接结构新元素。其成果和 insert() 一样,但效率更高emplace_hint()实质上和 emplace() 在 multiset 容器中结构新元素的形式是一样的,不同之处在于,使用者必须为该办法提供一个批示新元素生成地位的迭代器,并作为该办法的第一个参数count(val)在以后 multiset 容器中,查找值为 val 的元素的个数,并返回绝对于set容器,count()、find()、lower_bound()、upper_bound()、equal_range()等办法更罕用于multiset容器。 ...

July 10, 2021 · 1 min · jiezi

关于c++:C二维数组按行遍历与按列遍历的速度比较

1.程序:#include<cstdio>#include<cstdlib>#include<sys/time.h>#include<sys/resource.h>// 从进行开始执行到实现所经验的墙上时钟工夫(wall clock)工夫,// 包含其余过程应用的工夫片(time slice)和本过程消耗在阻塞(如期待I/O操作实现)上的工夫// CPU工夫是指过程占用CPU的工夫,过程阻塞的工夫则不会计入CPU工夫void gettime(double *cpu){ struct rusage ru; if(cpu != NULL) { getrusage(RUSAGE_SELF, &ru); *cpu = ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 1e-6; }}int main(int argc,char* argv[]){ int count = 20000; double cpu0,cpu1,cpu2; int* arr = (int*)malloc(sizeof(int) * count * count); int i,j; gettime(&cpu0); // 按行遍历二维数组 for(i=0;i<count;i++) { for(j=0;j<count;j++) { arr[i * count + j]=1; //printf("%d-%d ",i,j); } } // printf("\n"); gettime(&cpu1); // 按列遍历二维数组 for(i=0;i<count;i++) { for(j=0;j<count;j++) { arr[j * count + i]=1; // printf("%d-%d ",j,i); } } // printf("\n"); gettime(&cpu2); printf("按行遍历二维数组CPU时间差:%lf\n",cpu1-cpu0); printf("按列遍历二维数组CPU时间差:%lf\n",cpu2-cpu1); return 0;}测试机器:处理器:Apple M1内存:8g ...

July 9, 2021 · 1 min · jiezi

关于c++:STLemplaceback-和-pushback-的区别

性能问题:在引入右值援用,转移构造函数,转移复制运算符之前,通常应用push_back()向容器中退出一个右值元素(长期对象)的时候,首先会调用构造函数结构这个长期对象,而后须要调用拷贝构造函数将这个长期对象放入容器中。原来的长期变量开释。这样造成的问题是长期变量申请的资源就节约。 引入了右值援用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数。 在这下面有进一步优化的空间就是应用emplace_back(),应用emplace_back()在容器尾部增加一个元素,这个元素原地结构,不须要触发拷贝结构和转移结构。而且调用模式更加简洁,间接依据参数初始化长期对象的成员。 #include <vector>#include <string>#include <iostream>struct President{ std::string name; std::string country; int year; President(std::string p_name, std::string p_country, int p_year) : name(std::move(p_name)), country(std::move(p_country)), year(p_year) { std::cout << "I am being constructed.\n"; } President(const President& other) : name(std::move(other.name)), country(std::move(other.country)), year(other.year) { std::cout << "I am being copy constructed.\n"; } President(President&& other) : name(std::move(other.name)), country(std::move(other.country)), year(other.year) { std::cout << "I am being moved.\n"; } President& operator=(const President& other);};int main(){ std::vector<President> elections; std::cout << "emplace_back:\n"; elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创立 std::vector<President> reElections; std::cout << "\npush_back:\n"; reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936)); std::cout << "\nContents:\n"; for (President const& president: elections) { std::cout << president.name << " was elected president of " << president.country << " in " << president.year << ".\n"; } for (President const& president: reElections) { std::cout << president.name << " was re-elected president of " << president.country << " in " << president.year << ".\n"; }}源码分析:push_back: ...

July 6, 2021 · 2 min · jiezi

关于c++:C-explicit-关键字

隐式类型转换 (构造函数的隐式调用)举例: #include <iostream>using namespace std;class Point {public: int x, y; Point(int x) : x(x) {}};void displayPoint(const Point& p) { cout << "(" << p.x << ")" << endl;}int main(){ displayPoint(1); Point p = 1;}explicit关键字 指定构造函数或转换函数 (C++11起)为显式, 即它不能用于隐式转换和复制初始化.构造函数被explicit润饰后, 就不能再被隐式调用了. 也就是说, 之前的代码, 在Point(int x)前加了explicit润饰, 就无奈通过编译了. //退出explicit关键字后#include <iostream>using namespace std;class Point {public: int x, y; explicit Point(int x) : x(x) {}};void displayPoint(const Point& p) { cout << "(" << p.x << ")" << endl;}int main(){ displayPoint(1); Point p = 1;}Effective C++: ...

July 6, 2021 · 1 min · jiezi

关于c:c语言三子棋游戏每天一个装杯小技巧源码在末尾

三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,绝对两边顺次摆上三个单方棋子,只有将本人的三个棋子走成一条线,对方就算输了。然而,有很多时候会呈现和棋的状况。咱们学习了c语言,当初咱们尝试本人用C语言写一个三子棋小游戏玩玩吧! 三子棋棋盘图案:游戏开始抉择:抉择1:开始游戏抉择0:退出游戏当抉择开始游戏时,你与电脑开始对弈 当咱们抉择的坐标为(2,2) 电脑它抉择的坐标为(1,3)对弈的后果只有3种: 玩家赢:电脑赢:平 局:小伙伴们能够本人去尝试一下啦!!! 看看你与你的电脑谁的棋艺更高!!! 难度级别能够本人调: 棋盘格子的多少能够由本人来定 #define ROW 3 #define COL 3 //这里的行和列有本人来设定源码: kt.c (文件名) #include "game.h" void menu(){ printf("***********************\n"); printf("****1.play 0.exit*****\n"); printf("***********************\n");} void game(){ char ret = 0; char board[ROW][COL] = { 0 }; InitBoard(board, ROW, COL); DisplayBoard(board, ROW, COL); while (1) { PlayerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if (ret != 'C'){ break; } ComputerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if (ret != 'C'){ break; } } if (ret == '*'){ printf("玩家赢\n"); } else if (ret == '#'){ printf("电脑赢\n"); } else{ printf("平局\n"); }} void test(){ int input = 0; srand((unsigned int)time(NULL)); do{ menu(); printf("请抉择:>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("抉择谬误,请从新抉择!\n"); break; } } while (input);} int main(){ test(); return 0;}game.c (文件名) ...

July 5, 2021 · 3 min · jiezi

关于c++:Write-a-program

F. Task(s) Write a program to sort an array of size 10 using both Merge and Quick sort algorithms.Make sure that both algorithms collaborate to sort one dimensional array, i.e. if merge sortis applied on the first part of the array then Quick sort must be applied on the other part asshown in the following figure:Make sure to follow the following rules:a. You are not allowed to apply each algorithm on the entire array.b. If one algorithm applied for one part, then the other algorithm applied to the rest of thearray. For example mergeSort(arr,0,4) then quicksort(arr,5,n-1).c. Make sure that your code works on any input.d. Never use any other sorting algorithms.e. You are only allowed to apply algorithms with O(n) complexity other than Merge andQuick sort.f. Make sure that your final array is sorted after both Merge and Quick sort algorithmsfinish.Sort elements in ascending order using stack, i.e. make the smallest element to be the topelement of the stack. For example, given the stack elements (from bottom to top): 5, 2, 6,9, sort the elements to make the stack elements become (from bottom to top): 9, 6, 5, 2.The only data structure you can use is array-based stack. Given a stack st, use one extrastack, tmpst, to store temporary data.Merge sort Quick sortNot sortedSorteda. Write a C++ program to sort elements in an array-based stack in ascending order.b. Demonstrate the sorting process with given input numbers {25, 10, 15, 20, 30}.Algorithm:pop out the st to a variable tmp until it finishes all elements.while tmpst is not emptyif the top element of tmpst is smaller than tmp,pop out tmpst and push that element onto stpush tmp onto tmpst ……Sample output (Example):Note: implement the Stack class with all necessary functionality.APPENDIX 1MARKING RUBRICSComponent Title Mergesort and Quicksort Percentage(%) 50CriteriaScore and Descriptors Weight(%) Marks(50-40) (40-30) (30-15) (15-10) (10-0)WX:codehelp ...

July 5, 2021 · 2 min · jiezi

关于c++:数据结构-哈希表

数据结构 哈希表 什么是哈希表 Hash表也称散列表,也有间接译作哈希表,Hash表是一种依据关键字值(key - value)而间接进行拜访的数据结构。它基于数组,通过把关键字映射到数组的某个下表来放慢查找速度,然而又和数组、链表、树等数据结构不同,在这些数据结构中查找某个关键字,通常要遍历整个数据结构,也就是O(N)的工夫级,然而对于哈希表来说,只是O(1)的工夫级。留神,这里有个重要的问题就是如何把关键字转换为数组的下标,这个转换的函数称为哈希函数(也称散列函数),转换的过程称为哈希化。个别哈希表都是用来疾速判断一个元素是否呈现在汇合中。图片哈希函数它把一个大范畴的数字哈希(转化)成一个小范畴的数字,这个小范畴的数对应着数组的下标。应用哈希函数向数组插入数据后,这个数组就是哈希表。哈希抵触 链地址法 --(拉链法)这种办法的根本思维是将所有哈希地址为i的元素形成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因此查找、插入和删除次要在同义词链中进行。链地址法实用于常常进行插入和删除的状况。线性探测法长处:易于施行;总是找到一个地位(如果有);当表不是很满时,均匀状况 下的性能十分好。毛病:表的相邻插槽中会造成“集群”或“集群”键;当这些簇填满整个阵列的大部 分时,性能会重大降落,因为探针序列执行的工作实际上是对大部分阵列的穷举搜寻。哈希表的长处能够像数组一样通过下标随机拜访。补救了数组只能通过整数索引拜访的缺点。哈希表的毛病每次存取数据之前要通过散列函数计算对应的散列值,耗费了更多内存。装载因子 是散列表性能的衡量标准之一。因为散列表实际上还是数组,所以能承载的数据是无限的,当哈希表存储的数据超过数组索引的长度时则必然会呈现散列抵触。 常见的三种哈希构造当咱们想应用哈希法来解决问题的时候,咱们个别会抉择如下三种数据结构。数组set(汇合)map(映射)在C++语言中,实现在C++中,set 和 map 别离提供了以下三种数据结构,其底层实现以及优劣如下表所示:图片红黑树是一种均衡二叉搜寻树,所以key值是有序的,但key不能够批改,改变key值会导致整棵树的错乱,所以只能删除和减少。 图片 std::map 和std::multimap的key也是有序的(这个问题也常常作为面试题,考查对语言容器底层的了解)。当咱们要应用汇合来解决哈希问题的时候,优先应用unordered_set,因为它的查问和增删效率是最优的,如果须要汇合是有序的,那么就用set,如果要求不仅有序还要有反复数据的话,那么就用multiset。那么再来看一下map ,在map 是一个key value 的数据结构,map中,对key是有限度,对value没有限度的,因为key的存储形式应用红黑树实现的。总结总结一下,当咱们遇到了要疾速判断一个元素是否呈现汇合里的时候,就要思考哈希法。然而哈希法也是就义了空间换取了工夫,因为咱们要应用额定的数组,set或者是map来存放数据,能力实现疾速的查找。 本文由博客一文多发平台 OpenWrite 公布!

July 4, 2021 · 1 min · jiezi

关于c++:COMP2396

COMP2396Due: 14 April, 2019, 23:55IntroductionThis assignmenttests your skills on writing simple JavaGUI program, using Java graphics andevents.YouneedtowriteapuzzleprogramJavaPuzzle.java,whichallows theusertoselectanimage as a puzzle and the user can then play with the selected images.This assignment will be evaluated on both functionality and program design. You can getpart ofthe full marks if you implement some ofthe features.You are expected to use Java GUI graphics to display the userinterface ofthis assignment.YouarealsorequiredtowriteJavaDocforallnon-privateclassesandnon-privateclassmembers. Programs without JavaDoc will not be marked.Part I Select an ImageWhenJavaPuzzleisexecuted,afilechoosershouldbepresentedtoaskforanimagefile.Part II Display the Image and randomize the imageTheimageisloadedfromtheselectedfileandisdividedintoblocksof80*80pixelsinsize displayed as shown in above figure. The blocks ofthe image are randomized so thatthe user will not see the original image.Ifthe image file fails to load,the program shouldgenerateanerrormessageandasktheusertoselectanotherimagefile.Eachimageblockshouldkeepitsoriginalpositioninformationsothattheoriginalimagecanbereconstructed.Your main UI should contain the following: ...

July 4, 2021 · 3 min · jiezi

关于c++:CCTSCMICC

include <stdio.h>include "tulip.h"include "TSCMI.h"define _CHECK_BUFLEN_DEMAND_RETFALSE(done, total, demand) \do { \ if ((done+demand) > total) \{ \ if (dbg_TSCPrt) \ { \ printf("[%s:%d]EPMS TotalLen not enough. total:%u, demand:%u\n", __FUNCTION__, __LINE__, (WORD32)total, (WORD32)demand); \ } \ return FALSE; \} \} while (0) ifdef LITTLE_ENDIANdefine _GET_NTOH16(ptrbyte) (WORD16)(((((WORD16 )(ptrbyte))>>8) & 0xff) | (((WORD16 )(ptrbyte))<<8))define _GET_NTOH32(ptrbyte) (WORD32)(((((WORD32 )(ptrbyte))>>24) & 0xff) | ((((WORD32 )(ptrbyte))>>8) & 0xff00) | ((((WORD32 )(ptrbyte))<<8) & 0xff0000) | (((WORD32 )(ptrbyte))<<24))define _GET_NTOH64(ptrbyte) (WORD64)(((((WORD64 )(ptrbyte)) & 0xff00000000000000) >> 56) | \ (((*(WORD64 *)(ptrbyte)) & 0x00ff000000000000) >> 40) | \ (((*(WORD64 *)(ptrbyte)) & 0x0000ff0000000000) >> 24) | \ (((*(WORD64 *)(ptrbyte)) & 0x000000ff00000000) >> 8) | \ (((*(WORD64 *)(ptrbyte)) & 0x00000000ff000000) << 8) | \ (((*(WORD64 *)(ptrbyte)) & 0x0000000000ff0000) << 24) | \ (((*(WORD64 *)(ptrbyte)) & 0x000000000000ff00) << 40) | \ (((*(WORD64 *)(ptrbyte)) & 0x00000000000000ff) << 56))define _SET_HTON16(ptrbyte, val) do {((WORD16 )(ptrbyte)) = ((((val)>>8) & 0xff) | ((val)<<8));} while (0)define _SET_HTON32(ptrbyte, val) do {((WORD32 )(ptrbyte)) = ((((val)>>24) & 0xff) | (((val)>>8) & 0xff00) | (((val)<<8) & 0xff0000) | ((val)<<24));} while (0)define _SET_HTON64(ptrbyte, val) do {((WORD64 )(ptrbyte)) = ((((val) & 0xff00000000000000) >> 56) | \ (((val) & 0x00ff000000000000) >> 40) | \ (((val) & 0x0000ff0000000000) >> 24) | \ (((val) & 0x000000ff00000000) >> 8) | \ (((val) & 0x00000000ff000000) << 8) | \ (((val) & 0x0000000000ff0000) << 24) | \ (((val) & 0x000000000000ff00) << 40) | \ (((val) & 0x00000000000000ff) << 56));} while (0)elsedefine _GET_NTOH16(ptrbyte) (WORD16)((WORD16 )(ptrbyte))define _GET_NTOH32(ptrbyte) (WORD32)((WORD32 )(ptrbyte))define _GET_NTOH64(ptrbyte) (WORD64)((WORD64 )(ptrbyte))define _SET_HTON16(ptrbyte, val) do {((WORD16 )(ptrbyte)) = (val);} while (0)define _SET_HTON32(ptrbyte, val) do {((WORD32 )(ptrbyte)) = (val);} while (0)define _SET_HTON64(ptrbyte, val) do {((WORD64 )(ptrbyte)) = (val);} while (0)endififndef MAXdefine MAX(x, y) (((x)>(y))?(x):(y))endififndef MINdefine MIN(x, y) (((x)<(y))?(x):(y))endifBOOLEAN dbg_TSCPrt = FALSE; ...

July 3, 2021 · 21 min · jiezi

关于c++:gdb命令使用

编译程序时须要加上-g,之后能力用gdb进行调试:gcc -g main.c -o main gdb pcefctrl_test进入GDB后,设置执行单条用例的命令:set args --gtest_filter=PcefctrlPolicyDetection.GIVEN_sess_crt_WHEN_build_detection_ruleInfo_THEN_build_detection_RuleInfo_ok执行一组用例集set args --gtest_filter=SetPackage.*gdb中命令: 回车键:反复上一命令 (gdb)help:查看命令帮忙,具体命令查问在gdb中输出help + 命令,简写h (gdb)run:从新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r (gdb)start:单步执行,运行程序,停在第一执行语句 (gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l (gdb)set:设置变量的值 (gdb)next:单步调试(逐过程,函数间接执行),简写n (gdb)step:单步调试(逐语句:跳入自定义函数外部执行),简写s (gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt (gdb)frame:切换函数的栈帧,简写f (gdb)info:查看函数外部局部变量的数值,简写i (gdb)finish:完结以后函数,返回到函数调用点 (gdb)continue:持续运行,简写c (gdb)print:打印值及地址,简写p (gdb)quit:退出gdb,简写q (gdb)break+num:在第num行设置断点,简写b (gdb)info breakpoints:查看以后设置的所有断点 (gdb)delete breakpoints num:删除第num个断点,简写d (gdb)display:追踪查看具体变量值 (gdb)undisplay:勾销追踪察看变量 (gdb)watch:被设置观察点的变量产生批改时,打印显示 (gdb)i watch:显示观察点 (gdb)enable breakpoints:启用断点 (gdb)disable breakpoints:禁用断点 (gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元 (gdb)run argv[1] argv[2]:调试时命令行传参 (gdb)set follow-fork-mode child#Makefile项目管理:抉择跟踪父子过程(fork()) core文件:先用$ ulimit -c 1024 开启core,当程序出错会主动生成core文件。调试时 gdb a.out core

July 3, 2021 · 1 min · jiezi

关于c++:COSC1076

COSC1076Advanced Programming TechniquesAssignment 1Particle FilterWeight: 15% of the final course markDue Date: 11.59 pm, Friday 5 April 2019 (Week 5)Learning Outcomes: This assignment contributes to CLOs: 1, 2, 3, 4, 6Change Log1.3 Added submission instructions Updated code description requirements for Milestone 4 Minor corrections in Background1.2 Updated references to classes Updated notes on Unit Tests to be clearer about the purpose of the sample unit tests. Updated parts of the Task descriptions to be clearer Added Section "Getting Started"1.1 Corrected positions on the worked example. Updated compilation command, removing -c from full code command.1.0 Initial Release1Contents1 Introduction 31.1 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Relevant Lecture/Lab Material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Start-up Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Plagiarism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Background 42.1 Particle Filter Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Worked Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Task 73.1 Milestone 1: Unit Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2 Milestone 2: Particle Filter API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2.1 Particle Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.2 ParticleList Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.3 ParticleFilter Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.2.4 Code Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.5 Code Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.6 Mandatory Requirements and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.3 Milestone 3: Unknown Orientation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.4 Milestone 4: Efficient Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.4.1 Code Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Starter Code 124.1 Running Unit Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124.2 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 Submission Instructions 135.1 Submitting Code Files (.h/.cpp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135.2 Submitting Unit Tests (.maze/.obs/.pos) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1321 Introduction1.1 SummaryIn this assignment you will implement an algorithm known as a Particle Filter, and use it with a simplesimulated 2D robot moving around a room.In this assignment you will: Practice the programming skills covered throughout this course, such as:– Pointers– Dynamic Memory Management– Provided API Correctly Implement a pre-defined API Implement a medium size C++ program Use a prescribed set of C++11/14 language featuresThis assignment is divided into four Milestones: Milestone 1: Writing Unit Tests Milestone 2: Minimum required component for implementing the simple particle filter Milestone 3: Optional component to extend the particle filter for map rotations Milestone 4: Optional component for efficient memory management1.2 Relevant Lecture/Lab MaterialTo complete this assignment, you will requires skills and knowledge from lecture and lab material for Weeks 2 to4 (inclusive). You may find that you will be unable to complete some of the activities until you have completedthe relevant lab work. However, you will be able to commence work on some sections. Thus, do the work youcan initially, and continue to build in new features as you learn the relevant skills.1.3 Start-up CodeOn Canvas you will find starter code to help you get running with the assignment. This code includes: Dummy (empty) code files, for you to implement Unit Testing code, to help you write and run tests on your implementation Example Unit Test cases1.4 Plagiarism!Plagiarism is a very serious offence.A core learning outcomes for this course is for you to: Demonstrate and Adhere to the standards and practiceof Professionalism and Ethics, such as described in the ACS Core Body of Knowledge (CBOK) for ICTProfessionals.The penalty for plagiarised assignments include zero marks for that assignment, or failure for this course.Please keep in mind that RMIT University uses plagiarism detection software to detect plagiarism and that allassignments will be tested using this software. See the RMIT website for more information about the universitypolicies on Plagiarism and Academic Misconduct.32 BackgroundOne challenge in robotics is called localisation. This is the process of the robot figuring out where it is withinsome environment. One algorithm for localising a robot is called a Particle Filter. In this assignment youwill implement a simple particle filter for a robot moving about a simple 2D maze.In this assignment, the simple 2D maze will be represented as a grid of ASCII characters. For example:Aspects of the maze are represented by different symbols:Symbol Meaning. (dot) Empty/Open Space. The robot can enter any open space.= (equal) Wall or Obstacle within the maze. The robot cannot pass obstacles~ (tilda) The edge of the maze. Every maze is always bounded by the edge symbolsEach location in the maze (including the maze edges) is indexed by a cartesian (x,y) co-ordinate. The top-leftcorner of the maze is always the co-ordinate (0,0), the x-coordinate increases right-wards, and the y-coordinateincreases down-wards. For the above maze, the four corners have the following co-ordinates:For the purposes of this assignment we will make two assumptions: ...

July 3, 2021 · 20 min · jiezi

关于c:STM32定时器参数设置TIMPrescalerTIMPeriod

TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器时钟,它设定 TIMx_PSC寄存器的值。可设置范畴为 0 至 65535,实现 1 至 65536 分频。 TIM_Period:定时器周期,理论就是设定主动重载寄存器的值,在事件生成时更新到影子寄存器。可设置范畴为 0 至 65535。 依据定时器时钟的频率,比方时钟的频率是72MHZ,能够了解为一秒钟STM32会本人数72M次,预分频系数就是将频率宰割,比方分频系数是72,则该时钟的频率会变成72MHZ/72=1MHZ,然而在设置的时候要留神,数值应该是72-1。 假设分频系数是72-1,那么频率变成1MHZ,也就意味着STM32在一秒钟会数1M次,即1us数一次。 好了,接下来就是确定预装载值,比方须要定时1ms,因为1ms=1us*1000,那么预装载值就是1000-1;如此类推,在预分频系数确定的状况下,定时的时长就由预装载值确定了。至于要把值减一的起因,预计是计数是从0开始,所以要减一。 原文链接:https://blog.csdn.net/ZIIllII... //对于71MHZ的频率,500ms中断一次,这两个参数设置如下:TIM_Prescaler=7199; //预分频值TIM_Period=4999; //下一个更新事件装入流动的主动重装载寄存器周期的值 //分频7200,用72000000/7200=10000Hz //此时的周期就是1/10000=0.0001s //500ms=0.0001s*5000次 //5000-1=4999次 //即通过4999次零碎的运行,就是500ms

July 3, 2021 · 1 min · jiezi

关于c++:swoole467golangpythoncclinux核心技术底层分析到微服务实战

https://www.bilibili.com/vide...

July 2, 2021 · 1 min · jiezi

关于c++:解讲CCSCI251CSCI851

School of Computing & Information TechnologyCSCI251/CSCI851 Advanced ProgrammingAutumn 2019Assignment 1 (Worth 10%)Due 11:55pm Friday 5th April 2019. (End of Week Five)OverviewThis assignment is to be implemented using procedural programming. The overall program should processanimals through a veterinary (Vet) clinic. This is not supposed to be a sensible simulation of such a clinic,and does not comply with typical operating practices for such centres.General code notesThese are some general rules about what you should and shouldn’t do. ...

June 30, 2021 · 6 min · jiezi

关于c++:在C中你真的会用new吗

摘要:“new”是C++的一个关键字,同时也是操作符。对于new的话题十分多,因为它的确比较复杂,也十分神秘。本文分享自华为云社区《如何编写高效、优雅、可信代码系列(2)——你真的会用new吗》,原文作者:我是一颗大西瓜 。 C++内存治理1. C++内存调配C++中的程序加载到内存后依照代码区、数据区、堆区、栈区进行布局,其中数据区又能够分为自在存储区、全局/动态存储区和常量存储区,各区所长如下: 栈区函数执行的时候,局部变量的存储单元都在栈上创立,函数执行完结后存储单元会主动开释。栈内存调配运算内置于处理器指令集中,效率高,但调配内存容量无限。堆区堆就是new进去的内存块,编译器不论开释,由利用程序控制,new对应delete。如果没开释掉,程序完结后,操作系统会主动回收。自在存储区C中malloc调配的内存块。用free完结生命周期。全局/动态存储区全局变量和动态变量被调配到同一块内存中,定义的时候就会初始化。常量存储区比拟非凡的存储区,寄存常量,不容许批改。堆和栈的区别 治理形式栈由编译器主动治理,堆由程序员管制空间大小32位零碎下,堆内存能够达到4GB,栈有肯定的空间大小碎片治理对于堆,频繁的new/delete必定造成内存空间的不间断,产生大量内存碎片升高程序效率;栈因为遵循先进后出的规定,不会产生空隙成长方向堆是向上成长的,即向着内存地址减少的方向增长;而栈是向着内存地址减小的方向增长的调配形式堆是动态分配的,栈有动态分配和动态调配之分:动态调配由编译器实现,动态分配由alloca函数实现,即便是动态分配,仍然是编译器主动开释调配效率计算机底层提供了栈的反对,调配了专门的寄存器寄存栈的地址,压栈出栈都有专门的指令执行,这决定了栈的效率会比拟高。堆则是由C/C++函数库提供的,机制比较复杂,比方为了调配某个大小的内存须要在堆内存中搜寻可用足够大小的空间,效率比栈要低的多2. new/delete和new []/delete []回收new调配的单个对象内存空间时用delete,回收用new[]调配的一组对象时用delete[]对于内置类型(int/double/float/char/…),因为new[]申请内存时,编译器还会轻轻在内存中保留整数,示意指针数组的个数,所以delete/delete[]都能够正确开释所申请的内存空间倡议在调用new时应用的[],那么调用delete也应用[]3. new的三种状态new operator 罕用的new,语言函数内建,不能重载。调用过程中理论实现的有三件事:为类型对象分配内存;调用构造函数初始化内存对象;返回对象指针如果是在堆上建设对象,间接应用new operator。operator new 一般操作符,能够重载。如果仅仅是分配内存,那么应该调用operator new,但不负责初始化。零碎默认提供的分配器在工夫和空间两方面都存在一些问题:分配器速度较慢,调配小型对象时空间节约重大,重载new/delete有三方面益处:改善效率检测代码中的内存谬误取得内存应用的统计数据C++标准规定,重载的operator new必须是类成员函数或全局函数,全局的operator new重载不应该扭转原有签名,而是间接无缝替换原有版本。全局重载很有侵略性,他人应用你的库无奈应用默认的new,而具体类的重载只会影响本class和其派生类,然而类的operator new函数重载必须申明为static,因为operator new是在类的具体对象被构建进去之前调用的。为了取得2和3的劣势,重载的operator new须要如下函数申明void operator new(size_t, const char file, int line);placement new 定义在库<<new>>中。如果想在一块曾经取得内存里建设对象,那么应该调用placement new。通常状况不倡议应用,但在某些对工夫要求十分高的利用中能够思考,因为抉择适合的构造函数实现对象初始化是一个工夫绝对较长的过程。点击关注,第一工夫理解华为云陈腐技术~

June 30, 2021 · 1 min · jiezi

关于c++:linux-网络编程-socket

1、开发流程图 2、socket中TCP的三次握手建设连贯详解 咱们晓得tcp建设连贯要进行“三次握手”,即替换三个分组。大抵流程如下: 客户端向服务器发送一个SYN J服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1客户端再想服务器发一个确认ACK K+1只有就完了三次握手,然而这个三次握手产生在socket的那几个函数中呢?请看下图: image 图1、socket中发送的TCP三次握手 从图中能够看出,当客户端调用connect时,触发了连贯申请,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连贯申请,即收到SYN J包,调用accept函数接管申请向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手结束,连贯建设。 3、网络字节序与主机字节序 主机字节序就是咱们平时说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保留的程序,这个叫做主机序。援用规范的Big-Endian和Little-Endian的定义如下: a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 网络字节序:4个字节的32 bit值以上面的秩序传输:首先是0~7bit,其次8~15bit,而后16~23bit,最初是24~31bit。这种传输秩序称作大端字节序。因为TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种秩序,因而它又称作网络字节序。字节序,顾名思义字节的程序,就是大于一个字节类型的数据在内存中的寄存程序,一个字节的数据没有程序的问题了。 所以:在将一个地址绑定到socket的时候,请先将主机字节序转换成为网络字节序,而不要假设主机字节序跟网络字节序一样应用的是Big-Endian。因为这个问题曾引发过血案!公司我的项目代码中因为存在这个问题,导致了很多莫名其妙的问题,所以请谨记对主机字节序不要做任何假设,务必将其转化为网络字节序再赋给socket。

June 30, 2021 · 1 min · jiezi

关于c#:C实践笔记3数据类型之间的转换

前言无论是什么语言在开发的过程中,总会遇到不同类型数据之间的转换。C#也不例外,不过C#曾经帮咱们做好了一些转换的办法。 一.罕用的转换类。Encoding BitConverterConvertMarshal 二.数据转换1.byte[] => string 办法1:string str1 = System.Text.Encoding.Default.GetString(byteArray);办法2:string str2 = BitConverter.ToString(byteArray);转换后数据之间会带"-""31-32-33-34-35-36-37-38-39"办法3:string str3 = Convert.ToBase64String(byteArray); 办法4:string str4 = HttpServerUtility.UrlTokenEncode(byteArray);2.string => byte[] 办法1:byte[] byteArray = System.Text.Encoding.Default.GetBytes(str);办法2:byte[] byteArray = new byte[str.Length];for (int i =0;i<str.Length;i++){ byteArray[i] = Convert.ToByte(str[i]);}办法3;byte[] byteArray = Convert.FromBase64String(str);办法4:byte[] byteArray = HttpServerUtility.UrlTokenDecode(str);

June 30, 2021 · 1 min · jiezi

关于c++:C内存管理18总结从最基础到最复杂

整顿于侯捷老师 《C++内存管理机制-从高山到万丈高楼》 视频内容 文档《C++内存管理机制-从高山到万丈高楼》pdf(来源于网络,非常感激) 测试环境ubuntu-18.4.3Qt 5.13.1Dev 5.11其余阐明免费视频来源于b站,可自行搜寻,C++内存管理机制-从高山到万丈高楼 课程简介内存是电脑中的“脑”吗?CPU才是脑,CPU才是计算机中的三魂六魄。但若没有内存,所有只存在于扑朔迷离间,等同于不存在。 内存已经是贵重也最低廉的周边资源,古代程序员无奈设想 Dos 时代对内存的斤斤计较。 俱往矣,且看今朝。咱们(仿佛)有用不完的便宜内存。但表象之下是操作系统和规范库做了大量工作。而如果你开发内存高耗软件,或处于内存受限环境下(例如嵌入式零碎),就有必要粗浅理解操作系统和规范库为你所作的内存寸治理,甚至须要自行治理内存。 课程分为6讲: 第一讲:PrimitivesC++ 语言中于内存相干的所有根底组件(constructs),包含 malloc/free, new/delete, operator new/operator delete, placement new/placement delete, 我将探讨他们的意义、使用形式和重载形式。并以此开发一个小型内存池(memory pool)。 Overview内存调配的每个层面四个根本层面的用法根本构件之一 new/delete expressions根本构件之二 array new/delete根本构件之三 placement new/delete根本构建之调配流程根本构建之重载Per-class allocatorPer-class allocatorCommon static allocator (第三版)Macro allocator(第四版)GNU C++ allocator(第五版)杂项探讨[以上章节在博客中进行了局部合并整顿]第二讲:std::allocator规范库的衰亡,意味着咱们能够解脱内存治理的重复琐碎,间接应用容器。然而容器背地的分配器(allocator)攸关容器的速度能效和空间能效。我将比拟 Visual C++, Borland C++, GUN C++ 规范库中的 allocator, 并深入探讨其中最精美的 GNU C++ allocator 的设计。 内存块布局VC6 allocatorBC5 allocatorGNU allocatorGNU allocator 行为分析GNU allocator 源码分析GNU allocator 探讨GNU allocator 监督GNU allocator 移植到 C 语言[以上章节在博客中进行了局部合并整顿]第三讲:malloc/freemalloc/free 是所有内存管理手段的最初一里;通过它才和操作系统搭上线。当然你也能够间接调用 system API, 但不倡议。因而了解 malloc/free 的外部治理至为重要。我将以 Visual C++ 的 CRT (C RunTime Library)所带的 malloc/free 源代码为根底,深度摸索这最根底最要害的内存调配于开释函数。 ...

June 29, 2021 · 1 min · jiezi

关于c++:带你掌握C中三种类成员初始化方式

摘要:在C++11之后,申明时初始化->初始化列表->构造函数初始化。本文分享自华为云社区《如何编写高效、优雅、可信代码系列(3)——类成员初始化的三种形式》,原文作者:我是一颗大西瓜。 首先,先得理解一下C++反对哪几种类成员初始化的形式,你罕用的又是哪一种。 初始化形式一:初始化列表class A{public: int a; // 初始化列表 A(int a_):a(a_){}};初始化形式二:构造函数初始化class A{public: int a; // 初始化列表 A(int a_, bool b) { a = a_; }};初始化形式三:申明时初始化(也称就地初始化,c++11后反对)class A{public: int a = 1; // 申明时初始化 A() {}};在C++98中,反对了在类申明中应用等号“=”加初始值的形式,来初始化类中动态成员常量。这种申明形式咱们也称之为“就地”申明。就地申明在代码编写时十分便当,不过C++98对类中就地申明的要求却十分高。如果动态成员不满足常量性,则不能够就地申明,而且即便常量的动态成员也只能是整型或者枚举型能力就地初始化。而非动态成员变量的初始化则必须在构造函数中进行。比方,如下代码在c++98中编译 class Init{public: Init(): a(0) [] Init(int d): a(d) {}private: int a; const static int b = 0; int c = 1; // member, cannot pass build static int d = 0; // member, cannot pass build static const double e = 1.3; // not int or enum type, cannot pass build stati const char* const f = "e"; // not int or enum type, cannot pass build}这十分不不便,所以在C++11中,规范容许非动态成员变量的初始化有多种形式。具体而言,除了初始化列表外,在C++11中,规范还容许应用等号= 或者 花括号{} 进行就地的非动态成员变量初始化。 ...

June 29, 2021 · 1 min · jiezi

关于c:JIT原理简单介绍

JIT = just in time ,简略来说就是在运行时动静编译。一个程序在它运行的时候创立并且运行了全新的代码,而并非那些最后作为这个程序的一部分保留在硬盘上的固有的代码。其实蕴含两个概念,一个是动静生成代码,再一个是动静运行代码。 咱们都晓得,计算机运行的都是机器码,而汇编语言的全称应该是“机器码注记语言”,每一条汇编都对应一串机器码。而JIT的原理就是在内存中生成和运行一段代码。 生成的过程,是编译器干的,当然手动也是能够的,而在内存中运行一段代码,则是依赖操作系统提供的mmap syscall来实现的。 比方,上面是一个求和的机器码 //求和函数long add(long num) { return num + 2; }//对应机器码0x55,0x48,0x89,0xe5,0x48,0x89,0x7d,0xf8,0x48,0x8b,0x45,0xf8,, 0x83, 0xc0, 0x02,0x5d,0xc3动静地在内存上创立函数之前,咱们须要在内存上调配空间。具体到模仿动态创建函数,其实就是将对应的机器码映射到内存空间中。这里咱们应用c语言,利用 mmap函数来实现这一点。而mmap函数的底层就是对操作系统mmap syscall的一个封装。 头文件:#include <unistd.h> #include <sys/mman.h>定义函数:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize);参数阐明:参数 阐明start 指向欲对应的内存起始地址,通常设为NULL,代表让零碎主动选定地址,对应胜利后该地址会返回。length 代表将文件中多大的局部对应到内存。其中,prot 代表映射区域的保护方式,有下列组合 PROT_EXEC 映射区域可被执行; PROT_READ 映射区域可被读取; PROT_WRITE 映射区域可被写入;参数flags:影响映射区域的各种个性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE咱们须要这块代码可读可执行,所以咱们能够这样来创立一块空间 #include <stdio.h> #include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/mman.h>//分配内存void* createSpace(size_t size) { void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); return ptr;}咱们能够试试把“可执行”PROT_EXEC权限去掉,看看后果如何。 ...

June 29, 2021 · 2 min · jiezi

关于c++:编程语言C-四种强制类型转换

一、const_cast1、常量指针被转化成十分量的指针,并且依然指向原来的对象; 2、常量援用被转换成十分量的援用,并且依然指向原来的对象; 3、const_cast个别用于批改指针。如const char *p模式。 #include<iostream>int main() { // 原始数组 int ary[4] = { 1,2,3,4 }; // 打印数据 for (int i = 0; i < 4; i++) std::cout << ary[i] << "\t"; std::cout << std::endl; // 常量化数组指针 const int*c_ptr = ary; //c_ptr[1] = 233; //error // 通过const_cast<Ty> 去常量 int *ptr = const_cast<int*>(c_ptr); // 批改数据 for (int i = 0; i < 4; i++) ptr[i] += 1; //pass // 打印批改后的数据 for (int i = 0; i < 4; i++) std::cout << ary[i] << "\t"; std::cout << std::endl; return 0;}out print: ...

June 28, 2021 · 3 min · jiezi

关于c++:CSCI-2132-Software-Development

Assignment 7CSCI 2132: Software DevelopmentDue April 8, 2019Assignments are due on the due date before 23:59. All assignments must be submitted electronically via the course SVNserver. Plagiarism in assignment answers will not be tolerated. By submitting your answers to this assignment, you declarethat your answers are your original work and that you did not use any sources for its preparation other than the class notes,the textbook, and ones explicitly acknowledged in your answers. Any suspected act of plagiarism will be reported to theFaculty’s Academic Integrity Officer and possibly to the Senate Discipline Committee. The penalty for academic dishonestymay range from failing the course to expulsion from the university, in accordance with Dalhousie University’s regulationsregarding academic integrity.General Instructions: How to Submit Your WorkYou must submit your assignment answers electronically: Change into your subversion directory on bluenose: cd ~/csci2132/svn/CSID . Create a directory a7 for the current assignment. Change into your assignment directory: cd a7 . Create files inside the a7 directory as instructed in the questions below and put them underSubversion control using svn add <filename> . Only add the files you are asked to add! Once you are done answering all questions in the assignment (or the ones that you are able toanswer—hopefully all), the contents of your a7 directory should look like this:a7permutations.clinked_list.clinked_list.hnode_pool.cnode_pool.hstringset.c(You will also have executable programs and potentially some data files in this directory, but youshould not add them to SVN.) Submit your work using svn commit -m"Submit Assignment 7" .1(Q1) RecursionConsider the sequence of the first n positive integers, ?1,2, . . . , n?. A permutation of this sequence isany sequence that contains each of the numbers 1, 2, . . . , n exactly once. So, ?3, 4, 2,is a permutation of 1, 2, 3, 4 but 1, 3, 2, 3 and 1, 5, 3, 2 are not.A permutation x1 is lexicographically less than another permutation y1 yn if andonly if there exists an index 1 ≤ k ≤ n such that xi = yifor all 1 ≤ i < k and xk < yk.So,2, 1, 3, 4 is lexicographically less than 2, 3, 1, 4 because x1 = y1 = 2 and x2 = 1 < y2 = 3. If theelements in the sequence were letters rather than integers, you could interpret the sequence of lettersas a word and the ordering defined here would simply be the one in which the words would occur in adictionary.Your task is to write a C program permutations that takes a command line argument n and outputsall permutations of the sequence ?1,2, . . . , n? in lexicographic order. The output should consist ofn! lines, each containing one permutation. The numbers in each permutation must be printed inorder, separated by exactly one space between each pair of consecutive numbers. Thus, when runningpermutations 3, you should see the following output on your screen:$ ./permutations 31 2 31 3 22 1 32 3 13 1 23 2 1permutations 4 should produce$ ./permutations 41 2 3 41 2 4 31 3 2 41 3 4 21 4 2 31 4 3 22 1 3 42 1 4 32 3 1 42 3 4 12 4 1 32 4 3 13 1 2 43 1 4 223 2 1 43 2 4 13 4 1 23 4 2 14 1 2 34 1 3 24 2 1 34 2 3 14 3 1 24 3 2 1As the title of the question suggests, recursion is a natural strategy to implement this program. Youshould not have to generate the permutations and then sort them. Your code should be able to generatethe permutations in the desired order.The basic strategy is fairly simple: Your top-level invocation of the function that generates the permutationshould iterate over all possible choices of the first element in the permutation, from smallestto largest. For each such choice, you make a recursive call that generates all permutations of theremaining n 1 elements. How do you do this? You iterate over all possible choices for the secondelement, from smallest to largest and, for each such choice, make a recursive call that generates allpermutations of the remaining n?2 elements, and so on. The deepest recursive call is asked to generatea permutation of 0 elements, that is, you have already chosen all n elements in the permutation. Thisis the point at which you print the current permutation.One issue you will have to deal with is how to keep track of the elements that can still be chosen asthe second, third, fourth, . . . element in the permutationu after choosing the first one, two, three, . . .elements in the permutation. One easy way to do this is to initialize an array of size n that containsall the numbers from 1 to n. Whenever you choose an element from this array, you set its entry to 0and, in subsequent recursive calls, you skip elements that are 0 because they were already chosen.Don’t forget to restore each number x in this array of candidates when it is no longer part of the set ofelements currently chosen as part of the permutation. This is not the most efficient way to do this, butefficiency is not your main concern in this question.Implement your program in a single source file permutations.c. Do not submit the executable fileobtained by compiling it. However, you should obviously compile and test your code.3(Q2) Structs, unions, and dynamic memory managementThe ability to allocate and deallocate memory on the heap at arbitrary times is key to writing flexibleprograms, but every allocation or deallocation has an associated cost because the runtime system oroperating system needs to perform a certain amount of bookkeeping to keep track of which memorylocations on the heap are currently occupied and which ones are available for future allocation requests.As a result, in programs that create and destroy many small objects on the heap, the cost of heapmanagement may become the main performance bottleneck. This is the case in object-oriented programsthat manipulate complex collections of small objects and in the implementation of pointer-based datastructures such as linked lists and binary search trees, where a na?ve implementation represents eachlist or tree node as a separately allocated block on the heap.A common technique to improve the performance of such programs substantially is to allocate largerchunks of memory at a time, large enough to hold hundreds or thousands of the manipulated objects(e.g., a chunk that is big enough to hold 1000 list nodes in a linked list implementation). Your codethen has to manually track which of the slots in this large memory chunk are occupied or not, but thisis a much simpler problem that can be solved much more efficiently than general heap management.The data structure that manages the allocation of individual list nodes from this array of list nodes isoften referred to as a “node pool”.Here, your task is to implement a linked list that uses a node pool to efficiently manage the memoryoccupied by its nodes. As an application, you will use the same test program as in Lab 8, which needsa data structure to store a collection of strings. In Lab 8, you implement this collection as a splay treein order to guarantee fast searches. Here, you do not worry about the speed of searching the datastructure, only about the cost of heap management, so a linked list suffices as the data structure tostore the collection of strings.1Develop your code for this question in four steps: ...

June 28, 2021 · 16 min · jiezi

关于c++:C内存管理18补充

谈谈 const当成员函数的 const 和 no-const 版本同时存在, const object 只会(只能)调用 const 版本, non-const object 只会(只能)调用 non-const 版本是否可被调用const object(data members 不得变动)non-const object(data members 可变动)const member functions(保障不更改data members)√√non-const member functions(不保障 data members 不变)×√const String str("hello word");str.printf();如果当初设计 String::printf() 时未指明 const, 那么以上代码将是经由 const object 调用 non-const member function, 编译时会报错(并非咱们所愿)class template std::basic_string<...> 有如下两个 member funcionscharT operator[](size_type pos) const{ ... /* 不用思考 COW */ }reference operation[](size_type pos){ ... /* 必须思考 COW */ }COW: Copy On Write (援用技术数据共享机制) ...

June 27, 2021 · 1 min · jiezi

关于c:C入门程序中的运算

Summary1)C语言中反对如下4种类型的运算: 运算类型运算符四则运算+,-,*,/,%关系运算<,>,<=,>=,==,!=逻辑运算&&,!,II位运算&,I,^,>>,<<,~2)运算符的优先级:单算移比,按逻三赋。如果不同类型的运算符同时呈现在一个表达式中,尽量用括号()指明运算程序。 3)逻辑运算的短路法令:对于&&运算,第一个为假的操作数之后的其余操作数都不再计算;对于||运算,第一个为真的操作数之后的其余操作数都不再计算。因而对于if表达式的逻辑表达式,肯定要思考到后续的操作数是否须要运算到。 4)十进制正数和二进制的互相转换规则如下: 1)符号位:2)绝对值(二进制):3)按位取反:4)加1:如果一个二进制位示意的是一个正数,那么推算的形式按上述规定逐渐相同。5)在计算机中,不同数据类型的实质在于: a)占用的内存大小不同:如int占4字节,char占1字节b)示意数据的具体形式不同:如正整数用原码示意、负整数用补码示意;整数和浮点数的二进制示意办法不同。6)位运算操作时的关键点: a)操作数的类型(占用的内存大小)b)符号位(0还是1)c)不同数据类型的运算要先对齐,再运算(补符号位进行对齐)7)设置整数integer指定Bit位的值规定如下: 置0:应用按位与(运算数n指定地位为0,其余为1,同integer进行&运算),如果对应地位为0,其余地位能够不变为1,这样运算数n能小一点,直观一些置1:应用按位或(运算数n指定地位为1,其余为0,同interger进行|运算)取反:按位异或(如一次指定多位取反)1、四则运算四则运算(+, -, *, /, %) 就是数学中的加减乘除等运算遵循先乘除后加减的运算优先级能够应用括号扭转运算程序留神:C语言中的除法运算,除数不能为0!/和%都是除法。对于“/”,运算的后果和大类型统一。对于“%”,只能作用于整型数。 int a = 1;int b = 2;int c = 0;c = a / b; // 计算失去除法的商,大类型为int,后果依然是intprinf("c = %d\n", c); // c = 0c = a % b; // 计算失去登程的余数,只能作用于整型数prinf("c = %d\n", c); // c = 1double a = 5;double b = 2;double c = 3;c = a / b; // 两个浮点数的除法,大类型为double,后果依然是浮点数doubleprinf("c = %f\n", c); // c = 2.5c = a % n; // error,取余运算不能够作用于浮点型2、关系运算关系运算(<, >, <=, >=, ==, !=) ...

June 27, 2021 · 2 min · jiezi

关于c++:C内存管理17G49-的七个分配器

规范库规定,分配器最顶层在 《...\memory》 头文件下new_allocatornew_allocator 的 allocate 间接调用的 ::operator new ,deallocate 间接调用 ::operator delete malloc_allocatormalloc_allocator 的 allocate 间接调用的 malloc,deallocate 间接调用 free。 array_allocatortr1 (Technical Report 1) 不是正式的库只是一个草案,作为C++ 2003规范的附加库被大多数编译器厂商所反对,它是个过渡性质的库,其实现将会作为C++11规范的一部分。到 C++2011 时,其局部内容被正式蕴含到规范库,在应用形式上依然保留 std::tr1,例如 std::tr1::array 可用 std::array 代替。 在构造函数中须要传入一个指针,这个指针能够指向动态调配的数组,也能够指向动态分配的数组,所以说内存调配不是在array_allocator中进行的,array_allocator 只是对调配好的内存进行治理(因而 deallocate 什么都没做)。 array_allocator 并不会"回收"(指从新被array_allocator治理)已给出的内存空间,因而很少被应用 动态内存调配的形式应用 动态内存调配的形式应用 debug_allocator 包裹另一个分配器,应用至多一个元素大小的空间,用于记录整个区块大小(子元素数量)(是不是相等于另一种 cookie? 但 allocator 的主要用途是缩小 cookie,因而很少被应用)pool_allocatorG2.9 容器应用的分配器不是 std::allocator 而是 std::alloc (毛病,只申请不偿还) G4.9 中的进化G4.9 规范库中有许多 extented allocators, 其中 __pool_alloc 就是 G2.9 的化身 #include <iostream>#include <cstddef>#include <memory> //內含 std::allocator#include <ext\pool_allocator.h> //欲应用 std::allocator 以外的 allocator, 就得自行 #include <ext/...>#include <ext\array_allocator.h>#include <ext\mt_allocator.h>#include <ext\debug_allocator.h>#include <ext\bitmap_allocator.h>#include <ext\malloc_allocator.h>#include <ext\throw_allocator.h>#include <ext\new_allocator.h> //這其實已被 <memory> included, 它就是 std:allocator 的 base class#include <iostream>#include <list>#include <deque>#include <vector>using namespace std;template<typename Alloc>void cookie_test(Alloc alloc, size_t n){ typename Alloc::value_type *p1, *p2, *p3; //需有 typename p1 = alloc.allocate(n); //allocate() and deallocate() 是 non-static, 需以 object 呼叫之. p2 = alloc.allocate(n); p3 = alloc.allocate(n); cout << "p1= " << p1 << '\t' << "p2= " << p2 << '\t' << "p3= " << p3 << '\n'; alloc.deallocate(p1,sizeof(typename Alloc::value_type)); //需有 typename alloc.deallocate(p2,sizeof(typename Alloc::value_type)); //有些 allocator 對於 2nd argument 的值無所謂 alloc.deallocate(p3,sizeof(typename Alloc::value_type));}int main(){ //從語法上試用各式各樣的 allocators cout << sizeof(std::allocator<int>) << endl; //1 cout << sizeof(__gnu_cxx::new_allocator<int>) << endl; //1. //觀察 STL source 可知: new_allocator 是 std::allocator 的 base //我們無法改變 std::allocator 的 base class, 那該如何应用其余的 GNU allocators ? //是否要寫個 custom_allocator (像下面) 並為它加上我想要的 base (例如 __pool_alloc) ? //不,不用,就间接应用, 但需自行 #include <ext/...> cout << sizeof(__gnu_cxx::malloc_allocator<int>) << endl; //1. 大小 1者其實為 0, fields 都是 static. cout << sizeof(__gnu_cxx::__pool_alloc<int>) << endl; //1 cout << sizeof(__gnu_cxx::__mt_alloc<int>) << endl; //1 cout << sizeof(__gnu_cxx::bitmap_allocator<int>) << endl; //1 cout << sizeof(__gnu_cxx::array_allocator<int>) << endl; //8 ==> 因為它有一個 ptr 指向 array 和一個 size_t 示意耗费到 array 哪兒 cout << sizeof(__gnu_cxx::debug_allocator<std::allocator<double>>) << endl; //8 //! cout << sizeof(__gnu_cxx::throw_allocator<int>) << endl; //只有 throw_allocator_base, throw_allocator_random, throw_allocator_limit, 沒有 throw_allocator !! cout << endl; //搭配容器 list <int, __gnu_cxx::malloc_allocator<int>> list_malloc; deque <int, __gnu_cxx::debug_allocator<std::allocator<int>>> deque_debug; vector<int, __gnu_cxx::__pool_alloc<int>> vector_pool; //! vector<int, __pool_alloc<int>> vector_pool; //如果沒加上 namespace : [Error] '__pool_alloc' was not declared in this scope cookie_test(std::allocator<int>(), 1); //相距 10h (示意帶 cookie) cookie_test(__gnu_cxx::malloc_allocator<int>(), 1); //相距 10h (示意帶 cookie) cookie_test(__gnu_cxx::__pool_alloc<int>(), 1); //相距 08h (示意不帶 cookie) //以下將 int 改為 double 結果不變,象征上述 ints 間隔 8 (而非 4) 乃是因為 alignment. cookie_test(std::allocator<double>(), 1); //相距 10h (示意帶 cookie) cookie_test(__gnu_cxx::malloc_allocator<double>(), 1); //相距 10h (示意帶 cookie) cookie_test(__gnu_cxx::__pool_alloc<double>(), 1); //相距 08h (示意不帶 cookie) cout << endl; try { //示範应用 array_allocator: 須先 new an array, 將其 ptr 設給 array_allocator, 最後還要 delete array std::tr1::array<double,100>* arrayTR1 = new std::tr1::array<double,100>; //应用 tr1::array cookie_test(__gnu_cxx::array_allocator<double, std::tr1::array<double,100>>(arrayTR1), 1); //相距 08h (示意不帶 cookie) delete arrayTR1; array<double,100>* arraySTD = new array<double,100>; //应用 std::array cookie_test(__gnu_cxx::array_allocator<double, array<double,100>>(arraySTD), 1); //相距 08h (示意不帶 cookie) delete arraySTD; std::tr1::array<double,1>* p = new std::tr1::array<double,1>; //為搭配下一行 "default 2nd argument 是 std::tr1::array<T,1>" (見 source), 我們须要做一個來. cookie_test(__gnu_cxx::array_allocator<double>(p), 1); //未指明 2nd argument, 所以应用 default, 即 std::tr1::array<T,1> //bad allocation! 因為 cookie_test() 需 3 doubles 而 // 本處所用之 array_allocator 卻只能提供 1 double。 delete p; } catch(...) { cout << "bad allocation! \n"; } return 0;}输入: ...

June 27, 2021 · 6 min · jiezi

关于c:C入门数据类型

Summary0)对于所操作数据的具体类型,肯定要十分明确! 1)C语言对数据的分类:整数类型、浮点数类型、字符类型(一般字符型、无回显字符型)。各个类型的基本区别在于,所占用的内存大小不同。 2)类型所占的字节数是由编译器决定的,32位和64位的次要区别在于:指针所占字节数别离为4和8;long所占字节数别离为4和8。 3)辨别初始化和赋值的关键点:赋值操作是在创立变量时候进行的,还是在创立变量之后进行的。 4) 当遇到以下2种状况时: 以后的值曾经溢出了(超过了以后类型所能示意的范畴里的数)大类型向小类型转换对于溢出当前的值:正值:溢出的值 - 以后类型能示意的个数 = 理论值负值:溢出的值 - 以后类型能示意的个数 = 理论值5)sizeof用于取得类型或者变量所占用的内存字节数,sizeof作用于数组名时,能够失去数组占用的内存。 6)C语言中字面量的默认类型:如2为int,0.2为double,'2'为char 1、数据类型与变量1.1 C语言中的数据类型初学阶段应把握的类型:整形: int:占用4个字节(32位(bit)),示意范畴:-2147483648~2147483647(-231 ~ 231-1)。short:占用2个字节(16位(bit)),示意范畴:-32678 ~ 32767。浮点型: float:占用4个字节(32位(bit)),示意范畴:-3.4 x 1038 ~ 3.4 x 1038。double:占用8个字节(64位(bit)),示意范畴:-1.7 x 10-308 ~ 3.4 x 10308。字符型: char:占用1个字节内存(8位(bit)),示意范畴:-128~127。字符数据应用单引号括起来。包含一般字符(英文字符类型,如'D','t');无回显字符类型(无回显字符必须以反斜杠'\'结尾,是一种打印后在屏幕上看不到的字符,如换行符'\n',制表符'\t',这是一个字符);字符类型理论也是种整型。各个数据类型的基本区别在于,所示意的内存大小不同。 1.2 C语言中变量的命名规定字母(a-z, A-Z)、数字(0-9)、下划线(_)形成的字符序列第一个字符必须为字符或者下划线(不能为数字)大小写敏感(如name和Name是两个不同的变量名字)// 小测试:以下哪些命名是非法的?()A.WORD B.-abc C.2c D._1E.m_test F.a@b G.c3 H._// A、D、E、G、H非法变量命名的标准:1)见名知义:变量命名肯定要一眼能看出这个变量的用处2)便于浏览:能够遵循一些标准,如“驼峰标准”,不便本人和别人浏览、保护代码。 1.3 C语言中变量的定义C语言中创立变量的语法:type name; 如下:int n1;double n2;short n3;初始化:在创立变量的同时,给变量一个值。赋值:在创立变量之后,扭转变量的值。 int n1; // 定义变量,名为n1,类型为intdouble hello; // 定义变量,名为hello,类型为doubleint n2 = 2; // 定义变量,名为n2,类型为int,并初始化为2n1 = 1; // 赋值操作,扭转n1的值,使其示意12、深刻数据类型与变量2.1 程序中数值的类型C语言是类型严格的语言,字面量也有类型,应用字面量时也须要思考字面量的类型。字面量的类型包含默认类型和指定类型,如: ...

June 26, 2021 · 2 min · jiezi

关于c#:ftp多线程上传下载以及断点续传

上传性能首先退出默认的配置项(这部分有对应的办法进行设置): 异步上传的局部代码 /// <summary> /// 异步上传 (多个文件最好用这个办法) 多线程时设置最大连接数 能够保障按队列先入先进来传输 此时不须要设置线程池中线程数量 /// </summary> /// <param name="fullName"></param> /// <param name="fileName">如果为空 默认取上传文件的名称</param> /// <param name="process"></param> public void AsynUpload(string fullName,string fileName, Func<FtpState, FtpState> process) { ManualResetEvent waitObject; FtpState state = new FtpState(); try { string _port = string.IsNullOrEmpty(port) ? "" : $":{port}"; fileName = string.IsNullOrEmpty(fileName) ? Path.GetFileName(fullName) : fileName; string ftpfullpath = $"ftp://{ipAddr}{_port }//{fileName}"; Uri target = new Uri(ftpfullpath); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target); request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = new NetworkCredential(account, password); //request.KeepAlive = false;//是否保留连贯 设置了这个并不能失效 异步上传 request.UseBinary = true;// ftp默认是传输二进制 request.ServicePoint.ConnectionLimit = maxConnect;//最大连接数 // Store the request in the object that we pass into the // asynchronous operations. state.Request = request; state.FullName = fullName; state.ProcessCall = process; state.Operate = FtpOperate.UpLoad; //文件大小 FileInfo file = new FileInfo(fullName); state.Size = file.Length; // Get the event to wait on. waitObject = state.OperationComplete; // Asynchronously get the stream for the file contents. request.BeginGetRequestStream( new AsyncCallback(EndGetStreamCallback), state ); // Block the current thread until all operations are complete. waitObject.WaitOne(); // The operations either completed or threw an exception. if (state.OperationException != null) { if (UploadFail != null) { UploadFail.Invoke(state, state.OperationException); return; } throw state.OperationException; } else { if (UploadSuccess != null) { UploadSuccess.Invoke(state, state.StatusDescription); return; } } } catch (Exception ex) { if (UploadFail != null) { UploadFail.Invoke(state, ex); return; } } }利用多线程 异步上传: ...

June 26, 2021 · 2 min · jiezi

关于c:STM32最小系统下载程序方法

我应用的STM32最小零碎板是stm32f103c8t6 采纳用ISP形式下载: 须要的器件: CH340E USB转TTL模块转串口mcuisp.exe软件stm32f103c8t6USB转TTL模块与stm32的连贯: STM32USB-TTL3.3V3.3VGNDGNDA9RxA10TxSTM32芯片的启动形式: 在应用JLINK烧写程序的时候,BOOT0和BOOT1都接在0的地位,而用mcuisp.exe串口烧写程序,须要将BOOT0接到1的地位. 留神:当程序下载实现后,STM32f103c8t6最小板即开始运行程序了。不过如果将最小板断电之后从新上电,程序无奈执行,须要断电后,将BOOT0接到0上,再从新上电,程序就能失常运行了

June 26, 2021 · 1 min · jiezi

关于c#:Win32Api-使应用Always-on-top的几种方法

本文介绍几种使利用始终置于顶层的办法。 问题形容个别状况下,想要将利用置于顶层,设置其TopMost属性为true即可。对于多个设置了TopMost属性的利用,后激活的在下面。 但有的利用,比方全局的快捷操作工具条,它须要在所有利用之上,即便是设置了TopMost的利用。 解决思路留神:使某个利用永远不会被其它利用笼罩,这自身是个伪命题。因为如果有两个程序(A和B)这样做,拖动两个窗口使它们重叠,这两个窗口中的一个必须在另一个之上,这在逻辑上是互相矛盾的。 所以应该尽量避免这种状况,如果非要这样做,本文提供如下几种方法实现(不要将两个这样的利用重叠,否则会不停将置顶)。 首先,该应用程序须要设置其TopMost属性为true,这样一般窗口自身就会在它上面。本文次要探讨该窗口如何置于设置了TopMost属性的窗口之上。 计划一:捕捉WM_WINDOWPOSCHANGING音讯咱们晓得,应用Win32的SetWindowPos接口能够扭转窗口的Z Order,能够猜想,当另外一个利用置顶时,咱们的利用会扭转其Z Order,因而,咱们能够尝试捕捉WM_WINDOWPOSCHANGING音讯。 当窗口的大小、地位、Z序扭转时,窗口会接管到WM_WINDOWPOSCHANGING音讯,咱们能够应用WndProc解决窗口音讯。当捕捉到该音讯时,咱们能够尝试将利用再次置顶。要害代码如下,测试可行,但不确定是否有副作用: /// <summary>/// 计划一:捕捉WM_WINDOWPOSCHANGING音讯,若无SWP_NOZORDER标记,则置顶/// </summary>private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){ switch (msg) { case Win32Api.WM_WINDOWPOSCHANGING: Win32Api.WINDOWPOS wp = (Win32Api.WINDOWPOS)Marshal.PtrToStructure( lParam, typeof(Win32Api.WINDOWPOS)); if ((wp.flags & Win32Api.SWP_NOZORDER) == 0) _ = SetTopMostLater(); // 不应用弃元编译器会收回正告 break; } return IntPtr.Zero;}private async Task SetTopMostLater(){ await Task.Delay(300); var interopHelper = new WindowInteropHelper(this); Win32Api.SetWindowPos(interopHelper.Handle, Win32Api.HWND_TOPMOST, 0, 0, 0, 0, Win32Api.TOPMOST_FLAGS);}计划二:循环置顶这个是比拟容易想到的一个计划,每隔肯定的工夫给利用设置下TopMost,该计划也是可行的: ...

June 25, 2021 · 1 min · jiezi

关于c#:C实践笔记1语言语法的使用

一.using static 1.C#6 using static新语法,能够简化前缀:例: 1 using static System.Console; //1.应用using static 2 3 namespace test 4 { 5 internal class Program 6 { 7 private static void Main(string[] args) 8 { 9 WriteLine("test"); //2.省去写Console.只是语法糖而已。 Console.WriteLine("test");10 }11 }12 }2.只能应用它的静态方法目前我在单例模式来用Instance,省略类名的前缀,这有点相似应用c++的宏定义来应用实例。

June 25, 2021 · 1 min · jiezi

关于c++:熬夜整理近百份大厂面经2022校招提前批面经总结分享腾讯字节阿里百度京东等招聘信息必考点简历书写

整顿面经镇楼,随着高考的完结,2022的校招提前批曾经轻轻开始了,不论你是大四还是研三,应聘将会成为大家接下来半年乃至一年的重要工作! 接下来就联合我本身的教训以及我翻阅几百份最新面经后的一点点总结经验,心愿对同学们的上岸之路有所帮忙! 1.招聘信息的获取路径2.大厂面试必考点(人俗称:八股文)3.学习打算4.简历书写5.面试技巧与经验之谈 1.招聘信息的获取路径不少的同学在校招的时候,并不是没有那个实力进更好的企业,只是遗记了招聘投递工夫,毕竟在没有孤注一掷的状况下,比拟好的公司的招聘音讯都是须要留神的,那不免就会呈现脱漏与遗记。所以,第一点就是要做好招聘信息获取的渠道起源: ①各大公司官方网站与公众号②牛客网③实习僧④业余的技术QQ微信群⑤有更好的能够留言评论分享一下 2.大厂面试必考点(俗称:八股文)面试屡次的同学就会晓得,有些技术问题往往都是面试官绕不开,而你躲不掉的。而在我整顿的187份大厂面经中,面试官问到频率最高的技术点及畛域就是上面这些,这个肯定要划重点!! 技术点: 1.红黑树2.零拷贝3.过程线程4.TCP、UDP5.epoll、poll、select6.排序7.哈希8.拥塞管制9.B树和B+树10.虚拟内存11.http协定12.malloc和new的区别 就这12个问题不是全副百分之一百会全副呈现,至多搞定它们会成为你的面试加分点,毕竟作为一个应届生而言,能考的点也就那么多了。至于问的范畴泛不泛,这个就要看你的简历是如何写的了,这个文章前面也会说到。 技术畛域: 1.c++根底2.计算机网络3.操作系统4.网络编程5.数据结构与算法6.数据库7.我的项目 作为一名应届生来说,我的项目教训的有余是一种常态,所以校招时尽管也会问到相干的我的项目技术内容,然而外围点还是看你对技术自身的钻研与了解。 3.学习打算尽管总结了很多经典的面试题,然而也架不住咱面试的公司多。所以,实打实的夯实好本人的技术能力才是要害,而面试官也能够通过对你学习技术的布局与速度,来判断你的学习能力,这一点对于程序员来说也是尤为重要的。 学习打算如何制订,这里也参考了网上大多优良的同学总结进去的打算进行汇总,供有须要的同学参考。依据常考的技术畛域,咱们也将学习打算做区块的划分: c++根底1、面向对象的三大个性:封装、继承、多态 2、类的拜访权限:private、protected、public 3、类的构造函数、析构函数、赋值函数、拷贝函数 4、挪动构造函数与拷贝构造函数比照 5、深拷贝与浅拷贝的区别 6、空类有哪些函数?空类的大小? 7、内存分区:全局区、堆区、栈区、常量区、代码区 8、C++与C的区别 9、struct与class的区别 10、struct内存对齐 11、new/delete与malloc/free的区别 12、内存泄露的状况 13、sizeof与strlen比照 14、指针与援用的区别 15、野指针产生与防止 16、多态:动静多态、动态多态 17、虚函数实现动静多态的原理、虚函数与纯虚函数的区别 18、继承时,父类的析构函数是否为虚函数?构造函数能不能为虚函数?为什么? 19、动态多态:重写、重载、模板 20、static关键字:润饰局部变量、全局变量、类中成员变量、类中成员函数 21、const关键字:润饰变量、指针、类对象、类中成员函数 22、extern关键字:润饰全局变量 23、volatile关键字:防止编译器指令优化 24、四种类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast 25、右值援用 26、std::move函数 27、四种智能指针及底层实现:auto_ptr、unique_ptr、shared_ptr、weak_ptr 28、shared_ptr中的循环援用怎么解决?(weak_ptr) 29、vector与list比拟 30、vector迭代器生效的状况 31、map与unordered_map比照 32、set与unordered_set比照 33、STL容器空间配置器 举荐书籍:《C++ Primer》(第5版)、《STL源码分析》、《深度摸索C++对象模型》,面试考点根本几种在虚函数、虚继承、vector等容器的底层实现以及c++新个性上,所以应答面试这三本就够了。 计算机网络1、OSI7层网络模型:应用层、表示层、会话层、运输层、网络层、链路层、物理层 2、TCP/IP四层网络模型:应用层、运输层、网际层、接口层 综合OSI与TCP/IP模型,学习五层网络模型: 从上向下架构:应用层、运输层、网络层、链路层、物理层 链路层: 3、MTU 4、MAC地址 网络层: 5、地址解析协定 6、为啥有IP地址还须要MAC地址?同理,为啥有了MAC地址还须要IP地址? 7、网络层转发数据报的流程 8、子网划分、子网掩码 9、网络管制报文协定ICMP 10、ICMP利用举例:PING、traceroute 运输层: 11、TCP与UDP的区别及利用场景 12、TCP首部报文格式(SYN、ACK、FIN、RST必须晓得) 13、TCP滑动窗口原理 14、TCP超时重传工夫抉择 15、TCP流程管制 16、TCP拥塞管制(肯定要弄清楚与流量管制的区别) 17、TCP三次握手及状态变动。为啥不是两次握手? 18、TCP四次挥手及状态变动。为啥不是三次挥手? 19、TCP连贯开释中TIME_WAIT状态的作用 20、SYN泛洪攻打。如何解决? 21、TCP粘包 22、TCP心跳包 23、路由器与交换机的区别 24、UDP如何实现牢靠传输 应用层: 25、DNS域名零碎。采纳TCP还是UDP协定?为什么? 26、FTP协定(理解) 27、HTTP申请报文与响应报文首部构造 28、HTTP1.0、HTTP1.1、HTTP2.0比照 29、HTTP与HTTPS比照 30、HTTPS加密流程 31、办法:GET、HEAD、POST、PUT、DELETE 32、状态码:1、2、3、4、5** 33、cookie与session区别 34、输出一个URL到显示页面的流程(越具体越好,搞明确这个,网络这块就差不多了) ...

June 24, 2021 · 1 min · jiezi

关于c++:TcaplusDB知识库软件和硬件环境建议配置

TcaplusDB是专为游戏进行额定优化设计的分布式 NoSQL 数据库,作为腾讯云的数据库服务的一部分为广大客户提供极致的游戏数据体验。目前已为多个千万级 DAU 大作提供了稳固的数据存储服务,依靠腾讯云遍布寰球五大洲(亚洲、欧洲、北美洲、南美洲、大洋洲)的根底设施服务节点,游戏开发商只需接入一次,便可不便寰球游戏用户体验。 TcaplusDB 作为一款高性能分布式 NOSQL 数据库,能够很好的部署和运行在 Intel x86-64 架构服务器环境(ARM 架构的服务器环境)及支流虚拟化环境,并反对绝大多数的支流硬件网络。作为一款高性能数据库系统,TcaplusDB 反对支流的 Linux 操作系统环境。 1. Linux 操作系统版本要求Linux 操作系统平台版本Red Hat Enterprise Linux6.x - 7.xCentOS6.x - 7.xTlinux1.2 / 2.2留神: TcaplusDB 在 CentOS 6.x 、CentOS 7.x 的环境下进行过大量的测试,同时机会经营案例也有很多该操作系统部署的最佳实际,因而,倡议应用 CentOS 7.3 以上的 Linux 操作系统来部署。以上 Linux 操作系统可运行在物理服务器以及 VMware、KVM、XEN、Docker 支流虚拟化环境上2. 服务器倡议配置TcaplusDB 反对部署和运行在 Intel x86-64 架构的 64 位通用硬件服务器平台(或者 ARM 架构的硬件服务器平台)。对于开发,测试,及生产环境的服务器硬件配置(不蕴含操作系统 OS 自身的占用)有以下要求和倡议: 2.1. 开发及测试环境CPU内存本地存储网络实例数量(最低要求)8 核+16 GB+SAS, 200 GB+千兆网卡1所有组件在同一台机器部署,包含TcapOMS、Mysql、Tcapdb、Tcapcenter、Tcapdir、Tcapsvr、Tcaproxy、TcapRestProxy 留神: 如进行性能相干的测试,防止采纳低性能存储和网络硬件配置,避免对测试后果的正确性产生烦扰。2.2. 生产环境2.2.1. 最小配置模块组件CPU内存本地存储网络实例数量(最低要求)组件形容管控TcapOMS4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)Tcaplus存储网页治理端管控Tcapdb4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)提供数据缓写性能,可同步流式数据到MySQL、ES管控Tcapcenter4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)Tcaplus核心治理节点管控Tcapdir4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)Tcaplus目录服务器,提供鉴权、接入节点更新告诉性能管控Mysql4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)数据库,保留Tcaplus外围配置、监控上报数据管控Tmonitor4 核+16 GB+SAS, 100 GB+千兆网卡2(跨机房、机架部署)Tcaplus 过程监控服务存储Tcapsvr8 核+32 GB+备份、Binlog盘:SAS/SSD/NVME 1 TBdata盘:SSD/NVME 500GB万兆网卡2 (跨机房、机架部署)Tcaplus存储节点接入Tcaproxy8 核+32 GB+备份、Binlog盘:SAS/SSD/NVME 1 TBdata盘:SSD/NVME 500GB万兆网卡2 (跨机房、机架部署)Tcaplus接入节点接入TcapRestProxy8 核+32 GB+备份、Binlog盘:SAS/SSD/NVME 1 TBdata盘:SSD/NVME 500GB万兆网卡2 (跨机房、机架部署)Tcaplus Rest接入节点全局索引TcapIndex Tcaplus全局索引节点冷备Gluster4 核+8 GB+SAS,举荐5T, 存储容量跟冷备天数和binlog寄存天数相干,可按需调整万兆网卡2或2的倍数Tcaplus 冷备存储节点, Gluster内做Raid1,所以理论使用率是50%,举荐按15天冷备+25天binlog寄存2.2.2. 高性能配置模块组件CPU内存本地存储网络实例数量(最低要求)组件形容管控TcapOMS4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)Tcaplus存储网页治理端管控Tcapdb4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)提供数据缓写性能,可同步流式数据到MySQL、ES管控Tcapcenter4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)Tcaplus核心治理节点管控Tcapdir4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)Tcaplus目录服务器,提供鉴权、接入节点更新告诉性能管控Mysql4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)数据库,保留Tcaplus外围配置、监控上报数据管控Tmonitor4 核+16 GB+SAS, 200 GB+千兆网卡2(跨机房、机架部署)Tcaplus 过程监控服务存储Tcapsvr24 核+64 GB+备份、Binlog盘:SAS/SSD/NVME 2 TBdata盘:SSD/NVME 1 TB万兆网卡2 (跨机房、机架部署)Tcaplus存储节点接入Tcaproxy8 核+16 GB+SAS, 100 GB+万兆网卡2(跨机房、机架部署)Tcaplus接入节点接入TcapRestProxy8 核+16 GB+SAS, 100 GB+万兆网卡2(跨机房、机架部署)Tcaplus Rest接入节点全局索引TcapIndex Tcaplus全局索引节点冷备Gluster4 核+8 GB+SAS,举荐10T, 存储容量跟冷备天数和binlog寄存天数相干,可按需调整万兆网卡2或2的倍数Tcaplus 冷备存储节点, Gluster内做Raid1,所以理论使用率是50%,举荐按15天冷备+25天binlog寄存留神: ...

June 22, 2021 · 1 min · jiezi

关于c++:DPST1092-21T2

DPST1092 21T2 — Assignment 1: cellular, 1D Cellular Automaton in MIPSAssignment 1: cellular, 1D Cellular Automaton inMIPSversion: 1.0 last updated: 2021-06-3 20:00:00Aimsto give you experience writing MIPS assembly codeto give you experience with data and control structures in MIPSGetting StartedCreate a new directory for this assignment called cellular, change to this directory, and fetch the provided code by running thesecommands:$ mkdir cellular$ cd cellular$ 1092 fetch cellularThis will add the following files into the directory:cellular.c: a cellular automaton renderercellular.s: a stub assembly file to completecellular.c: A Cellular Automaton Renderercellular.c is an implementation of a one-dimensional, three-neighbour cellular automaton. It examines its neighbours and its value inthe previous generation to derive the value for the next generation.Here, we using '#' to indicate a cell that's alive; and '.' to indicate a cell that is not.Given we examine three neighbours, there are eight states that the prior cells could be in. They are:For each one, we decide what action to take. For example, we might choose to have the following 'rule':We apply this rule to every cell, to determine whether the next state is alive or dead; and this forms the next generation. If we print thesegenerations, one after the other, we can get some interesting patterns.The description of the rule above — by example, showing each case and how it should be handled — is inefficient. We can abbreviatethis rule by reading it in binary, considering live cells as 1's and dead cells as 0s; and if we consider the prior states to be a binary valuetoo — the above rule could be 0b00011110, or 30.To use that rule, we would mix together the previous states we're interested in — left, middle, and right — which tells us which bit of therule value gives our next state.The size of a generation, the rule number, and the number of generations are supplied on standard input. For example:Files c.out and mips.out are identicalTry this for different values of the parameters.Assumptions and ClarificationsLike all good programmers, you should make as few assumptions as possible.Your submitted code must be hand-written MIPS assembly, which you yourself have written. You may not submit code in otherlanguages. You may not submit compiled output.You may not copy a solution from an online source (e.g., Github).There will be a style penalty for assignments that do not use the stack to save and restore $ra (in main)There will be a style penalty for assignments that do not follow these important MIPS calling conventions:function arguments should be passed in $a0 through $a3$s0..$s9 should be preserved across function calls: if a function changes these registers, it must restore the original value beforereturningThe above two style penalties apply only to assignments which score above CR (65+) on performance testing.If you need clarification on what you can and cannot use or do for this assignment, ask in the class forum.You are required to submit intermediate versions of your assignment. See below for details.AssessmentWhen you think your program is working, you can use autotest to run some simple automated tests:$ 1092 autotest cellular cellular.sSubmissionWhen you are finished working on the assignment, you must submit your work by running give:$ give dp1092 ass1_cellular cellular.sYou must run give before June 28 23:59:59 to obtain the marks for this assignment. Note that this is an individual exercise, the workyou submit with give must be entirely your own.You can run give multiple times.Only your last submission will be marked.You cannot obtain marks by e-mailing your code to tutors or lecturers.You can check your latest submission on CSE servers with:$ 1092 classrun -check ass1_cellularManual marking will be done by your tutor, who will mark for style and readability, as described in the Assessment section below. Afteryour tutor has assessed your work, you can collect your assignment by typing on the command line:$ 1092 classrun -collect ass1_cellularThe resulting mark will also be available by typing:$ 1092 classrun -sturecDue Date2021/6/18 DPST1092 21T2 — Assignment 1: cellular, 1D Cellular Automaton in MIPSDue DateThis assignment is tentatively due June 28 23:59:59.If your assignment is submitted after this date, each hour it is late reduces the maximum mark it can achieve by 2%. For example, if anassignment worth 74% was submitted 10 hours late, the late submission would have no effect. If the same assignment was submitted 15hours late, it would be awarded 70%, the maximum mark it can achieve at that time.Assessment SchemeThis assignment will contribute 9 marks to your final DPST1092 mark.80% of the marks for assignment 1 will come from the performance of your code on a large series of tests.20% of the marks for assignment 1 will come from hand marking. These marks will be awarded on the basis of clarity, commenting,elegance and style. In other words, you will be assessed on how easy it is for a human to read and understand your program.An indicative assessment scheme follows. The lecturer may vary the assessment scheme after inspecting the assignment submissions,but it is likely to be broadly similar to the following:HD (85+) beautiful documented code, which uses the stack with MIPS calling conventions, andimplements spec perfectlyDN (75+) very readable code, prints cells correctly if n_generations positive or negative, all rulescorrectly handledCR (65+) readable code, prints cells correctly if n_generations positive, rules mostly workingPS (55+) prints initial world (first line) correctly and sometimes more correct linesPS (50+) good progress on assignment but not passing autotests0% knowingly providing your work to anyoneand it is subsequently submitted (by anyone).0 FL forDPST1092submitting any other person's work; this includes joint work.academicmisconductsubmitting another person's work without their consent;paying another person to do work for you.Intermediate Versions of WorkYou are required to submit intermediate versions of your assignment.Every time you work on the assignment and make some progress you should copy your work to your CSE account and submit it usingthe give command below. It is fine if intermediate versions do not compile or otherwise fail submission tests. Only the final submittedversion of your assignment will be marked.Attribution of WorkThis is an individual assignment.The work you submit must be entirely your own work, apart from any exceptions explicitly included in the assignment specificationabove. Submission of work partially or completely derived from any other person or jointly written with any other person is notpermitted.You are only permitted to request help with the assignment in the course forum, help sessions, or from the teaching staff (the lecturer(s)and tutors) of DPST1092.Do not provide or show your assignment work to any other person (including by posting it on the forum), apart from the teaching staffof DPST1092. If you knowingly provide or show your assignment work to another person for any reason, and work derived from it issubmitted, you may be penalized, even if that work was submitted without your knowledge or consent; this may apply even if your workis submitted by a third party unknown to you. You will not be penalized if your work is taken without your consent or knowledge.Do not place your assignment work in online repositories such as github or any where else that is publically accessible. You may use aprivate repository.Submissions that violate these conditions will be penalised. Penalties may include negative marks, automatic failure of the course, andpossibly other academic discipline. We are also required to report acts of plagiarism or other student misconduct: if students involvedhold scholarships, this may result in a loss of the scholarship. This may also result in the loss of a student visa.Assignment submissions will be examined, both automatically and manually, for such submissions.Change LogVersion 1.0 Initial release. ...

June 21, 2021 · 6 min · jiezi

关于c++:C到C

1. 新类型 布尔 援用整型 int long浮点型 float double字符类型 char 布尔 boolbool 寄存真(1)和假(0)的类型 大小1个字节 能够寄存true false指针 寄存地址的变量 能够间接批改变量的值 定义的时候能够不必赋值 应用的时候 如果不赋值不能够解援用 应用的是指向的变量援用 变量的别名 应用援用和应用变量是一样的 定义的时候必须绑定一个变量 绑定之后不能够让援用指向别的变量2. 函数 内联 重载 缺省2.1 内联inline 宏定义#define 不带参数 能够替换简略的函数 不能替换简单函数 先替换再计算 没有函数的跳转工夫 增长代码长度 节约运行工夫长度 消耗内存 倡议应用内联函数替换带参宏 区别: 1.内联函数 参数有类型(更平安) 带参宏没有类型 2.带参宏 先替换再计算 须要思考优先级问题 内联函数 先计算 而后后果带进去 不须要思考优先级问题 内联inline关键字 放到函数后面 倡议这个函数用内联的形式编译 `inline void(int& a)//函数背后加上inline关键字称之为内联函数 { a = 2; }` 2.2 重载 C++容许函数重名 函数定义 容许重名 函数返回值类型/参数名字不一样不形成重载 次要看参数 函数参数个数不一样 形成重载 void fun(int a); int fun(int aa, int bb); 函数参数类型不一样 形成重载 void fun(int a); int fun(double b);2.3 缺省 给函数形参一个默认值 调用函数的时候 有默认值的形参能够不必传递参数 申明/定义的时候赋值 缺省必须从右往左 void fun_1(int a, int b, int c = 1); fun_1(3, 2); void fun_2(int aa, int bb = 12, int cc = 11); fun_2(13); 缺省和重载 引发一个二义性问题 两个函数形成重载 然而调用的时候两个函数都能够匹配 void fun_3(int a, int b = 2); void fun_3(int a, int b = 4, int c = 6); fun_3(1);//此时都能够调用3.C++申请内存 new deleteC语言 申请堆内存 malloc 开释 free 头文件 stdlib.hint* p = (int*)malloc(sizeof(int)*20);//申请内存free(p);//开释内存C++申请内存 应用new 开释内存 应用deleteint* p = new int;//申请一个int;delete p;//开释一个int* pp = new int[20];//申请20个 new 类型[个数]delete[] pp;//开释多个申请内存的时候给他赋初值int* p = new int(20);//()示意初值int* pp = new int[20]{1, 2, 3. 4. 5};//赋予多个初值4.C++的输入输出形式stdio.h C语言输入输出头文件 io input输出 output输入 standard规范iostream io 输入输出 stream流count<<输入的内容<<endl;//endl示意换行 输入数据cin>>变量;//输出数据

June 21, 2021 · 1 min · jiezi

关于c++:C内存管理16GNU-C-对于-Allocator-的描述

当你将元素退出容器中,容器必须调配更多内存以保留这些元素,于是它们向其模板参数 Allocator 收回申请,该模板参数往往被另名为(aliased to)allocator_type。甚至你将 chars 增加到 string class 也是如此,因为 string 也算是一个正规 STL 容器。 template <class T, class Allocator=allocator<T>>class vector;template <class T, class Allocator=allocator<T>>class list;template <class T, class Allocator=allocator<T>>class deque;每个元素类型为 T 的容器(container-of-T) 的 Allocator 模板参数默认为 allocator<T>。其接口只有大概 20 个 public 申明,包含嵌套的(nested) typedefs 和成员函数。最终要的两个函数是: T *allocate(size_type n, const void *hint = 0);void deallocate(T *p, size_type n);n 指的是客户申请的元素个数,不是指空间数量(字节数) 这些空间都是通过调用 ::operator new 取得,但何时调用以及如许频繁调用,并无具体指定 最容易满足需要的做法就是每当容器须要内存就调用 operator new, 每当容器开释内存就调用 operator delete。这种做法比起调配大块内存并缓存(caching)而后徐徐小块应用当然慢,劣势则是能够在极大范畴的硬件和操作系统上无效运作 __gnu_cxx::new_allocator实现出俭朴的 operator new 和 operator delete 语义 ...

June 20, 2021 · 2 min · jiezi

关于c++:C内存管理15Loki-allocator-源码分析

Loki是由 Andrei 编写的一个与《Modern C++ Design》(C++设计新思维)一书配套发行的C++代码库。其中有两个文件 SmallObj.h 、SmallObj.cpp 进行内存治理,能够独自进行应用 Loki 源码下载 类层次结构SmallObj 文件中有三个类:chunk, FixedAllocator 和 SmallObjAllocator。其中SmallObjAllocator 位于最顶层供应用程序调用 ChunkChunk 是类层次结构中最底层治理内存块的类,它负责向操作系统进行内存申请 Init, Reset, Release 1. Init(), 应用 operator new 申请一段内存 chunk, 并应用 pData_ 指向 chunk2. Reset(), 对 pData_ 指向的内存进行宰割。[数组代替链表,索引代替指针] [与嵌入式指针相似]每一块 block 的第一个字节寄存的是下一个可用的 block 间隔起始地位 pData_ 的偏移量(以 block 大小为单位)3. Relese(), 向操作系统偿还内存--1. blockSize、blocksblock, block 大小及数量 2. firstAvailableBlock_,以后可用内存块的偏移量3. blocksAvailable,以后 chunk 中残余的 block 数量 unsigned char i = 0;unsigned char *p = pData;for(;i!=blocks; p+=blockSize) // 以 blockSize 为距离切分 chunk 为 block *p = ++i; // 以 block 的第一个字节存储下一个可用 block 索引参数初始化后的 chunk ...

June 20, 2021 · 3 min · jiezi

关于c:C入门一Hello-World

Summary1、前言1.1 什么是软件软件是一种计算机部件,是计算机的组成部分;软件是指挥硬件实现具体性能的“意识形态”;硬件是软件的“躯干”,接管并执行软件的命令;当代计算机软硬件架构:最底层的是计算机硬件,包含CPU、内存、显卡、网卡、键盘、鼠标等。而后是运行于计算机硬件之上的各类操作系统,如Linux、Windows、MacOs等。(操作系统也是一种软件)再就是基于操作系统的各类软件,如设计软件、办公软件、聊天软件等。 1.1 什么是程序设计语言应用一组固定规定和符号表达思想的形式;人类应用这组规定和符号形容须要计算机实现的性能;计算机可能读懂由这组规定和符号形成的描述语言,并严格执行;即:程序设计语言是程序员和计算机进行交换沟通的语言,是计算机可能读懂并执行的语言。同咱们日常所用汉语一样,也有本人的一系列的规定。咱们只须要严格遵守规则,就能写出计算机能够执行的程序。 2、C程序中的数据输入2.1 C语言是怎么执行的个别状况下,C语言程序从main()开始执行,从左花括号“{”开始,到右花括号“}”完结,默认状况下,C语言程序是以自上而下的程序来执行,执行的根本单位是语句,每条语句应用分号“;”隔开。(正如中文中对一段文章的浏览,个别也是自上而下,按句子来读,每个句子的完结符号是句号“。”) 上图中,C程序:单纯的文本文件,无奈间接执行编译软件的工作:1)检测C程序的语法是否合规;2)将C程序翻译成二进制可执行程序:如Windows零碎下的.exe文件,Linux零碎下的.out文件 2.2 应用C语言如何打印“Hello World!”C语言中内置了很多实用的“工具包”工具包都有一个固定的名字,通过名字应用(#include <name>)每个工具包中提供了很多“工具”,如stdio.h工具包中就提供了一个用于“打印”输入的工具:printf,printf通过设置参数后能在屏幕上打印出文本。// 在屏幕上打印Hello World。// 代码留神点以正文模式给出#include <stdio.h> // #include用于申明须要应用的工具包 // stdio.h:程序中须要用到的stdio.h工具包int main(){ printf("%s\n", "Hello World!"); // printf是用来打印输出的工具 // %s是对应于字符串的“格式化字符”,第一个参数中除了格式化字符外的,都是一些说明性字符 // 第二个参数"Hello World!"是要打印到屏幕上的数据 return 0;} printf应用数据对参数中的格式化字符进行替换(%s等)不同类型的数据对应于不同的格式化字符:如%s对应字符串,%d对应整数,%f对应浮点数等最终打印的数据是一个字符串。3、C程序中的数据输出3.1 如何从键盘输入数据stdio.h工具包中提供了一个数据输出工具scanfscanf通过正确设置后,可能获取键盘输入的数据scanf将键盘获取的数据“填入”变量 // scanf工具应用示例#include <stdio.h> // scanf工具在stdio.h工具包中int main(){ int i = 0; scanf("%d", &i); // 1)scanf是从键盘输入的工具 // 2)接管键盘输入的变量名前要加上“&” // 3)输出数据的类型必须和变量i的类型统一 // 4)scanf的第一个参数中,只能有格式化字符,不能蕴含任何与类型无关的字符(如\n) return 0;}3.2 使如何间断地从键盘中输出数据#include <stdio.h>int main(){ int i = 0; int j = 0; // 1)一次性输出 scanf("%d%d", &i, &j); // 输出时应用空格或回车对不同数据进行分隔 // 2)离开输出 scanf("%d", &i); scanf("%d", &j); return 0;}本文总结自“狄泰软件学院”唐佐林老师《C语言入门课程》。如有错漏之处,恳请斧正。 ...

June 20, 2021 · 1 min · jiezi

关于c:解析Large-Coding-Question

Part 3: Large Coding Question[P3 Q1] Quack from afar[P3Q2] Quack Family - Siblings[P3 Q3] Chucky's Chicken App1) Read in Menu From File2) Order Items3) Calculate Prices4) Charge the UserScaffold[P3 Q1] Quack from afarThe ProblemUnfortunately, the duck population has seen an outbreak of QUACK19, and the Duck governmenthas placed social distancing restrictions on all pond activities. However, the Duck government isconstantly changing their distancing requirements, so it is up to you to determine which ducks areallowed to swim in the pond.You are provided with a file which contains a list of coordinates of where ducks will land in apond. Ducks will land in the pond one after the other. The order that coordinates appear in thefile corresponds to the order they will land in the pond.When a duck attempts to land in the pond, it must first determine if the position it wants to landis far enough away from any of the current ducks in the pond. Using the distance that the DuckGovernment has given you, we can calculate whether the new duck will encroach on existingducks in the pond. If their landing spot is too close to other ducks, they will keep flying and findanother pond somewhere (we do not care about the other pond).After all the ducks in violation of social distancing have moved on, you should write to a file thecoordinates of all the ducks which are currently in the pond. The order these ducks appear in thefile should preserve the order in which they arrived in the pond.Your program should the write to a file with the same name as the filename parameter,although prefixed with filtered- .For example, if my filename is ducks.txt , I would write the filtered duck coordinates tofiltered-ducks.txt . Another example, if my filename was pond.ducks , I would write thefiltered duck coordinates to filtered-pond.ducks .The TaskWrite a function distance_ducks(filename, distance) . The function will read a file from thegiven filename which contains the coordinates of duck landing zones in a pond. Thefunction will then filter the file so that only ducks adhering to social distancing rules can stay inthe pond. The function will then write to a file containing the coordinates of ducks which are notin violation of social distancing.If the file cannot be opened because it does not exist, you must catch the FileNotFoundErrorobject and throw a new exception FileNotFoundError with the contents of the exception beingthe filename. Any other exception for failure to open a file is not caught.If the parameter filename is not a string type, then a TypeError exception is thrown with thecontents of the exception being a string "parameter filename is not a string" .If the parameter distance is not a float or int type, then a TypeError exception is thrown withthe contents of the exception being a string "parameter distance is not a numeric type" .The fileEach line in the file will consist of two floating point values separated by a comma. Each new lineof the file represents the position that a new duck will attempt to land in the pond.An example of the file contents is shown below:You can find sample input and output files in the testing folder in your workspace.The directory names in outputs specify the distance value used, e.g. 1-5 indicates 1.5m ofdistance between ducks.Note:You do not have to write your own tests / test driver for this task (although you can if you'd like).The contents of the testing directory are sample outputs for you to check if your program isworking. This is optional.The directory structure for the testing folder is to let you know the distance value that was usedwhen the sample outputs were generated, so that you can test your function with the samearguments (to hopefully get the same output). Check the README file, You can use the diffcommand to check if your output file matches the sample.Your program does not have to mimic this directory structure. You can assume that python willoutput the file in the same directory as the input file (I recommend you put your input files in thecurrent working directory).Disclaimer: you are not guaranteed to be provided sample tests in the examCalculating DistanceYou can use Euclidean distance to calculate the distance between any two ducks:Consider two ducks and with associated coordinates and .1.45,10.5-3.51,0.3151.925,-9.338-9.283,3.190-0.261,-10.5283.877,-13.0030.740,-12.0949.066,10.7071.099,11.568-5.154,-6.7301.134,-5.480-13.035,-0.588The distance between the ducks can be found with the following formula:Due to floating points having some precision issues, you are allowed to correct for errors lessthan 0.0001.That means, 1.500000005135 would be considered as 1.5 in regards to the distance calculation.[P3Q2] Quack Family - SiblingsThe ProblemA duck can usually raise 12 ducklings, which is quite a lot. In the Kingdom of Mallard, there is aculture of recording their own family tree. Some family trees can trace back hundreds of years oflineage, while others have records of only the latest generation.You have found some family trees online. While you were learning about their history, you had anidea to present the family tree interactively. Specifically, you would like to interactively count andidentify the siblings and step-siblings of a given duck of interest.The provided data files present the details of each duck in a separate row in the following format:<name>, <gender>, <year of birth>, <father>, <mother>Each data field is separated by commas. An example of the file contents is shown below:The TaskWrite a function count_siblings(filename, name) . The function will read a file from the givenfilename which contains the family tree of the duck of interest. It will then determine the siblings(same father and mother) and step-siblings (same father, different mother or same mother,different father) of the duck. The function will return a string in the following format:<name> has <number> siblings: <list of siblings>, <list of step-siblings>Siblings will be listed first, followed by step-siblings. Step-siblings will also be identified with thestring (step) following their names. Regular English punctuation will need to be applied. Forexample, from the data of the sample file shown above:If the parameter filename is not a string type, then a TypeError exception is thrown with thecontents of the exception being a string "parameter filename is not a string" .If the parameter name is not a string type, then a TypeError exception is thrown with thecontents of the exception being a string "parameter name is not a string" .Theo, m, 1958, ,Ray, m, 1952, ,Stephen, m, 1979, Theo, MaryDaffy, m, 1976, Ray, MaryAnnabelle, F, 1975, John, OliviaRyan, m, 1981, Ray, PenelopeChris, m, 1981, Theo, MaryDeborah, F, 1996, Stephen, AnnabelleDominic, m, 1997, Ryan, MayBrian, M, 2007, Ray, PenelopeMelvin, m, 1981, Ray, Penelopeprint(count_siblings("family.dcf", "Brian")) ...

June 20, 2021 · 9 min · jiezi

关于c++:多位专家力推丨大量经典案例分析集锦带你深入学习Nginx底层源码

前言  说到学习不晓得大家有没有一种对常识的渴望,对技术的极致谋求。不晓得大家有没有,“或者”我有。当然学习是为了获取常识、总结学习后果,便于对将来工作利用中得心应手。随着大家的激情剑拔弩张,想帮忙更多和笔者们一样的人独特学习,笔者们就产生了写书的想法。而后大家不约而同,把对常识的渴望和激情撰写成一本书。   书中作者来自各“网校”与“根底服务中台”的多位专家,在本书发明之前,组织过对Nginx底层源码的浏览与调试。经验过数个月的学习与实际,通过积攒积淀了本书。在本书中RTMP模块的解析局部,也利用到屡次直播顶峰,经验过数百万在线直播验证。 准备常识  在学习Nginx源码之前能够对一些常识进行初步理解,把握这些常识后,这样便于对常识学习与了解。 C/C++根底:首先要把握C/C++语言根底,在浏览源码过程中,是否了解语意、语法、以及相干的业务逻辑。便于学习Nginx的相干常识。GDB调试:在本书中一些调试代码片段是采纳GDB进行调试,理解GDB调试工具也便于对Nginx的过程和一些逻辑进行调试。Nginx根底应用:学习的版本为Nginx1.16版本,如果您在浏览过程中,对Nginx的一些应用曾经理解。在浏览的过程中,能够起到一些帮忙。HTTP协定与网络编程基础知识。联结作者网校团队: 聂松松好未来学而思网校学习研发直播零碎后端负责人,负责网校外围直播零碎开发和架构工作。毕业于东北大学计算机科学与技术业余,9年以上音视频及流媒体相干工作教训,精通Nginx、ffmpeg相干技术栈。 根底服务中台: 赵禹好将来后端资深开发,曾参加自主守业。目前负责将来云容器平台kubernetes组件开发,隶属于容器iaas团队。相熟PHP、Ngnix、Redis、Mysql等源码实现,乐于钻研技术。 网校团队: 施洪宝好将来后端开发专家,东南大学硕士,对Redis、Nginx、Mysql等开源软件有较深的了解,相熟C/C++、Golang开发,乐于钻研技术,合著有<<Redis5设计与源码剖析>>。 网校团队: 景罗开源爱好者,高级技术专家,曾任搜狐团体大数据高级研发工程师、新浪微博研发工程师,7年后端架构教训,相熟PHP、Nginx、Redis、MySQL等源码实现,善于高并发解决及大型网站架构,“打造学习型团队”的践行者。 网校团队: 黄桃高级技术专家,8年后端工作教训,善于高性能网站服务架构与稳定性建设,著有《PHP7底层设计与源码实现》等书籍。 网校团队: 李乐好未来学而思网校PHP开发专家,西安电子科技大学硕士,乐于钻研技术与源码钻研,对Redis和Nginx有较深了解。合著有《Redis5设计与源码剖析》。 根底服务中台: 张报好将来团体接入层网关方向负责人,对Nginx,Tengine,Openresty等高性能web服务器有深刻了解,精通大型站点架构与流量调度零碎的设计与实现。 网校团队:闫昌好将来后端开发专家,深耕信息安全畛域多年,对Linux下服务端开发有较深见解,善于高并发业务的实现。 网校团队:田峰学而思网校学服研发部负责人。13年多的互联网从业教训,先后次要在搜狗、百度、360、好将来公司从事研发和技术团队管理工作,在高性能服务架构设计及简单业务零碎开发方面领有丰盛教训。 学习疏导  在学习的过程中,可能大部分人更关注的是收益问题。一方面是技术的硬技能收益,另一方面高阶晋升。   说到学习,那么能够整顿一些学习门路。能够通过一张图来看看学习Nginx源码都须要学习些什么内容。并且能够怎么样去学习,如图1-1所示。<center>图1-1 Nginx学习纲要</center>  通过上图,能够清晰的理解到学习Nginx源码都须要学习些什么内容。在学习初期,能够先理解Nginx源码与编译装置和Nginx架构根底与设计念想,从Nginx的劣势、源码构造、过程模型等几个方面理解Nginx。而后在学习Nginx的内存治理、从内存池、共享内存开展对Nginx内存治理与应用。紧接着能够开展对Nginx的数据结构学习,别离对字符串、数组、链表、队列、散列、红黑树、根底树的数据结构和算法应用。   学习完数据结构后,能够对Nginx的配置解析、通过main配置块、events配置块与http配置块进行学习,而后学习Nginx配置解析的全副过程。接下来能够学习过程机制,通过过程模式、master过程、worker过程,以及过程建通信机制残缺理解Nginx过程的治理。而后在学习HTTP模块,通过模块初始化流程、申请解析、HTTP的11个阶段解决,以及HTTP申请响应,把握HTTP模块的处理过程。   学习完HTTP模块后,再来学习Upsteam机制,对Upstream初始化、上下游建设、长连贯、FastCGI模块做肯定了解。   而后能够理解一些模块,比方Nginx工夫模块实现,Nginx事件模型的文件事件、工夫事件、过程池、连接池等事件处理流程。其次是Nginx的负载平衡、限流、日志等模块实现。   如果要跨平台应用Nginx,能够理解跨平台实现,对Nginx的configure编译文件,跨平台原子操作锁进行肯定理解。   对直播比拟感兴趣,还能够学习Nginx直播模块RTMP实现,通过RTMP协定,模块解决流程,进一步理解RTMP模块实现。 基础架构与设计理念  从诞生以来,Nginx始终以高性能、高牢靠、易扩大闻名于世,这得益于它诸多优良的设计理念,本章就站在宏观的角度来观赏Nginx的架构设计之美。 Nginx过程模型  现在大多数零碎都须要应答海量的用户流量,人们也越来越关注零碎的高可用、高吞吐、低延时、低消耗等个性,此时玲珑且高效的Nginx走进了大家的视线,并很快受到了人们的青眼。Nginx的全新过程模型与事件驱动设计使其能天生轻松应答C10K甚至C100K高并发场景。   Nginx应用了Master治理过程(治理过程Master)和Worker工作过程(工作过程Worker)的设计,如图2-1所示。<center>图2-1 Master-Worker过程模型</center>   Master过程负责管理各个Worker,通过信号或管道的形式来管制Worker的动作。当某个Worker异样退出时,Master过程个别会启动一个新的Worker过程代替它。Worker是真正解决用户申请的过程,各Worker过程是平等的,它们通过共享内存、原子操作等一些过程间通信机制来实现负载平衡。多过程模型的设计充分利用了SMP(Symmetrical Multi-Processing)多核架构的并发解决能力,保障了服务的健壮性。   同样是基于多过程模型,为什么Nginx能具备如此强的性能与超高的稳定性,其起因有以下几点。 异步非阻塞:  Nginx的Worker过程全程工作在异步非阻塞模式下,从TCP连贯的建设到读取内核缓冲区里的申请数据,再到各HTTP模块解决申请,或者是反向代理时将申请转发给上游服务器,最初再将响应数据发送给用户,Worker过程简直不会阻塞,当某个零碎调用产生阻塞时(例如进行I/O操作,然而操作系统还没将数据筹备好),Worker过程会立刻解决下一个申请,当条件满足时操作系统会告诉Worker过程持续实现这次操作,一个申请可能须要多个阶段能力实现,然而整体上看每个Worker始终处于高效的工作状态,因而Nginx只须要很多数Worker过程就能解决大量的并发申请。当然,这些都得益于Nginx的全异步非阻塞事件驱动框架,尤其是在Linux2.5.45之后操作系统的I/O多路复用模型中新增了epoll这款神器,让Nginx换上了全新的发动机一路狂飙到性能之巅。 CPU绑定  通常在生产环境中配置Nginx的Worker数量等于CPU外围数,同时会通过worker_cpu_affinity将Worker绑定到固定的核上,让每个Worker独享一个CPU外围,这样既能无效地防止频繁的CPU上下文切换,也能大幅提高CPU缓存命中率。 负载平衡  当客户端试图与Nginx服务器建设连贯时,操作系统内核将socket对应的fd返回给Nginx,如果每个Worker都争抢着去承受(accept)连贯就会造成驰名的“惊群”问题,也就是最终只会有一个Worker胜利承受连贯,其余Worker都白白地被作零碎唤醒,这势必会升高零碎的整体性能。另外,如果有的Worker运气不好,始终承受失败,而有的Worker自身曾经很繁忙却承受胜利,就会造成Worker之间负载的不平衡,也会升高Nginx服务器的解决能力与吞吐量。Nginx通过一把全局的accept_mutex锁与一套简略的负载平衡算法就很好的解决了这两个问题。首先每个Worker在监听之前都会通过ngx_trylock_accept_mutex无阻塞的获取accept_mutex锁,只有胜利抢到锁的Worker才会真正监听端口并accept新的连贯,而抢锁失败的Worker只能持续解决已承受连贯上的事件。其次,Nginx为每个Worker设计了一个全局变量ngx_accept_disabled,并通过如下形式对该值进行初始化: ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n  其中connection_n示意每个Worker一共可同时承受的连接数,free_connnection_n示意闲暇连接数,Worker过程启动时,闲暇连接数与可承受连接数相等,也就是ngx_accept_disabled初始值为-7/8 * connection_n。当ngx_accept_disabled为负数时,表明闲暇连接数曾经有余总数的1/8了,此时阐明该Worker过程非常忙碌,于是它本次事件循环放弃争抢accept_mutex锁,专一于解决已有的连贯,同时会将本人的ngx_accept_disabled减一,下次事件循环时持续判断是否进入抢锁环节。上面的代码摘要展现了上述算法逻辑: if (ngx_use_accept_mutex) { if (ngx_accept_disabled > 0) { ngx_accept_disabled--; } else { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return; } …… }  总体上来看这种设计略显毛糙,但它胜在简略实用,肯定水平上保护了各Worker过程的负载平衡,防止了单个Worker耗尽资源而拒绝服务,晋升了Nginx服务器的高性能与健壮性。   另外,Nginx也反对单过程工作模式,然而这种模式不能施展CPU多核的解决能力,通常只实用于本地调试。 Nginx模块化设计  Nginx主框架中只提供了大量的外围代码,大量弱小的性能是在各模块中实现的。模块设计齐全遵循了高内聚、低耦合的准则,每个模块只解决本人职责之内的配置项,专一实现某项特定的性能,各类型的模块实现了对立的接口标准,这大大加强了Nginx的灵活性与可扩展性。 ...

June 19, 2021 · 1 min · jiezi

关于c#:AgileConfig轻量级配置中心130发布支持多用户权限控制

AgileConfig 当初是设计给我本人用的一个工具,所以只设置了一道管理员明码,没有用户的概念。然而很多同学在应用过后都提出了须要多用户反对的倡议。整个团队或者整个公司都应用同一个明码来治理十分的不不便。 明天 AgileConfig 1.3.0 版本终于反对了多用户,以及简略的权限治理。用户跟权限的设计,在咱们开发管理系统的时候常常波及,最罕用的就是RBAC基于角色的权限管制。然而基于 AgileConfig 简略的理念,我略微简化了一点权限管制的功能设计,尽量的升高学习老本。 权限设计AgileConfig 的权限设计分为3个固定的角色: 超级管理员 超级管理员具备所有的管制权限,能够随便增加批改删除用户、利用、配置等等任何信息管理员 一般管理员能够新建利用,能够删除批改属于他的利用(利用的管理员属性为以后用户),以及该利用的配置项。管理员能够给任何用户受权所属利用配置项的管理权限。管理员能够增加批改删除角色为操作员的用户。操作员 操作员对利用没有任何管制权限,只能编辑或者公布下线通过管理员受权的利用的配置项。用户治理1.3.0 版本新增了多用户反对,那么用户治理是必须的性能。应用管理员级别的用户登录零碎后,点击“用户”=>“增加”按钮弹出用户新增界面。增加“用户名”、“明码”、团队等根本信息后,抉择用户的角色。点击“确定”新建用户。提醒胜利后就能够应用该用户登录零碎了。 利用受权1.3.0 版本反对对用户进行简略的受权治理。管理员在新建/编辑利用的时候能够保护一个管理员角色的用户。该账号对该利用具备齐全的管制权限。如果想要其它用户来编辑配置项,能够在受权界面进行受权。点击“受权”按钮弹出受权界面。权限分为两局部: 配置修改权:配置项的改删查权限配置高低线权:配置项的上线,下线权限。降级须要更新的数据库构造因为1.3退出了多用户的反对,新增了几张表跟字段,导致1.2降级1.3后程序运行报错的问题,须要手工调整表构造。 以下以mysql为例: agc_app表新增字段 app_admin varchar(36)新建agc_user表 CREATE TABLE `agc_user` ( `id` varchar(36) NOT NULL, `user_name` varchar(50) DEFAULT NULL, `password` varchar(50) DEFAULT NULL, `salt` varchar(36) DEFAULT NULL, `team` varchar(50) DEFAULT NULL, `create_time` datetime(3) NOT NULL, `update_time` datetime(3) DEFAULT NULL, `status` enum('Normal','Deleted') NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;新建agc_user_app_auth表 CREATE TABLE `agc_user_app_auth` ( `id` varchar(36) NOT NULL, `app_id` varchar(36) DEFAULT NULL, `user_id` varchar(36) DEFAULT NULL, `permission` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;新建agc_user_role表CREATE TABLE `agc_user_role` ( `id` varchar(36) NOT NULL, `user_id` varchar(50) DEFAULT NULL, `role` enum('SuperAdmin','Admin','NormalUser') NOT NULL, `create_time` datetime(3) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;新建实现表跟字段后从新运行程序,会提醒重置超级管理员明码,之后就能够失常应用了。 ...

June 18, 2021 · 1 min · jiezi

关于c:C语言初阶三子棋

棋盘的实现家喻户晓,三子棋棋盘其实是一个就九方格,所以咱们首先要定义一个二维数组来实现寄存棋子。每一个方格咱们规定为占三个小格例如 ’ X ',且必须有分隔符来离开棋子。 棋盘的初始化棋局开始时,棋盘必须是空的,所以咱们首先的初始化数组,将每一个元素都置为’ ',而后再来实现棋盘的性能,棋盘的初始化代码如下; void InitBoard(char board[ROW][COL], int row, int col){ for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; } }}棋盘棋盘是一个二维数组,且每一个元素都要用分隔符来分隔它们,横行用‘ | ’,竖列用‘—’。一行有三个元素所以用两个‘ | ’,有三列所以用两个‘—’。而且在‘—’所占的一行也要加‘ | ’。棋盘的实现代码如下: void ShowBoard(char board[ROW][COL], int row, int col){ printf("=====================\n"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { //三个空格 printf(" %c ", board[i][j]); //两列竖线 if (j < col - 1) { printf("|"); } } //换行 printf("\n"); //横线只有2行 if (i < row - 1) { for (int j = 0; j < col; j++) { printf("---"); // if (j < col - 1) { printf("|"); } } printf("\n"); } } printf("=====================\n");}这两步实现后,棋盘的实现就实现了 ...

June 18, 2021 · 3 min · jiezi

关于c#:CSC-503SENG-474-2

Due on: Friday, JUNE 25th at 23:59 PSTWhere: Brightspace (https://bright.uvic.ca/d2l/ho...Instructions: >? You must complete this assignment entirely on your own. In other words, you should come upwith the solution yourself, write the code yourself, conduct the experiments yourself, analyze theresults yourself, and finally, write it all solely by yourself. The university policies on academicdishonesty (a.k.a. cheating) will be taken very seriously.? This does not mean that you need to go to a cave and self-isolate while preparing the assignment.You are allowed to have high-level discussions with your classmates about the course material.You are also more than welcome to use Piazza or come to office hours and ask questions. If indoubt, ask!— we are here to help.? If you are still stuck, you can use books and published online material (i.e., material that has afixed URL). However, you must explicitly credit all sources. You are also not allowedto copy-paste online materials. Woe to you if we catch you copy-pasting the uncreditedsources!– Why “if stuck”? Assignments are designed to develop your practical ML skills and makeyou strong. If you do the assignments well, the project will feel like a piece of cake. So,give your best. But, on the other hand, do not waste a whole week on a single question:if you are stuck on a question for a few days, ask (us) for help!? If you cannot make it until the deadline, you can use a maximum of two grace days perassignment. They are not free, though: each grace day comes with the 25% mark penalty(so submitting on Monday evening would reduce your score by 25%; submitting on Tuesdaywould further reduce it by 50%). No other accommodations will be provided unless explicitlyapproved by the instructor at least 7 days before the deadline.? These assignments are supposed to be really hard! Start early! You will need at leasttwo weeks to complete them!– If you do not feel challenged enough, please let me know, and I’ll think of something.? Remember: you will need to gather at least one-third of all points during the assign-ments to pass the course. If you don’t, you will get an F!? Make sure to follow the technical requirements outlined below. TAs have the full power to take50% off your grade if you disregard some of them.? Be sure that your answers are clear and easy for TAs to understand. They can penalize you ifyour solutions lack clarity or are convoluted (in a non-algebraic way), even if they are nominallycorrect.? We will try to grade your assignments within seven (7) days of the initial submission deadline.1? If you think there is a problem with your grade, you have one week to raise concerns after thegrades go public. Grading TAs will be holding office hours during those seven days to addressany such problems. After that, your grade is set in stone.Technical matters:? You must type up your analysis and solutions electronically and submit them as a self-containingJupyter notebook. Jupyter notebooks can contain code, its output, and images. They can alsobe used to type math and proofs in LATEX mode.– You must use LATEX mode to type formulas. Typing a?2=sqrt(3)+b1 is a pretty goodway to lose 50% of your grade for no good reason.? Each problem should be submitted as a separate file.? Each file should be named SurnameInitial N.ipynb, where N is two digit-padded problemnumber. Correct: SmithJ 05.ipynb. Incorrect: JohnSmith V12345 Problem 1.ipynb,prob1.pdf etc.? Zip all ipynb files and submit them as assignment1.zip to the Brightspace. Do not submitRAR, TAR, 7zip, SHAR and whatnot; just use good ol’ ZIP. Do not include other files.? The first cell of each Jupyter notebook must start with your name and V number. See theattached notebook for the details.? Your notebook should be organized sequentially according to the problem statement. Usesections (with the appropriate numbers and labels) within the notebook. Figures and relevantcode should be placed in the proper location in the document.? Notebook code must be runnable! Ideally, all answers will be the output of a code cell.? You must use Python 3 to complete the assignments. Feel free to use NumPy and pandas asyou find it fit. Use SciPy, scikit-learn, and other non-standard libraries only when explicitlyallowed to do so.? Your first executable cell should set the random seed to 1337 to ensure the reproducibility ofyour results. For Numpy/SciPy and pandas, use numpy.random.seed(1337); otherwise, userandom.seed(1337).? Document your code! Use either Markdown cells or Python comments to let us know what youhave done!? Finally, be concise! We do not appreciate long essays that amount to basically nothing.This assignment consists of 4 problems. Some are intended only for graduate students (thosetaking CSC 503), and are labelled as such. Some contain bonus sections: you can use bonus pointsto improve your overall homework score. Bonus points cannot be transferred to other assignments orthe final project. Any graduate-level problem counts as a bonus problem for undergraduate students.Some problems are purposefully open-ended. Whatever you think the correct answer is, makesure to support it with code and data.2Problem 1. The American Handwriting [40 points]The U.S. National Institute of Standards and Technology collected digital images of the digits writtenby high school students and the U.S. Census Bureau employees over the years. These images serveas the basis of the extremely popular MNIST dataset that is commonly used to benchmark machinelearning classifiers.Wouldn’t it be a good idea to play with that dataset? To do so, install Keras and load the MNISTdataset as follows:from keras.datasets import mnist(train_X, train_y), (test_X, test_y) = mnist.load_data()Now, let’s see how we can use neural networks to classify these images. ...

June 18, 2021 · 9 min · jiezi

关于c:利用core-dump进行C项目socket编程的异常定位errno为110-Connection-timed-out

最近在一个碰到一个socket相干的异样。 环境:linux我的项目:C++,波及大量网络IO察看对象:一个常驻过程,既是客户端,也是服务端景象:特定操作后,隔132分钟后,过程便会主动退出。能通过exception异样类捕捉到errno为110, 对应的message为"Connection timed out"。剖析过程: 假如1:从该Connection time out这音讯提醒,联合该我的项目波及大量的socket通信,很天然地联想到是该过程在调用connect(),与服务端建设连贯的时候出了问题?颠覆假如1:connect()是linux的C实现的库函数,不会抛异样(异样是C++中的机制)。 假如2:回到一开始,正是因为代码里有异样捕捉,才得悉errno,的确抛了异样。那么就有可能是人为地依据errno,被动throw进去的。搜寻得悉,我的项目中有大量的throw system_error(errno, system_category()),合乎假如2。 在这种有大量可疑点的状况下,被动从代码的角度去一个个刻意点排查是很吃力的。既然定时可能复现,且有抛异样的机制。那来一个刻舟求剑,不捕获异样解决,让程序间接core dump,便可依据core文件的堆栈信息,定位到起因。 最初无效地找到问题所在:程序作为服务端,其客户端在运行过程中退出了,服务端的连贯没有进行敞开,代码层面没有close与客户端的连贯socket,且该连贯的socket设置了SO_KEEPALIVE属性。这就呈现了,默认7200s,服务端就会往一个半关上的连贯发送一个心跳报文,对方是不会回复该报文的,引发连贯超时的谬误。 解决方案:服务端在检测到客户端发动敞开连贯后,及时进行敞开连贯。惯例来说,客户端close --> 服务端接管完接收缓冲区的数据,close --> 连贯敞开。

June 18, 2021 · 1 min · jiezi

关于c++:性能分析之CPU分析从CPU调用高到具体代码行CC

明天在培训的过程中,也提到了剖析要具体到代码的事件,如果思路方向是正确的,对java利用和C/C++利用来说,也是几个命令就能够跳到代码行了。前提是要能看得懂堆栈信息。所以始终以来我在讲课的过程中都有画过这样的一个剖析思路的图。 在性能剖析中,如果是C/C++的利用的话,也同样是有些工具能够做失去的。明天咱们来看一个简略的C代码示例,看下如何做到这几步。我在网上看到有一段示例代码,也省得本人写了。就间接拿来编译用了。上面来看一下操作。[root@7dgroup Sample6]# gcc -o test6 -g test6.c编译的时候记得加-g的参数,能够生成调试信息。[root@7dgroup Sample6]# ./test6运行起来:[root@7dgroup Sample6]# ./test6返回值 :3返回值 5返回值 :5返回值 7返回值 :7返回值 9执行过程会产生这样的数据。同时查看top。看到31356这个过程曾经耗费了CPU。因为这个过程十分的简略,所以这里我就不再细化到线程级了。间接打堆栈看了。(如果是简单的利用的话,在这一步,还要再细化一步的就是打印线程级的状态。办法有多种,能够用top -H,也能够pidstat,也能够用调试工具attach下来再查threaddump。总之抉择本人喜爱的形式就好。)间接gstack打印堆栈。[root@7dgroup ~]# gstack 31356 #0 0x00000000004005ed in function2 (input=963) at test6.c:4 #1 0x000000000040065b in function1 (a=9, b=10) at test6.c:21 #2 0x00000000004006e8 in main () at test6.c:39当然你也能够pstack打印堆栈(因为我从新运行了一次,所以PID变了)。[root@7dgroup ~]# pstack 31438 #0 0x0000000000400620 in function3 (input=3524) at test6.c:14 #1 0x000000000040067e in function1 (a=5, b=6) at test6.c:25 #2 0x00000000004006e8 in main () at test6.c:39 ...

June 17, 2021 · 1 min · jiezi

关于c++:百度C工程师的那些极限优化并发篇

导读:对于工程教训比拟丰盛的同学,并发应该也并不是生疏的概念了,然而每个人所了解的并发问题,却又往往并不对立,本文零碎梳理了百度C++工程师在进行并发优化时所作的工作。 全文15706字,预计浏览工夫24分钟。 一、背景简略回顾一下,一个程序的性能形成要件大略有三个,即算法复杂度、IO开销和并发能力。因为古代计算机体系结构复杂化,造成很多时候,工程师的性能优化会更集中在算法复杂度之外的另外两个方向上,即IO和并发,在之前的《百度C++工程师的那些极限优化(内存篇)》中,咱们介绍了百度C++工程师工程师为了优化性能,从内存IO角度登程所做的一些优化案例。 这次咱们就再来聊一聊另外一个性能优化的方向,也就是所谓的并发优化。和IO方向相似,对于工程教训比拟丰盛的同学,并发应该也并不是生疏的概念了,然而每个人所了解的并发问题,却又往往并不对立。所以上面咱们先回到一个更基本的问题,从新梳理一下所谓的并发优化。 是的,这个问题可能有些跳跃,然而在天然地停顿到如何解决各种并发问题之前,咱们的确须要先停下来,回忆一下为什么咱们须要并发? 这时第一个会冒出来的概念可能会是大规模,例如咱们要设计大规模互联网利用,大规模机器学习零碎。可是咱们认真思考一下,无论应用了那种水平的并发设计,这样的规模化零碎背地,都须要成千盈百的实例来撑持。也就是,如果一个设计(尤其是无状态计算服务设计)曾经能够反对某种小规模业务。那么当规模扩充时,很可能伎俩并不是晋升某个业务单元的解决能力,而是减少更多业务单元,并解决可能遇到的分布式问题。 其实真正让并发编程变得有价值的背景,更多是业务单元自身的解决能力无奈满足需要,例如一次申请解决工夫过久,业务精细化导致复杂度积攒晋升等等问题。那么又是什么导致了近些年来,业务单元解决能力问题有余的问题出现更加突出的趋势? 可能上面这个统计会很阐明问题: (https://www.karlrupp.net/2015...) 上图从一个长线角度,统计了CPU的外围指标参数趋势。从其中的晶体管数目趋势能够看出,尽管可能逐步艰巨,然而摩尔定律仍然尚能维持。然而近十多年,出于管制功耗等因素的思考,CPU的主频增长根本曾经停滞,继续减少的晶体管转而用来构建了更多的外围。 从CPU厂商角度来看,单片处理器所能提供的性能还是放弃了继续晋升的,然而单线程的性能增长曾经显著放缓。从工程师角度来看,最大的变动是硬件红利不再能通明地转化成程序的性能晋升了。随时代提高,更精准的算法,更简单的计算需要,都在对的计算性能提出继续晋升的要求。早些年,这些算力的增长需要大部分还能够通过处理器更新换代来天然解决,可是随着主频增长停滞,如果无奈利用多外围来减速,程序的解决性能就会随主频一起面临增长停滞的问题。因而近些年来,是否可能充分利用多外围计算,也越来越成为高性能程序的一个标签,也只有具备了充沛的多外围利用能力,能力随新型硬件演进,持续体现出指数级的性能晋升。而随同多外围多线程程序设计的遍及,如何解决好程序的并发也逐步成了工程师的一项必要技能。 上图形容了并发减速的基本原理,首先是对原始算法的繁多执行块拆分成多个可能同时运行的子工作,并设计好子工作间的协同。之后利用底层的并行执行部件能力,将多个子工作在工夫上真正重叠起来,达到真正晋升处理速度的目标。 须要留神的是还有一条从下而上的反向剪头,次要表白了,为了正确高效地利用并行执行部件,往往会反向领导下层的并发设计,例如正确地数据对齐,正当的临界区实现等。尽管减速看似齐全是由底层并行执行部件的能力所带来的,程序设计上只须要做到子工作拆分即可。然而现阶段,执行部件对下层还无奈达到通明的水平,导致这条反向依赖对于最终的正确性和性能仍然至关重要。既理解算法,又了解底层设计,并联合起来实现正当的并发革新,也就成为了工程师的一项重要技能。 三、单线程中的并行执行提到并行执行部件,大家的第一个印象往往时多外围多线程技术。不过在进入到多线程之前,咱们先来看看,即便是单线程的程序设计中,仍然须要关注的那些并行执行能力。回过头再认真看前文的处理器趋势图其实能够发现,尽管近年主频不再增长,甚至稳中有降,然而单线程解决性能其实还是有轻微的晋升的。这其实意味着,在单位时钟周期上,单核心的计算能力仍然在晋升,而这种晋升,很大水平上就得益于单核心单线程内的细粒度并行执行能力。 3.1 SIMD其中一个重要的细粒度并行能力就是SIMD(Single Instruction Multiple Data),也就是多个执行单元,同时对多个数据利用雷同指令进行计算的模式。在经典分类上,个别单核心CPU被纳入SISD(Single Instruction Single Data),而多外围CPU被纳入MIMD(Mingle Instruction Multiple D ata),而GPU才被纳入SIMD的领域。然而古代CPU上,除了多外围的MIMD根底模型,也同时附带了细粒度SIMD计算能力。 上图是Intel对于SIMD指令的一个示意图,通过减少更大位宽的寄存器实现在一个寄存器中,“压缩”保留多个较小位宽数据的能力。再通过减少非凡的运算指令,对寄存器中的每个小位宽的数据元素,批量实现某种雷同的计算操作,例如图示中最典型的对位相加运算。以这个对位相加操作为例,CPU只须要增大寄存器,内存传输和计算部件位宽,针对这个非凡的利用场景,就晋升到了8倍的计算性能。相比将外围数通用地晋升到8倍大小,这种形式付出的老本是非常少的,指令流水线零碎,缓存零碎都做到了复用。 从CPU倒退的视角来看,为了可能在单位周期内解决更多数据,减少外围数的MIMD强化是最直观的实现门路。然而减少一套外围,就象征减少一套 残缺的指令部件、流水线部件和缓存部件,而且理论利用时,还要思考额定的外围间数据扩散和聚合的传输和同步开销。一方面昂扬的部件需要, 导致残缺的外围扩大老本过高,另一方面,多外围间传输和同步的开销针对小数据集场景额定耗费过大,还会进一步限度利用范畴。为了最大限度利用好无限的晶体管,古代CPU在塑造更多外围的同时,也在另一个维度上扩大单核心的解决和计算位宽,从而实现晋升实践计算性能(外围数 * 数据宽度)的目标。 不过提起CPU上的SIMD指令反对,有一个绕不开的话题就是和GPU的比照。CPU上晚期SIMD指令集(MMX)的诞生背景,和GPU的功能定位就非常相似,专一于减速图像相干算法,近些年又随着神经网络计算的衰亡,转向通用矩阵类计算减速。然而因为GPU在设计根底上就以面向密集可反复计算负载设计,指令部件、流水线部件和缓存部件等能够远比CPU简洁,也因而更容易在量级上进行扩大。这就导致,当计算密度足够大,数据的传输和同步开销被足够冲淡的状况下(这也是典型神经网络计算的的个性),CPU仅作为控制流进行指挥,而数据批量传输到GPU协同执行反而 会更简略高效。 因为Intel本身对SIMD指令集的宣传,也集中围绕神经网络类计算来开展,而在以后工程实践经验上,支流的密集计算又以GPU实现为主。这就导致了不少CPU上SIMD指令集无用论应运而生,尤其是近两年Intel在AVX512初代型号上的降频事件,进一步强化了『CPU就应该做好CPU该做的事件』这一论调。然而单单从这一的视角来意识CPU上的SIMD指令又未免有些全面,容易漠视掉一些真正有意义的CPU上SIMD利用场景。 对于一段程序来讲,如果将每读取单位数据,对应的纯计算复杂度大小定义为计算密度,而将算法在不同数据单元上执行的计算流的雷同水平定义为模式反复度,那么能够以此将程序划分为4个象限。在大密度可反复的计算负载(典型的重型神经网络计算),和显著小密度和非反复计算负载(例如HTML树状解析)场景下,业界在CPU和GPU的选取上其实是有绝对明确“最优解”的。不过对于过渡地带,计算的反复特色没有那么强,  或者运算密度没有那么大的场景下,单方的弱点都会被进一步放大。即使是规整可反复的计算负载,随着计算自身强度减小,传输和启动老本逐步显著。另一方面,即使是不太规整可反复的计算负载,随着计算负荷加大,外围数有余也会逐步成为瓶颈。这时候,引入SIMD的CPU和引入SIMT 的GPU间如何抉择和应用,就造成了没有那么明确,见仁见智的衡量空间。 即便排除了重型神经网络,从程序的个别个性而言,具备肯定规模的反复个性也是一种普遍现象。例如从概念上讲,程序中的循环段落,都或多或少意味着批量/反复的计算负载。只管因为掺杂着分支管制,导致反复得没有那么纯正,但这种肯定规模的细粒度反复,正是CPU上SIMD施展独特价值的中央。例如最常见的SIMD优化其实就是memcpy,古代的memcpy实现会探测CPU所能反对的SIMD指令位宽,并尽力应用来减速内存传输。另一方面古代编译器也会利用SIMD指令来是优化对象拷贝,进行简略循环向量化等形式来进行减速。相似这样的一类优化办法偏『主动通明』,也是默默撑持着主频不变状况下,性能稍有回升的重要推手。 惋惜这类简略的主动优化能做到的事件还相当无限,为了可能充分利用CPU上的SIMD减速,现阶段还十分依赖程序层进行被动算法适应性革新,有 目的地应用,换言之,就是被动施行这种单线程内的并发革新。一个无奈主动优化的例子就是《内存篇》中提到的字符串切分的优化,现阶段通过编译器剖析还很难从循环 + 判断分支提取出数据并行pattern并转换成SIMD化的match&mask动作。而更为显著的是近年来一批针对SIMD指令从新设计的算法,例如Swiss Table哈希表,simdjson解析库,base64编解码库等,在各自的畛域都带来了倍数级的晋升,而这一类算法适应性革新,就曾经齐全脱离了主动通明所能涉及的范畴。能够预知近些年,尤其随着先进工艺下AVX512降频问题的逐步解决,还会/也须要涌现出更多的传统根底算法的SIMD革新。而纯熟使用SIMD指令优化技术,也将成为C++工程师的一项必要技能。 3.2 OoOE另一个重要的单线程内并行能力就是乱序执行OoOE(Out of Order Execution)。经典教科书上的CPU流水线机制个别形容如下(经典5级RISC流水线)。 指令简化表白为取指/译码/计算/访存/写回环节,当执行环节遇到数据依赖,以及缓存未命中等场景,就会导致整体进展的产生。其中MEM环节的影响尤其显著,次要也是因为缓存档次的深入和多外围的共享景象,带来单次访存所需周期数参差不齐的景象越来越重大。上图中的流水线在多层缓存下的体现,可能更像下图所示: 为了加重进展的影响,古代面向性能优化的CPU个别引入了乱序执行联合超标量的技术。也就是一方面,对于重点执行部件,比方计算部件,访存部件等,减少多份来反对并行。另一方面,在执行部件前引入缓冲池/队列机制,通用更长的预测执行来尽可能打满每个部件。最终从流水线模式,转向了更相似『多线程』的设计模式: 乱序执行零碎中,个别会将通过预测保护一个较长的指令序列,并构建一个指令池,通过解析指令池内的依赖关系,造成一张DAG(有向无环图) 组织的网状结构。通过对DAG关系的计算,其中依赖就绪的指令,就能够进入执行态,被提交到理论的执行部件中解决。执行部件相似多线程模型中的工作线程,依据个性细分为计算和访存两类。计算类个别有绝对固定可预期的执行周期,而访存类因为指令周期差别较大,采纳了异步回调的模型,通过Load/Store Buffer反对同时发动数十个访存操作。 乱序执行零碎和传统流水线模式的区别次要体现在,当一条访存指令因为Cache Miss而无奈立刻实现时,其后无依赖关系的指令能够插队执行(相似于多线程模型中某个线程阻塞后,OS将其挂起并调度其余线程)。插队的计算类指令能够填补空窗充分利用计算能力,而插队的访存指令通过更早启动传输,让访存进展期尽量重叠来减小整体的进展。因而乱序执行零碎的效率,很大水平上会受到窗口内指令DAG的『扁平』水平的影响,依赖深度较浅的DAG能够提供更高的指令级并发能力,进而提供更高的执行部件利用率,以及更少的进展周期。另一方面,因为Load/Store Buffer也有最大的容量限度,解决较大区域的内存拜访负载时,将可能带来更深层穿透的访存指令尽量凑近排布,来进步访存进展的重叠,也可能无效缩小整体的进展。 尽管实践比拟清晰,可是在实践中,仅仅从内部指标观测到的性能体现,往往难以定位乱序执行零碎外部的热点。最直白的CPU利用率其实只能表白线程未受阻塞,实在在应用CPU的工夫周期,然而其实并不能体现CPU外部部件真正的利用效率如何。略微进阶一些的IPC(Instruction Per Cyc le),能够绝对深刻地反馈一些利用效力,然而影响IPC的因素又多种多样。是指令并行度有余?还是长周期ALU计算负载大?又或者是访存进展过久?甚至可能是分支预测失败率过高?实在程序中,这几项问题往往是并存的,而且繁多地统计往往又难以对立比拟,例如10次访存进展/20次ALU 未打满/30个周期的页表遍历,到底意味着瓶颈在哪里?这个问题繁多的指标往往就难以答复了。 ...

June 17, 2021 · 2 min · jiezi

关于c++:VisualStudio-2019-C单元测试框架CppUnitTest配置说明

问题形容:在开发过程中,咱们须要对本人写的算法进行测试,应用应用调试工具、或者运行起来调会存在测试不到位,测试效率低下等问题,应用单元测试会好很多,它效率高、容易了解,并且更合乎基于TDD(测试驱动开发)的思维,这里将Vs 下C++单元测试框架CppUnitTest的配置过程记录如下。 注释内容:首先,单元测试我的项目在Visual Studio中会随着装置各种不同的语言环境默认装置,比方装置了.net 开发环境时会装置NUnit MSTest等测试框架。这里咱们简略介绍一下C/C++开发时Visual Studio能够为咱们提供的便当之处。 装置Visual Studio2019在首次装置时只有抉择了”应用C++的桌面开发”,这个时候就会默认装置google test 模块和Boost Test模块,如图:应用,首先咱们创立一个空解决方案,而后在空解决方案下建设一个基于C++的空我的项目,咱们命名为”ProjForUnittest”咱们简略创立一个C++的类,并创立一个返回值为int的函数,用作单元测试的解说。这里咱们创立了一个叫做Calc的类,而后创立并实现了一个名称为Add的函数,其作用为将x,y两个参数相加并返回这个后果。创立测试项目CppUnittest鼠标点选解决方案右键->增加->新建我的项目,咱们在我的项目模板搜寻栏中输出Test,会呈现如下界面咱们能够看到标注语言为C++的两个单元测试我的项目模板,一个是Google Test,另一个是本机单元测试我的项目,其中本机单元测试我的项目源自于微软,绝对简略,咱们这里抉择它进行创立,创立好之后,目录如下我的项目设置(1) 将测试指标我的项目的配置类型变更为动静库 .dll 或动态库 .lib点选测试指标我的项目右键->属性->惯例->配置类型->动态库(.lib) (2) 将测试指标我的项目和测试项目的输入目录都批改为ProjectDir(默认设置是SolutionDir)属性->惯例->输入目录,将SolutionDir替换为ProjectDir(3) 将测试指标我的项目增加至单元测试我的项目援用中选中单元测试我的项目下的“援用”节点右键->增加援用->抉择测试指标我的项目点击确定(4) 将测试指标我的项目中公开的头文件所在目录增加至单元测试我的项目的附加蕴含目录选中单元测试我的项目右键->C/C++->惯例->附加蕴含目录->编辑点击增加目录按钮,抉择测试目标目录的头文件所在目录。(5) 将测试指标我的项目的.lib 或 .dll 文件的输入目录增加至单元测试文件的附加库目录,并增加.lib文件名(为测试指标我的项目的名称)至附加依赖库。1 增加附加库目录测试项目右键属性->链接器->惯例->附加库目录(同上第4条操作)将lib文件的输入目录增加到列表中(个别测试时应用的是我的项目目录下的Debug目录)2 增加库文件至附加依赖库测试项目右键属性->链接器->输出->附加依赖库在随后关上的文本框中输出.lib(指代指标测试项目输入的lib文件名。)以上就是C++单元测试我的项目之间的配置过程。

June 15, 2021 · 1 min · jiezi

关于c:C语言之拒绝scanf从我做起

大家好,我来了,我是萌杰尔前段时间,我想实现一个命令行工具(相似cmd.exe那种的),于是捡起了万年不必的C语言,写起了输入输出。 问题就出在这里了,我用的scanf函数不承受空字符,只有我不输出货色,按回车还是无奈完结,这我能忍??? 作为一个在计算机这块混了八年的混子,我必定有我的方法,可能不肯定好,然而能够解决当下的这个问题。 我想,很多敌人曾经晓得怎么办了,然而还是有些萌新遇到这种问题不晓得如何解决,那我明天就来讲一讲吧。 解题思路我的思路是应用一个循环,通过getchar函数继续一直的接管字符,而后把字符存储到字符串中。 说干就干,昨天晚上我花了一点工夫实现这个性能,上面展现一下我的代码。 #include <stdio.h>#include <string.h>int main(int argc, char const *argv[]){ //外层循环,让程序每次执行完一个命令就返回到初始中央从新输出命令 while (1) { //命令字符串 char command[128]; //累加器,示意以后输出的字符对应命令字符串中的下标 int scannerIndex = 0; //清空命令字符串(防止缓冲区问题) memset(command, 0, sizeof(command)); //打印Command printf("Command > "); //里层循环,接管字符 while (1) { //接管字符临时存储地位 char buff = getchar(); //判断该字符是否为回车,如果是,就让累加器归零并且退出循环 if (buff == '\n') { scannerIndex = 0; break; } //如果不是,就将输出的字符保留到命令字符串中 command[scannerIndex] = buff; //累加器的值减少 scannerIndex++; } //判断命令是否为空,如果为空,让循环进行从新执行 if (strlen(command) == 0) continue; //这上面能够开始写命令操作的内容了 //Code Here } return 0;}执行后果如下能够看到当我留空时会间接从新执行,解决了scanf的问题。 ...

June 15, 2021 · 2 min · jiezi

关于c++:Markdown语法学习

Markdown语法学习1题目设置二级题目三级题目 四级题目 <!--题目 # + 空格 题目名称--> 2字体Hello World <!-- 加粗 字体 --> Hello World<!-- 斜体 字体 --> Hello World<!--斜体加粗 字体 --> Hello World <!--删除 字体--> 3援用good good study,day day up <!-- >援用内容 -->4分隔号<!-- --- 或 * --> 5图片![截图]() <!-- 本地图片 ctrl + shift + i --> 6超链接点击跳转到百度 7 列表无序列表AB <!-- 数字 + . + 空格 -->无序列表AB <!-- - + 空格 + 数字 -->8表格 <!-- 举荐应用鼠标右键增加啊表格 --> ...

June 13, 2021 · 1 min · jiezi

关于c#:C中委托和事件的区别

C#中委托和事件的区别大抵来说,委托是一个类,该类外部保护着一个字段,指向一个办法。事件能够被看作一个委托类型的变量,通过事件注册、勾销多个委托或办法。本篇别离通过委托和事件执行多个办法,从中领会两者的区别。 □ 通过委托执行办法 class Program{ static void Main(string[] args) { Example example = new Example(); example.Go(); Console.ReadKey(); }}public class Example{ public delegate void DoSth(string str); internal void Go() { //申明一个委托变量,并把已知办法作为其构造函数的参数 DoSth d = new DoSth(Print); string str = "Hello,World"; //通过委托的静态方法Invoke触发委托 d.Invoke(str); } void Print(string str) { Console.WriteLine(str); }}以上, ○ 在CLR运行时,委托DoSth实际上就一个类,该类有一个参数类型为办法的构造函数,并且提供了一个Invoke实例办法,用来触发委托的执行。○ 委托DoSth定义了办法的参数和返回类型○ 通过委托DoSth的构造函数,能够把合乎定义的办法赋值给委托○ 调用委托的实例办法Invoke执行了办法 但,实际上让委托执行办法还有另外一种形式,那就是:委托变量(参数列表) public class Example{ public delegate void DoSth(object sender, EventArgs e); internal void Go() { //申明一个委托变量,并把已知办法作为其构造函数的参数 DoSth d = new DoSth(Print); object sender = 10; EventArgs e = new EventArgs(); d(sender, e); } void Print(object sender, EventArgs e) { Console.WriteLine(sender); }}以上, ...

June 12, 2021 · 2 min · jiezi

关于c:Centos-7安装Pyqt5Qt-Designer以及配置Vscode教程

最近筹备学习Python GUI,除了要写代码的实现外,目前认为最快捷的形式预计是PyQt了,在配置环境的过程中,网上的教程都是基于Windows的,也有基于Ubuntu的,但始终没有找到CentOS下的教程,走了不少弯路,通过摸索,终于搞定。Ubuntu下的装置形式: sudo apt-get install qttools5-dev-toolsbut:......在centos下出错。。。 一、Python装置这一部分没什么好说的,网上有大量的教程,按图索骥就行。 二、装置Pyqt5PyQt5 有两种装置形式,一种是从官网下载源码装置,另外一种是应用 pip 装置。 这里我举荐大家应用pip 装置。因为它会主动依据你的Python 版本来抉择适合的 PyQt5 版本,如果是手动下载源码装置,难免会抉择出错。倡议应用比拟稳当的装置形式。 pip3 install PyQt5个别这种形式在国内的环境会比较慢,有可能会提醒装置失败,这里倡议应用国内装置源(豆瓣)的形式解决: pip install PyQt5 -i https://pypi.douban.com/simple三、装置 PyQt5-tools同样应用国内镜像装置 pip install PyQt5-tools -i https://pypi.douban.com/simple四、配置Vscode1.装置pyqt integration扩大 2.配置pyqt integration这里有个Qt designer门路的设置问题,因为咱们没有独自装置Qt designer,装置PyQt5-tools的时候曾经装置好Qt designer了,每台电脑的门路又不尽相同,所以刚开始寻找起来比拟麻烦,这里举荐应用Linux find命令来定位相干文件的地位。 find / -name designer找到QT designer门路后,复制并配置在pyqt integration里 在文件治理,空白处右键抉择PYQT:New Form建设表单 关上QT Designer,并创立一个表单保留ui文件,返回Vscode 右键选中方才创立的ui文件,抉择PYQT:Compile Form,生成同名的python文件 生成的代码: 尝试运行刚刚生成的“Ui_mainus.py”是没用的,因为生成的文件并没有程序入口。因而咱们在同一个目录下另外创立一个程序叫做“main.py”,并输出如下内容,将Ui_untitled替换为你生成.py文件名。 import sysfrom PyQt5.QtWidgets import QApplication, QMainWindowimport Ui_mainusif __name__ == '__main__': app = QApplication(sys.argv) MainWindow = QMainWindow() ui = Ui_mainus.Ui_Dialog() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_()) ...

June 12, 2021 · 1 min · jiezi

关于c#:C-学习笔记-6委托

委托是c#最重要的个性之一,c#前面所有的个性根本都是建设在委托的根底之上。1.c#的委托是什么c# 中的委托能够了解为函数的一个包装,C#中的函数已参数的形式进行传递,这绝对与C++中的函数指针。 委托的定义和办法的定义相似,在定义后面加上delegate关键字。举例: class Program { delegate void RunCmd(); // 申明委托类型 static RunCmd runcmd1; // 申明委托对象变量 static RunCmd runcmd2; // 申明委托对象变量 static RunCmd runcmd3; // 申明委托对象变量 public static void RunCmdExecute() { Console.Write("execute"); } public void RunCmdPause() { Console.Write("Puase"); } static void Main(string[] args) { runcmd1 = new RunCmd(RunCmdExecute);//创立委托对象,静态方法 //runcmd1 = RunCmdExecute; // 快捷语法集体不倡议应用 runcmd1 = new RunCmd(new Program().RunCmdPause);//创立委托对象,实例办法 //runcmd1 += new Program().RunCmdPause; // 快捷语法 runcmd1(); // 留神只会输入最初一个“pause” // 组合委托 runcmd1 = RunCmdExecute; runcmd2 = new Program().RunCmdPause; runcmd3 = runcmd1 + runcmd2; runcmd3(); // 输入 “executePuase” Console.Read(); } }委托的调用除了像办法(函数一样)还有一种是应用委托的Invoke办法。举例:runcmd1.Invoke(); //invoke翻译为征引(某人、某实践、实例等作为反对);留神调用委托不能为空,否则会引发异样。 ...

June 11, 2021 · 1 min · jiezi

关于c++:C内存管理14SBH行为分析分配释放之连续动作图解

第一次,调配 知识点补充LPVOID VirtualAlloc{ LPVOID lpAddress, // 要调配的内存区域的地址 (当实参为0时,由操作系统指定地址) DWORD dwSize, // 调配的大小 DWORD flAllocationType, // 调配的类型 DWORD flProtect // 该内存的初始爱护属性};1. virtualAlloc 是一个 Window API 函数,该函数的性能是在调用过程的虚拟地址空间预约或者提交一部分页2. flAllocationType : MEM_RESERVE 保留调配地址,不调配物理内存。这样能够阻止其它调配函数 malloc 和 LocalAlloc 等再应用已保留的内存范畴,直到它被开释 MEM_COMMIT 为指定地址空间提交物理内存。这个函数初始化外在为零typedef struct tagGroup { int cntEntries; struct tagListHead listHead[64];}GROUP, *PGROUP;1. int cntEntries, 累计量,内存调配时+1,内存开释时-1。当 cntEntries 为 0 ,示意 8 page 全副发出,就能够将此内存块归还给操作系统typedef unsigned int BITVEC;typedef struct tagRegion { int indGroupUes; ...... BITVEC bitvGroupHi[32]; BITVEC bitvGroupLo[32]; struct tagGroup grtHeadList[32];}1. indGroupUes, 定位以后正在应用的 Group 索引2. 32 组 GROUP 对应 32 * 64 bit,当 bitvGroup[i][j] (第 i 个 GROUP 中的第 j 条双向链表)的 bit 位为 1 示意链表有可用内存块, 为 0 示意链![image.png](/img/bVcSzQZ)typedef struct tagEntry{ int sizeFront; struct tagEntry *pEntryNext; struct tagEntry *pEntryPrev;}ENTRY, *PENTRY;1. pEntryNext、pEntryPrev 为嵌入式指针,在内存块调配前后调配后有不同的解释流程形容1. 由 ioinit.c, line#18 申请 100h,区块大小 130h (debugheader、cookie、16字节对齐调整)2. 应用 Group[indGroupUes] => Group[0] ; bitvGroup[indGroupUes] [130h = 304 * 16 - 1] => bitvGroup[0] [18] bit 为 0,表明对应 Group[0][18] (listHead[18])链表中无可用区块,于是持续向右查找,Group[0][63] 最初一条链表有可用区块3. 进行内存切割(参见上节文章流程)第二次,调配__crtGetEnvironmentStringsA() 发动 ...

June 11, 2021 · 2 min · jiezi

关于c++:性能工具之代码级剖析工具

上次有人提到说下分析工具。所以再来聊聊代码级分析工具。不管怎么吹,代码级分析工具对性能自身的损耗都是存在的。并且损耗还不小。即便是在偏底层做,也照样有很大的损耗。20-30%损耗都是失常的。 要找好代码级工具的切入点,一开始就用必定是不理智。只有剖析到了某一个具体的过程或线程,或者曾经有了可疑代码的具体方法,再上代码级分析工具就更有目的性了。 JAVA方向:对JAVA来说,代码级的分析工具有好多。自带的就有不少,像当初SUN JDK中的jvirtualVM就能够实时看CPU和内存在一个办法和对象上的耗费。还有jstack/jmap等工具可辅助。如果不想实时看,做下dump也能够看内存的占用。然而要想看办法调用工夫就比拟吃力一点。不过当初有不少的商业工具,比如说jprofiler,这工具直到现在还是我所见到的在java分析中性能最全面的工具(它是商业的)。不仅有树结构,还有调用图。倡议大家尽量找到可代替的适宜的开源工具。 C/C++方向:在这个方向上,其实不止有专门的代码级分析工具,像valgrind, google perftools。也有零碎级的调试工具能够用。各种的trace工具,像perf/systemtap/oprofile之类的也都可用,并且内核级工具损耗要小一些。在solaris上有Dtrace,那本《性能之颠》的书里简直全是Dtrace工具的例子。 并且这些工具还能生成火焰图、热力求之类的。 在其余语言上也有相应的分析工具可用。像PHP有 Xdebug、xhprof;python有cprofile、memoryprofiler、lineprofiler;.net有CLR profiler;Go语言有pprof(这个是移植过去的,google perf中的工具更多)。不论是什么语言,简直相似的工具都存在的。有了这些工具,再加上零碎级的调试工具,找到代码级性能问题就是分分钟的事。 当然,还是要强调人的思考能力在社会提高中的重要性,千万不要拿着榔头打枣,够不够得着不说,举一会也够累的。适宜的工具最重要。

June 10, 2021 · 1 min · jiezi

关于c++:Qt-自定义组件动态曲线

自定义组件_滚动横幅&弹窗&对话框&字体图标等自定义组件_圆弧进度条自定义组件_水波进度条自定义组件_多彩仪表盘自定义组件_通用仪表盘自定义组件_网格组件(GirdWidget)自定义组件_动静曲线 仓库 个性可设置 Y 轴范畴、标签格局、tick 数量可设置 X 轴时间跨度、工夫格局、tick 数量可显示任意多条曲线、设置对应曲线色彩及数值点是否显示可设置曲线更新工夫距离可抉择暗藏曲线自适应窗体拉伸,图表主动缩放#ifndef DYNAMICLINE_H#define DYNAMICLINE_H#include <QChart>#include <QChartView>#include <QDateTime>#include <QDateTimeAxis>#include <QLineSeries>#include <QTimer>#include <QValueAxis>#include <QVector>#include <QWidget>using namespace QtCharts;/* 动静曲线 * 1. 可设置 Y 轴范畴、标签格局、tick 数量 * 2. 可设置 X 轴时间跨度、工夫格局、tick 数量 * 3. 可显示任意多条曲线、设置对应曲线色彩及数值点是否显示 * 4. 可设置曲线更新工夫距离 * 5. 可抉择暗藏曲线 * 6. 自适应窗体拉伸,图表主动缩放 */class DynamicLine : public QWidget{ Q_OBJECTpublic: explicit DynamicLine(QWidget *parent = nullptr); ~DynamicLine(); void start(int intervalMsec = 1000); // 开始更新图表 void stop(); // 进行更新图表 int count() const; // 曲线数量 qint64 timeAxisXSpanSecs() const; // X 轴时间跨度 void addSplineSeries(const QString &name = "", const QPen &pen = QPen(), bool pointsVisible = false); // 增加一条新的曲线public slots: void setSeriesValues(int index, int value); // 设置曲线值 void setSeriesVisible(int index, bool visible); // 设置曲线是否可见 void setChartTitle(const QString &title); // 设置图表题目 void setTimeAxisXSpanSecs(qint64 secs); // 设置 X 轴时间跨度 void setTimeAxisXFormat(const QString &format = "HH:mm"); // 设置 X 轴工夫格局 void setTimeAxisXTickCount(int tickCount); // 设置 X 轴 tick 数量 void setAxisYRange(qreal min, qreal max); // 设置 Y 轴范畴 void setpAxisYTickCount(int count); // 设置 Y 轴 tick 数量 void setAxisYLabelFormat(const QString &format); // 设置 Y 轴标签格局private: void initUi(); void initCtrl(); QLineSeries *createSeries(QChart *chart, const QString &name, const QPen &pen, bool pointsVisible = false);private slots: void updateChart();private: QVector<QLineSeries*> m_series; QChartView* m_pChartView = nullptr; QChart* m_pChart = nullptr; QDateTimeAxis* m_pTimeAxisX = nullptr; QValueAxis* m_pAxisY = nullptr; qint64 m_spanSecs = 60; QVector<int> m_lastValues; bool m_isFirstTime = false; QTimer m_timer;};#endif // DYNAMICLINE_H

June 9, 2021 · 2 min · jiezi

关于c++:千万不要错过的后端纯干货面试知识点整理-I

C++面试题 语言相干根底题对象复用的理解,零拷贝的理解 对象复用 指得是设计模式,对象能够采纳不同的设计模式达到复用的目标,最常见的就是继承和组合模式了。 零拷贝: 零拷贝次要的工作就是防止CPU将数据从一块存储拷贝到另外一块存储,次要就是利用各种零拷贝技术,防止让CPU做大量的数据拷贝工作,缩小不必要的拷贝,或者让别的组件来做这一类简略的数据传输工作,让CPU解脱进去专一于别的工作。这样就能够让系统资源的利用更加无效。 零拷贝技术常见linux中,例如用户空间到内核空间的拷贝,这个是没有必要的,咱们能够采纳零拷贝技术,这个技术就是通过mmap,间接将内核空间的数据通过映射的办法映射到用户空间上,即物理上共用这段数据。 介绍C++所有的构造函数默认构造函数、个别构造函数、拷贝构造函数 默认构造函数(无参数):如果创立一个类你没有写任何构造函数,则零碎会主动生成默认的构造函数,或者写了一个不带任何形参的构造函数个别构造函数:个别构造函数能够有各种参数模式,一个类能够有多个个别构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)拷贝结构函数参数为类对象自身的援用,用于依据一个已存在的对象复制出一个新的该类的对象,个别在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中。参数(对象的援用)是不可变的(const类型)。此函数常常用在函数调用时用户定义类型的值传递及返回。为什么要内存对齐? 平台起因(移植起因):不是所有的硬件平台都能拜访任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异样。性能起因:数据结构(尤其是栈)应该尽可能地在天然边界上对齐。起因在于,为了拜访未对齐的内存,处理器须要作两次内存拜访;而对齐的内存拜访仅须要一次拜访。成员初始化列表的概念,为什么用成员初始化列表会快一些? 类型一 : 内置数据类型,复合类型(指针,援用) 类型二 : 用户定义类型(类类型) 对于类型一,在成员初始化列表和构造函数体内进行,在性能和后果上都是一样的 对于类型二,后果上雷同,然而性能上存在很大的差异 因为类类型的数据成员对象在进入函数体是曾经结构实现,也就是说在成员初始化列表处进行结构对象的工作,这是调用一个构造函数, 在进入函数体之后,进行的是 对曾经结构好的类对象的赋值,又调用个拷贝赋值操作符能力实现(如果并未提供,则应用编译器提供的默认按成员赋值行为) 简略的来说: 对于用户定义类型: 如果应用类初始化列表,间接调用对应的构造函数即实现初始化如果在构造函数中初始化,那么首先调用默认的构造函数,而后调用指定的构造函数所以对于用户定义类型,应用列表初始化能够缩小一次默认结构函数调用过程 c/c++ 程序调试办法 printf 大法(日志)本人封装宏函数,进行打印出错地位的文件,行号,函数 通过gcc -DDEBUG_EN 关上调试信息输入 #ifdefine DEBUG_EN#define DEBUG(fmt, args...) \do { \printf("DEBUG:%s-%d-%s "fmt, __FILE__, __LINE__, __FUNCTION__, ##args);\}while(0) #define ERROR(fmt, args...) \do { \printf("ERROR:%s-%d-%s "fmt, __FILE__, __LINE__, __FUNCTION__, ##args);\}while(0)#else#define DEBUG(fmt, args) do{}while(0)#define ERROR(fmt, args) do{}while(0)#endifcore-dump/map 调试当程序运行的过程中异样终止或解体,操作系统会将程序过后的内存状态记录下来,保留在一个文件中,这种行为就叫做Core Dump. MAP 文件是程序的全局符号、源文件和代码行号信息的惟一的文本示意办法,是整个程序工程信息的动态文本,通常由linker生成。 gdb通过运行程序,打断点、单步、查看变量的值等形式在运行时定位bug。 file <文件名>加载被调试的可执行程序文件b <行号>/<函数名称>在第几行或者某个函数第一行代码前设置断点r运行s单步执行一行代码n执行一行代码,执行函数调用(如果有)c持续运行程序至下一个断点或者完结p<变量名称>查看变量值q退出援用是否能实现动静绑定,为什么援用能够实现 因为对象的类型是确定的,在编译期就确定了,指针或援用是在运行期依据他们绑定的具体对象确定。 ...

June 8, 2021 · 2 min · jiezi

关于c:西电C语言程序设计实验之图书馆管理系统

简略文件数据库-模仿图书馆管理系统波及知识点:文件读写、内存治理、构造体定义、根本数据结构、高级格式化输入输出 要求:编写一个程序模仿图书管理系统。 用户分为管理员和读者两类,别离显示不同文本格式菜单,通过菜单项对应数字进行抉择。 读者菜单包含借书、还书、查问等性能。管理员菜单包含图书和读者信息录入、批改和删除。 图书信息至多应包含:编号、书名、数量。读者信息至多应包含:编号、姓名、所借图书。 可依据图书名称或编号进行图书信息查问,可查问某本书当初被哪些读者借走。 命令行参数如下:Libsim –a(-u) xxxx 第一个参数为可执行程序名称;第二个参数为用户身份,-a示意管理员,-u示意读者;第三个参数为用户名 几个函数阐明: 展现读者和图书信息 void ShowBook(char* bname);void ShowReader(char* rname);图书借阅和偿还 void BookLend(char *rname, char *bname);void BookReturn(char *rname, char* bname);图书和读者信息增删 void AddBook(char* bname);void DelBook(char* bname);void AddReader(char* rname, char* reroot); void DelReader(char* rname);读取读者,管理员和图书信息 void ReadBooksInfo();void ReadReadersInfo();void ReadAdministratorsInfo();更新读者,管理员和图书信息 void UpdateBorrowerList();void UpdateBorrowedBookList();void UpdateBookleft();void UpdateBooks();void UpdateReaders();void UpdateAdministrators();void UpdateReroots();void UpdateAdroots();图书馆信息:信息编写规定: 每个文件以end作为结尾而null示意该书或读者曾经被删除books.txt:每行一本书,第一行的书编号为1readers.txt:每行一个读者姓名,第一行的读者编号为1administrators.txt:每行一个管理员姓名,第管理员一行的读者编号为1books'borrowers.txt:每行若干个人名,第一行对应编号为1的书的借阅人borrowers'books.txt:每行若干个书名,第一行对应编号为1的人的在借书reroots.txt:每行一个明码,第一行对应编号为1的读者的明码adroots.txt每行一个明码,第一行对应编号为1的管理员的明码源码(不蕴含函数局部) #include<stdio.h>#include<string.h>typedef struct Book{ char name[20];//名称 int num; //编号 int left; //库存 }Book;typedef struct Reader{ char name[20];//姓名 int num; //编号 char root[20];//明码 }Reader;typedef struct Administrator{ char name[20];//姓名 int num; //编号 char root[20];//明码 }Administrator; Book books[110]; //图书信息 Reader readers[110]; //读者信息 Administrator administrators[10]; //管理员信息 char borrowerList[110][100]; //图书在借人 char borrowedBookList[110][100]; //读者在借书 void ShowBook(char* bname);void ShowReader(char* rname);void BookLend(char *rname, char *bname);void BookReturn(char *rname, char* bname);void ReadBooksInfo();void ReadReadersInfo();void ReadAdministratorsInfo();void UpdateBorrowerList();void UpdateBorrowedBookList();void UpdateBookleft();void UpdateBooks();void UpdateReaders();void UpdateAdministrators();void UpdateReroots();void UpdateAdroots();void AddBook(char* bname);void DelBook(char* bname);void AddReader(char* rname, char* reroot); void DelReader(char* rname);//Libsim –a(-u) xxxx//第一个参数为可执行程序名称;第二个参数为用户身份,-a示意管理员,-u示意读者;第三个参数为用户名int main(int argc, char *argv[]) { ReadBooksInfo(); ReadReadersInfo(); ReadAdministratorsInfo(); char *command = argv[1], *name = argv[2]; printf("Hello, %s! Welcome to XDULibrary!\n", name); if(!strcmp(command, "-a")){ char root[10]; printf("Please enter your root:\n"); scanf("%s", root); int i, flag = 0, choice; for(i = 0; i < 10; i++) if(!strcmp(administrators[i].root, root)) flag = 1; if(!flag){ printf("wrong root\n"); return -1; } printf("0.exit\n1.show books\n2.show readers\n3.delete readers\n4.delete books\n5.add readers\n6.add books\n"); while (1) { printf("please choose what to do:\n"); scanf("%d", &choice); if (choice == 0){ printf("exit successfully"); return 0; } switch(choice){ case 1:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); ShowBook(bname); break; } case 2:{ char rname[20]; printf("please enter reader's name:\n"); scanf("%s", rname); ShowReader(rname); break; } case 3:{ char rname[20]; printf("please enter reader's name:\n"); scanf("%s", rname); DelReader(rname); break; } case 4:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); DelBook(bname); break; } case 5:{ char rname[20], reroot[20]; printf("please enter reader's name:\n"); scanf("%s", rname); printf("please enter reader's root:\n"); scanf("%s", reroot); AddReader(rname, reroot); break; } case 6:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); AddBook(bname); break; } default:{ printf("illegal input\n"); break; } } } } else if (!strcmp(command, "-u")){ char root[10]; printf("Please enter your root:\n"); scanf("%s", root); int i, flag = 0, choice; for(i = 0; i < 10; i++){ if(!strcmp(readers[i].root, root)) flag = 1; } if(!flag){ printf("wrong root\n"); return -1; } printf("0.exit\n1.show books\n2.show readers\n3.lend books\n4.return books\n"); while (1) { printf("please choose what to do:\n"); scanf("%d", &choice); if (choice == 0){ printf("exit successfully"); return 0; } switch(choice){ case 1:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); ShowBook(bname); break; } case 2:{ char rname[20]; printf("please enter reader's name:\n"); scanf("%s", rname); ShowReader(rname); break; } case 3:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); BookLend(name, bname); break; } case 4:{ char bname[20]; printf("please enter book's name:\n"); scanf("%s", bname); BookReturn(name, bname); break; } default:{ printf("illegal input\n"); break; } } } } else{ printf("illegal input\n"); return -1; } return 0;}//编写函数的地位:……………………………………………………………………………………须要残缺源码可移步评论区留言,一键三连是对创作者最大的激励~ ...

June 8, 2021 · 3 min · jiezi

关于c++:C类的多态性一

目标把握运算符重载的应用办法 内容编程题1.(1)以成员函数的形式,实现运算符“+”的重载,程序运行后果放弃不变; (2)以友元函数的形式,实现运算符“+”的重载,程序运行后果放弃不变。代码:(1) #include<iostream.h>class Box{public: Box(){} Box(int l,int b, int h) { length=l; breadth=b; height=h; } Box operator+(Box& b) { Box box; box.length=length+b.length; box.breadth=breadth+b.breadth; box.height=height+b.height; return box; } void print() { cout<<"length:"<<length<<endl; cout<<"breadth:"<<breadth<<endl; cout<<"height:"<<height<<endl; }private: double length; double breadth; double height;};int main(){Box Box1(1,2,3);Box Box2(4,5,6);Box Box3;Box3=Box1+Box2;Box3.print();return 0;}后果:(2) #include<iostream.h>class Box{public: Box(){} Box(int l,int b, int h) { length=l; breadth=b; height=h; } friend Box operator+(Box& b,Box& b1); void print() { cout<<"length:"<<length<<endl; cout<<"breadth:"<<breadth<<endl; cout<<"height:"<<height<<endl; }private: double length; double breadth; double height;}; Box operator+(Box& b,Box& b1) { Box box; box.length=b1.length+b.length; box.breadth=b1.breadth+b.breadth; box.height=b1.height+b.height; return box; }int main(){Box Box1(1,2,3);Box Box2(4,5,6);Box Box3;Box3=Box1+Box2;Box3.print();return 0;}后果:2.把握以类的成员函数重载运算符的应用办法代码: ...

June 7, 2021 · 2 min · jiezi

关于c#:设计模式抽象工厂

设计模式之形象工厂上一篇咱们学习了简略工厂,晓得简略工厂是创立不同类的中央,那么这些工厂是如何创立得呢?随着咱们业务逻辑的减少,可能须要好多这种简略工厂,咱们不可能每一个都去被动创立,尽管说这样也能够实现,然而却不优雅而且前期维护者分不清批改重点,导致牵一发而动全身。 接下来学习如何创立通过一种形式去创立简略工厂,那么即便须要很多工厂,也能够通过这种形式去创立,缩小代码的耦合,使其内聚性更高。 形象工厂与工厂办法都为了解决接口抉择问题,然而实现上,形象工厂是一个核心工厂,用于创立其它工厂的模式。 不同的实现服务(类/Server)在局部办法上是不同的,因而须要做一个接口适配,这个适配类就相当于工厂中的工厂,用于创立把不同的服务形象为对立的接口做雷同的业务。 Demo业务: 假设当初目前有两个物流公司A,B,他们都有发货,取货的业务,同时公司A,B都能够自主的去进行各自不同品种的发货和取货,也就是说能够自定义。如果这有这两个公司那么很简略,咱们能够应用简略工厂,新创建两个工厂就能够解决,然而如果是10个或者50个公司,那么咱们创立工厂就有点不适合,这个时候就得应用形象工厂。 形象工厂定义的形象工厂都是抽象类,定义了发货,取货的形象办法,返回的也是抽象类。 /// <summary> /// 形象工厂 /// </summary> public abstract class AbstractFactory { /// <summary> /// 发货 /// </summary> /// <returns></returns> public abstract ASendGood SendGood(); /// <summary> /// 收货 /// </summary> /// <returns></returns> public abstract AGetGood GetGood(); } /// <summary> /// 取货 抽象类 /// </summary> public abstract class AGetGood { public abstract void GetGood(); } /// <summary> /// 发货 抽象类 /// </summary> public abstract class ASendGood { public abstract void SendGood(); } /// <summary> /// 公司A形象工厂 /// </summary> public class CompanyAAbstractFactory : AbstractFactory { public override AGetGood GetGood() { return new CompanyAGetGood(); } public override ASendGood SendGood() { return new CompanyASendGood(); } } /// <summary> /// 公司B的形象工厂 /// </summary> public class CompanyBAbstractFactory : AbstractFactory { public override AGetGood GetGood() { return new CompanyBGetGood(); } public override ASendGood SendGood() { return new CompanyBSendGood(); } } public class CompanyAGetGood : AGetGood { public override void GetGood() { Console.WriteLine("公司A 取货"); } } public class CompanyASendGood : ASendGood { public override void SendGood() { Console.WriteLine("公司A 发货"); } } class CompanyBGetGood : AGetGood { public override void GetGood() { Console.WriteLine("公司B 取货"); } } class CompanyBSendGood : ASendGood { public override void SendGood() { Console.WriteLine("公司B 发货"); } } 定义完形象工厂及各自的抽象类,接下来就是调用了。 ...

June 6, 2021 · 2 min · jiezi

关于c#:设计模式简单工厂

工厂模式工厂模式:顾名思义就是使得这个类的作用和工厂一样,生产产品,在这里应用,咱们就是生产类。工厂模式就是生产类,创立类的模式。 其在父类中提供一个创建对象的办法,容许子类决定实例化对象的类型。 代码绑定着具体类会导致代码更软弱,更不足弹性,不易扩大,批改艰难。 针对接口编程,能够隔离掉当前零碎可能产生的一大堆扭转,易于扩大。 用于解决扭转,并帮忙咱们“找出会变动的方面,把它们从不变的局部分离出来” Demo比方当初有一个物流公司,之前业务很繁多,只做陆上物流,随着工夫的推移,市场的变动,也有了海上物流,那么如何设计出一种实现形式来应答这种在业务逻辑上的不确定性,如果前面在减少一种地面物流,那么将如何设计呢。 如何只有路上物流和海上物流,咱们能够只在独自的类中各自申明下,前面通过if/eles形式来判断是那个物流,从而去实现它即可。这样做没有问题,能够解决业务下面所面临的问题,然而确不是软件开发中最好的实现形式,如果你通过if/eles来实现,那么它们的耦合度太高,前期如果陆上物流产生批改,会导致批改的中央过多,且不易于扩大。 简略实现逻辑 /// <summary> /// 海上物流 /// </summary> public class AtSeaLogistics { /// <summary> /// 海上发货 /// </summary> public void SendSeaGoods(string goodName) { Console.WriteLine("海上 Send:"+goodName); } } /// <summary> /// 海洋物流 /// </summary> public class LandLogistics { /// <summary> /// 海洋发货 /// </summary> public void SendLandGoods(string goodName) { Console.WriteLine("海洋 Send:"+goodName); } } static void Main(string[] args) { int logisticsType = 0; //默认为海洋运输 Console.WriteLine("开始发货"); if (logisticsType==0) { LandLogistics land = new LandLogistics(); land.SendLandGoods("Iphone 13"); } else { AtSeaLogistics atSea = new AtSeaLogistics(); atSea.SendSeaGoods("海鱼"); } Console.WriteLine("发货实现"); Console.ReadKey(); }运行后,因为是默认海洋发货,则调用海洋发货模块,进行发货。这其实是一种很简略,也是咱们目前写简略逻辑最最罕用的形式,实现性能没有问题,可是这种实现形式存在很大的隐患和不可扩大,如果前期在须要增加一种运输形式,可能得须要在Main()办法中批改才行,运输形式和物流的耦合性过高,且不易扩大。 ...

June 6, 2021 · 2 min · jiezi

关于c++:C内存管理13VC6-内存分配

VC6_SBH 概述SBH 是 Small Block Heap 的缩写,进行操作系统之上的小区块内存的治理。在 VC6 中可找到源码实现,降级版本 VC10 中对立应用零碎API进行内存申请, SBH 被整合到了操作系统外部。 VC6 局部实现 VC10 局部实现 留神: __heap_init 和 __ioinit 在 VC6 和 VC10 中都存在 VC6_SBH 合成heap_init(...)_heap_init(...) 、__sbh_heap_init() 阐明 :CRT 会先为本人创立一个 _ctrheap "独特"内存(HeapCreate), 而后从中配置 SBH 所需的 headers, regions(__sbh_heap_init).应用程序内存申请时如果 size > threshold 就以 HeapAlloc() 从 _crtheap 取.若size <= thread 就从 SBH 取(理论区块来自 VirtualAlloc) 1. 操作系统内存治理的一些概念:可创立一块独特的空间并给其命名,之后相干操作所需的内存都取自这里【逻辑上分类】1.1 HeapCreate 要求操作系统调配一块内存1.2 __crtheap 全局指针变量,指向调配的内存空间,专为 CRT(C Run Time) 应用2. __sbh_heap_init,到 __ctrheap 指向的内存获取 16 * sizeof(Header) 空间2.1 每个 SBH 中还有 16 个HEADERheader 构造剖析 ...

June 6, 2021 · 2 min · jiezi

关于c#:设计模式总览

看到掘金的30天发文连更挑战,想试试本人到底能够间断保持几天,奖品不奖品的不重要,重在参加吗?接下来的30天里,我将率领大家一起学习设计模式,以前总感觉设计模式很简单,在个别的惯例编程中很少应用到,仔细阅读后发现,之前的想法是如许无知。如果一个编程人员想晋升本人,想让本人更加值钱,那么代码标准,设计模式这些术层面的知识点也是须要理解和把握的。 其实在日常的开发中,咱们或多或少都会应用到设计模式,只是大家不太分明而已。比方咱们常常应用到的单例模式,工厂模式等。 楼主次要从事C#开发,程序中举例的代码应用C#。设计模式总览(形象、封装、继承、多态)是面向对象(OO)的基本概念,OO准则时咱们的指标,设计模式是咱们的做法。设计模式总共有23种,从大的构造上进行划分,可分为3大类,顺次是创立型模式、结构型模式、行为模式。 创立型模式这类模式是创建对象的机制,能够晋升已有代码的灵活性和可服用性。 工厂办法形象工厂生成器原型单例 结构型模式介绍如何将对象和类组装成较大的构造,并同时放弃构造的灵便和高效。 适配器桥接组合装璜外观享元代理 行为模式这类模式负责对象间的高效沟通和职责委派。 责任链命令迭代器中介者备忘录观察者状态策略模版办法访问者 如果你只有一把铁锤,那么任何货色看上去都像钉子。那么咱们要致力让本人手里领有多个铁锤。最根底的,底层的模式通常被称为习用技巧,这类模式个别只能在一种编程语言中应用。 最通用的,高层的模式是架构模式,咱们能够在任何编程语言中应用这类模式,与其余模式不同,它们可用于整个应用程序的架构设计。 小寄语一个人的奋斗,像怀孕一样,日子久了,总会被看进去的。 人生短暂,我不想去谋求本人看不见的,我只想抓住我能看的见的。 我是哉说,感谢您的浏览,如果对你有帮忙,麻烦点赞,转发 谢谢。

June 5, 2021 · 1 min · jiezi