当前位置: 首页 > news >正文

【CSAPP】家庭作业2.55~2.76

文章目录

  • 2.55*
  • 2.56*
  • 2.57*
  • 2.58**
  • 2.59**
  • 2.60**
  • 位级整数编码规则
  • 2.61**
  • 2.62***
  • 2.63***
  • 2.64*
  • 2.65****
  • 2.66***
  • 2.67**
  • 2.68**
  • 2.69***
  • 2.70**
  • 2.71*
  • 2.72**
  • 2.73**
  • 2.74**
  • 2.75***
  • 2.76*

2.55*

:在你能访问的不同的机器上,编译show_bytes.c并运行代码,确定这些机器的字节顺序。

// show_bytes.c
#include <stdio.h>typedef unsigned char *byte_pointer;void show_bytes(byte_pointer start, size_t len)
{for (size_t i = 0; i < len; ++i) {printf("%.2X ", start[i]);}printf("\n");
}void show_int(int x)
{show_bytes((byte_pointer)&x, sizeof(int));
}

x86_64上,运行结果为:

// show_int(0x87654321);
[liheng@localhost2 2]$ ./a.out 
21 43 65 87 

低位字节保存在低地址,该机器按小端顺序存储多字节对象。

2.56*

:试着用不同的示例值来运行show_bytes.c

// show_int(0x11223344);
[liheng@localhost2 2]$ ./a.out 
44 33 22 11 
// show_int(0x22);
[liheng@localhost2 2]$ ./a.out 
22 00 00 00 
// show_int(0x11000000);
[liheng@localhost2 2]$ ./a.out 
00 00 00 11 

2.57*

:编写并运行程序show_shortshow_longshow_double

void show_short(short x)
{show_bytes((byte_pointer)&x, sizeof(short));
}void show_long(long x)
{show_bytes((byte_pointer)&x, sizeof(long));
}void show_double(double x)
{show_bytes((byte_pointer)&x, sizeof(double));
}

x86_64上,运行结果为:

// show_short(0x1234);
// show_long(0x1234);
// show_double(0x1234);
[liheng@localhost2 2]$ ./a.out 
34 12 
34 12 00 00 00 00 00 00 
00 00 00 00 00 34 B2 40 
// show_short(0x1030);
// show_long(0x1030);
// show_double(0x1030);
[liheng@localhost2 2]$ ./a.out 
30 10 
30 10 00 00 00 00 00 00 
00 00 00 00 00 30 B0 40 

2.58**

:编写过程is_little_endian,当在小端法机器上运行时返回1,否则返回0

int is_little_endian()
{uint32_t x = 0x12345678; // #include <stdint.h>return *(uint8_t *)&x == (uint8_t)0x78;
}

x86_64上,运行结果为:

// printf("is_little_endian: %d\n", is_little_endian());
[liheng@localhost2 2]$ ./a.out 
is_little_endian: 1

2.59**

:编写一个C表达式,它生成一个字,由x的最低有效字节和y中剩下的字节组成。对于x = 0x89ABCDEFy = 0x76543210得到0x765432EF
:表达式为(x & 0xFF) | (y & ~0xFF)

2.60**

:假设我们将一个w位的字中的字节从0(最低位字节)到w / 8 - 1(最高位字节)编号,写出下面C函数的代码,它会返回一个无符号值,其中参数x的字节i被替换成字节b

unsigned replace_byte(unsigned x, int i, unsigned char b);
// replace_byte(0x12345678, 2, 0xAB) --> 0x12AB5678
// replace_byte(0x12345678, 0, 0xAB) --> 0x123456AB


replace_byte的实现:

unsigned replace_byte(unsigned x, int i, unsigned char b)
{unsigned bits = i << 3;unsigned x1 = x & ~(0xFF << bits);unsigned b1 = b << bits;return x1 | b1;
}

x86_64上的运行结果:

// printf("%p\n", replace_byte(0x12345678, 4, 0xAB));
// printf("%p\n", replace_byte(0x12345678, 3, 0xAB));
// printf("%p\n", replace_byte(0x12345678, 2, 0xAB));
// printf("%p\n", replace_byte(0x12345678, 1, 0xAB));
// printf("%p\n", replace_byte(0x12345678, 0, 0xAB));
[liheng@localhost2 2]$ ./a.out 
0x123456ab
0xab345678
0x12ab5678
0x1234ab78
0x123456ab

位级整数编码规则

在接下来的作业中,我们特意限制了你能使用的编程结构,来帮助你更好地理解C语言的位级、逻辑和算术运算。你的代码必须遵守以下规则:

  • 假设
  1. 整数用补码形式表示。
  2. 有符号数的右移是算术右移。
  3. 数据类型intw(一定是8的整数倍)位长的。某些题目会给出w的值。
  • 禁止使用
  1. 条件语句if? : 、循环、分支语句、函数调用和宏调用。
  2. 除法、模运算和乘法。
  3. 相对比较运算<><=>=
  • 允许的运算
  1. 所有的位级和逻辑运算。
  2. 左移和右移,位移量只能在0 ~ w-1之间。
  3. 加法和减法。
  4. 相等==和不相等!=
  5. 整型常数INT_MININT_MAX
  6. intunsigned进行隐式或显式强制类型转换。

个别题目有特殊的限制。

2.61**

:写一个C表达式,在下列描述的条件下产生1,在其他情况下得到0,假设xint类型。

  1. x的任何位都等于1
!~x
  1. x的任何位都等于0
!x;
  1. x的最低有效字节中的位都等于1
!~(x | ~0xFF)
  1. x的最高有效字节中的位都等于0
!((0xFF << ((sizeof(int) - 1) << 3)) & x);

2.62***

:编写一个函数int_shifts_are_arithmetic(),在对int类型的数使用算术右移的机器上运行时这个函数返回1,其他情况下返回0

int int_shifts_are_arithmetic()
{int x = -1;return (x >> 8) == x;  // return !(x ^ (x >> 8));
}

x86_64上的运行结果:

// printf("%d\n", int_shifts_are_arithmetic());
[liheng@localhost2 2]$ ./a.out 
1

2.63***

:将下面的C函数代码补充完整。函数srl用算术右移(由值xsra给出)完成逻辑右移,后面的操作不包括右移或者除法。函数sra用逻辑右移(由值xsrl给出)来完成算术右移,后面的操作不包括右移或者除法。w = sizeof(int) * 8k的取值范围是0 ~ w-1

unsigned srl(unsigned x, in k)
{unsigned xsra = (int)x >> k;  // 算术右移的值int mask = ((1 << k) - 1) << ((sizeof(int) << 3) - k);return xsra & ~mask;
}int sra(int x, int k)
{int xsrl = (unsigned)x >> k;  // 逻辑右移的值int sign = !!(x & (1 << ((sizeof(int) << 3) - 1)));int mask = ((sign << k) - sign) << ((sizeof(int) << 3) - k);return xsrl | mask;
}

x86_64上的运行结果:

// printf("%p\n", srl(-1, 0));
// printf("%p\n", srl(-1, 16));
// printf("%p\n", srl(-1, 31));
// printf("%p\n", sra(-1, 0));
// printf("%p\n", sra(-1, 16));
// printf("%p\n", sra(-1, 31));
// printf("%p\n", sra(0x0F000000, 16));
[liheng@localhost2 2]$ ./a.out 
0xffffffff
0xffff
0x1
0xffffffff
0xffffffff
0xffffffff
0xf00

2.64*

:实现一个函数,入参是一个整型xw = 32),如果有一个奇数位是1,就返回1,否则返回0

首先需要构造32位的掩码10[10]...,使用该掩码去掉x中的偶数位,再判断奇数位是否存在一个1
32位的掩码10[10]...的十六进制表示为0x55555555

int any_odd_one(unsigned x)
{int mask = 0x55555555;return x & mask;
}

x86_64机器上的运行结果:

// printf("%d\n", any_odd_one(0x1));
// printf("%d\n", any_odd_one(0x2));
[liheng@localhost2 2]$ ./a.out 
1
0

2.65****

:实现一个函数,入参是一个整型xw = 32),当x有奇数个值为1的位时,返回1,否则返回0

int odd_ones(unsigned x)
{x ^= x >> 16;x ^= x >> 8;x ^= x >> 4;x ^= x >> 2;x ^= x >> 1;return x & 0x1;
}

第一个^=运算把x0~15位和16~31位的^运算结果放在了x0~15位;第二个^=运算把x(上一步的运算结果)的0~7位和8~15位的^运算结果放在了x0~7位,以此类推。最终x的第0位上放的就是初值的x的所有位的^结果。

1 ^ 1 = 00 ^ 0 = 01 ^ 0 = 1,异或会抵消掉相同的位,把值归0,且异或具有结合律。因此只要把x中的所有位按任意顺序异或一遍,最终结果为1的话就说明它包含奇数个值为1的位。

x86_64机器上的运行结果:

// printf("%d\n", odd_ones(0x0));  // 0个值为1的位
// printf("%d\n", odd_ones(0x1));  // 1个值为1的位
// printf("%d\n", odd_ones(0x3));  // 2个值为1的位
// printf("%d\n", odd_ones(-1));  // 32个值为1的位
// printf("%d\n", odd_ones(369));  // 5个值为1的位
// printf("%d\n", odd_ones(11825));  // 7个值为1的位
[liheng@localhost2 2]$ ./a.out 
0
1
0
0
1
1

2.66***

:实现一个函数,入参是一个整型xw = 32),返回一个掩码指示最高位的1的位置。如输入0xFF00返回0x8000,输入0x6600返回0x4000,输入0返回0

int leftmost_one(unsigned x)
{x |= x >> 1;x |= x >> 2;x |= x >> 4;x |= x >> 8;x |= x >> 16;return (x >> 1) + !!x;
}

x的值为1的最高位算起往它的低位开始数,第一次|=运算的结果把2个位设置为1,第二次|=运算的结果把4个位设置为1,以此类推,把全32位都设置为1。最后把结果右移1位再加1,就得到了指示最高位的1的位置的数。

x86_64机器上的运行结果:

// printf("%d\n", leftmost_one(0x0));
// printf("%p\n", leftmost_one(0xF));
// printf("%p\n", leftmost_one(0x6600));
// printf("%p\n", leftmost_one(0x8000));
// printf("%p\n", leftmost_one(0x46531));
// printf("%p\n", leftmost_one(-1));
[liheng@localhost2 2]$ ./a.out 
0
0x8
0x4000
0x8000
0x40000
0x80000000

2.67**

:实现一个函数,当在一个int32位的机器上运行时,该程序产生1,其他情况产生0。不允许使用sizeof
下面是开始的尝试:

int bad_int_size_is_32()
{int set_msb = 1 << 31;int beyond_msb = 1 << 32;// set_msb非零时,int_size >= 32;beyond_msb为零时,int_size <= 32return set_msb && !beyond_msb;  
}

当我们在SUN SPARC这样的32位机器上编译运行时,这个过程返回的却是0。编译器打印了一句warning

warning: left shift count >= width of type

  1. 我们的代码在哪个方面没有遵守C语言标准?
    C标准没有明确规定当移位操作的位数大于等于变量的宽度时的行为。有的机器上1 << 32是零,有的机器上1 << 32是非零(移位的位数%(取模)变量的宽度)。上述代码预期在这种情况下,1 << 32是零。
    为了保证程序的可移植性,需要程序员保证移位数的取值范围是[0, w)
  2. 修改代码,使得它在int至少为32位的机器上都能正确地运行。
int int_size_is_32()
{int set_msb = 1 << 31;int beyond_msb = set_msb << 1;  // 确保在不同的机器上,程序的行为是一致的。// set_msb非零时,int_size >= 32;beyond_msb为零时,int_size <= 32return set_msb && !beyond_msb;  
}
  1. 修改代码,使得它在int至少为16位的机器上都能正确地运行。
int int_size_is_32()
{int set_msb = 1 << 15 << 15 << 1;  // 保证左移行为符合预期int beyond_msb = set_msb << 1;// set_msb非零时,int_size >= 32;beyond_msb为零时,int_size <= 32return set_msb && !beyond_msb;  
}

2.68**

:实现一个函数,输入正整数n(1≤n≤w)(1 \le n \le w)(1nw),返回低n位均为1的掩码值。如输入6返回0x3F,输入17返回0x1FFFF

int lower_one_mask(int n)
{return (unsigned)-1 >> ((sizeof(int) << 3) - n);
}

x86_64机器上的运行结果:

// printf("%d\n", lower_one_mask(0));
// printf("%p\n", lower_one_mask(6));
// printf("%p\n", lower_one_mask(17));
// printf("%p\n", lower_one_mask(31));
// printf("%p\n", lower_one_mask(32));
[liheng@localhost2 2]$ ./a.out 
0
0x3f
0x1ffff
0x7fffffff
0xffffffff

2.69***

:实现循环左移,0≤n<w0 \le n <w0n<w。如x = 0x12345678w = 32n = 4返回0x23456781n = 20返回0x67812345

unsigned rotate_left(unsigned x, int n)
{unsigned low = x >> ((sizeof(unsigned) << 3) - n);unsigned high = x << n;return high | low;
}

x86_64机器上的运行结果:

// printf("%p\n", rotate_left(0x12345678, 0));
// printf("%p\n", rotate_left(0x12345678, 4));
// printf("%p\n", rotate_left(0x12345678, 8));
// printf("%p\n", rotate_left(0x12345678, 12));
// printf("%p\n", rotate_left(0x12345678, 16));
// printf("%p\n", rotate_left(0x12345678, 20));
// printf("%p\n", rotate_left(0x12345678, 24));
// printf("%p\n", rotate_left(0x12345678, 28));
// printf("%p\n", rotate_left(0x12345678, 31));
[liheng@localhost2 2]$ ./a.out 
0x12345678
0x23456781
0x34567812
0x45678123
0x56781234
0x67812345
0x78123456
0x81234567
0x91a2b3c

2.70**

:实现一个函数,如果x能被表示成n(1≤n≤w)(1 \le n \le w)(1nw)的二进制补码,就返回1,否则返回0

int fits_bits(int x, int n)
{int w = sizeof(int) << 3;int offset = w - n;return ((x << offset) >> offset) == x;  // 如果x不能用n个比特位表示,移位操作会使它丢失最高的有效位
}

x86_64机器上的运行结果:

// printf("%d\n", fits_bits(-4, 3));
// printf("%d\n", fits_bits(3, 3));
// printf("%d\n", fits_bits(-5, 3));
// printf("%d\n", fits_bits(4, 3));
[liheng@localhost2 2]$ ./a.out 
1
1
0
0

2.71*

packed_t类型是将4个有符号字节封装成一个32位的unsigned,字节从0(最低有效字节)编码到3最高有效字节。有如下一个函数xbyte,提取出特定的字节,再把它符号扩展成一个int

typedef unsigned packed_t;
int xbyte(packed_t word, int byteNum)
{return (word >> (byteNum << 3)) & 0xFF;
}

  1. 写上述代码的人被解雇了,这段代码错在哪里?
    编译器会把(word >> (byteNum << 3)) & 0xFF的结果当作无符号数,扩展时使用零扩展而非符号扩展
// printf("%d\n", xbyte(-1, 3));
[liheng@localhost2 2]$ ./a.out 
255
  1. 给出函数的正确实现。
typedef unsigned packed_t;
int xbyte(packed_t word, int byteNum)
{return (int8_t)((word >> (byteNum << 3)) & 0xFF);  // 把结果转成有符号数
}

x86_64机器上的运行结果:

// printf("%d\n", xbyte(-1, 3));
[liheng@localhost2 2]$ ./a.out 
-1

2.72**

:下面的函数将整数val复制到缓冲区buf中。

void copy_int(int val, void *buf, int maxbytes)
{if (maxbytes - sizeof(val) >= 0) {memcpy(buf, &val, sizeof(val));}
}

  1. sizeof的返回值类型是size_t,这段代码存在什么问题?
    size_t是无符号类型unsigned的别名,maxbytes是有符号数,无符号数和有符号数运算时,结果是无符号数(永远≥0\ge00),因此if分支的判断语句永远为truememcpy会造成缓冲区的写溢出。
  2. 改正代码。
void copy_int(int val, void *buf, int maxbytes)
{if (maxbytes >= sizeof(val) {  // 无符号数之间的比较memcpy(buf, &val, sizeof(val));}
}

2.73**

:实现饱和加法:正溢出时返回TMax,负溢出时返回TMin

int saturating_add(int x, int y)
{int s = x + y;int mask = 1 << ((sizeof(int) << 3) - 1);int neg_overflow = (x & mask) && (y & mask) && !(s & mask);int pos_overflow = !(x & mask) && !(y & mask) && (s & mask);(neg_overflow && (s = INT_MIN)) || (pos_overflow && (s = INT_MAX));return s;
}

x86_64机器上的运行结果:

// printf("%d\n", saturating_add(123, 456));
// printf("%d\n", saturating_add(-123, -456));
// printf("%d\n", saturating_add(INT_MAX, 123));
// printf("%d\n", saturating_add(INT_MIN, -123));
[liheng@localhost2 2]$ ./a.out 
579
-579
2147483647
-2147483648

2.74**

:实现一个函数,两数相减不溢出就返回1,否则返回0

int tsub_ok(int x, int y)
{int s = x - y;return !((x > 0 && y < 0 && s < 0) || (x < 0 && y > 0 && s > 0));
}

x86_64机器上的运行结果:

// printf("%d\n", tsub_ok(-1, 3));
// printf("%d\n", tsub_ok(INT_MIN, 1));
// printf("%d\n", tsub_ok(INT_MAX, -1));
[liheng@localhost2 2]$ ./a.out 
1
0
0

正常情况:正数+正数=正数;溢出情况:正数+正数=负数。
正常情况:负数+负数=负数;溢出情况:负数+负数=正数。
正常情况:正数-负数=正数;溢出情况:正数-负数=负数。
正常情况:负数-正数=负数;溢出情况:负数-正数=正数。

2.75***

:假设我们要计算x * y的完整的2w位表示,其中xy都是无符号数,并且w=32,乘积的低w位能够用表达式x * y计算。所以我们只需要额外计算它的高w位,声明如下:

unsigned unsigned_high_prod(unsigned x, unsigned y);

我们使用一个库函数,它计算在xy采用补码形式的情况下,x * y的高w位。声明如下:

int signed_high_prod(int x, int y);

编写代码调用signed_high_prod,实现unsigned_high_prod


假设xy是无符号数,x′x'xy′y'y分别是它们的补码数。有x=x′+xw−12wx=x'+x_{w-1}2^wx=x+xw12wy=y′+yw−12wy=y'+y_{w-1}2^wy=y+yw12w,因此
x∗y=(x′+xw−12w)∗(y′+yw−12w)=x′∗y′+(x′yw−1+y′xw−1)2w+xw−1yw−122wx*y=(x'+x_{w-1}2^w)*(y'+y_{w-1}2^w)=x'*y'+(x'y_{w-1}+y'x_{w-1})2^w+x_{w-1}y_{w-1}2^{2w}xy=(x+xw12w)(y+yw12w)=xy+(xyw1+yxw1)2w+xw1yw122w
取低2w位,结果是x′∗y′+(x′yw−1+y′xw−1)2wx'*y'+(x'y_{w-1}+y'x_{w-1})2^wxy+(xyw1+yxw1)2w,获取其中的高w位的实现如下:

unsigned unsigned_high_prod(unsigned x, unsigned y)
{int a = signed_high_prod(x, y);return a + x * (y >> 31) + y * (x >> 31);
}

2.76*


库函数calloc声明如下:

void *calloc(size_t nmemb, size_t size);

函数calloc为一个数组分配内存,并将内存设置为0。该数组有nmemb个元素,每个元素的大小为size字节。如果nmembsize0calloc返回NULL
编写calloc的实现,通过malloc分配内存,再通过memset将内存设置为0。你的代码应该没有任何由算术溢出引起的漏洞,且无论size_t用多少位表示,代码都应该正常工作。mallocmemset的声明如下:

void *malloc(size_t size);
void *memset(void *s, inc c, size_t n);


calloc的实现如下:

void *calloc(size_t nmemb, size_t size)
{size_t bytes = nmemb * size;if ((bytes == 0) || (bytes / nmemb != size)) {  // 分配0字节或溢出return NULL;}void *addr = malloc(bytes);if (addr == NULL) {return NULL;}return memset(addr, 0x00, bytes);
}

相关文章:

【CSAPP】家庭作业2.55~2.76

文章目录2.55*2.56*2.57*2.58**2.59**2.60**位级整数编码规则2.61**2.62***2.63***2.64*2.65****2.66***2.67**2.68**2.69***2.70**2.71*2.72**2.73**2.74**2.75***2.76*2.55* 问&#xff1a;在你能访问的不同的机器上&#xff0c;编译show_bytes.c并运行代码&#xff0c;确定…...

Python操作MySQL数据库详细案例

Python操作MySQL数据库详细案例一、前言二、数据准备三、建立数据库四、处理和上传数据五、下载数据六、完整项目数据和代码一、前言 本文通过案例讲解如何使用Python操作MySQL数据库。具体任务为&#xff1a;假设你已经了解MySQL和知识图谱标注工具Brat&#xff0c;将Brat标注…...

MicroBlaze系列教程(8):AXI_CAN的使用

文章目录 @[toc]CAN总线概述AXI_CAN简介MicroBlaze硬件配置常用函数使用示例波形实测参考资料工程下载本文是Xilinx MicroBlaze系列教程的第8篇文章。 CAN总线概述 **CAN(Controller Area Network)**是 ISO 国际标准化的串行通信协议,是由德国博世(BOSCH)公司在20世纪80年代…...

网络安全领域中八大类CISP证书

CISP​注册信息安全专业人员 注册信息安全专业人员&#xff08;Certified Information Security Professional&#xff09;&#xff0c;是经中国信息安全产品测评认证中心实施的国家认证&#xff0c;对信息安全人员执业资质的认可。该证书是面向信息安全企业、信息安全咨询服务…...

stm32学习笔记-5EXIT外部中断

5 EXIT外部中断 [toc] 注&#xff1a;笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注&#xff1a;工程及代码文件放在了本人的Github仓库。 5.1 STM32中断系统 图5-1 中断及中断嵌套示意图 中断 是指在主程序运行过程中&#xff0c;出现了特定…...

MySQL Workbench 图形化界面工具

Workbench 介绍 MySQL官方提供了一款免费的图形工具——MySQL Workbench&#xff0c;它是一款功能强大且易于使用的数据库设计、管理和开发工具&#xff0c;总之&#xff0c;MySQL Workbench是一款非常好用的MySQL图形工具&#xff0c;可以满足大多数MySQL用户的需求。 目录 W…...

雪花算法(SnowFlake)

简介现在的服务基本是分布式、微服务形式的&#xff0c;而且大数据量也导致分库分表的产生&#xff0c;对于水平分表就需要保证表中 id 的全局唯一性。对于 MySQL 而言&#xff0c;一个表中的主键 id 一般使用自增的方式&#xff0c;但是如果进行水平分表之后&#xff0c;多个表…...

Linux防火墙

一、Linux防火墙Linux的防火墙体系主要在网络层&#xff0c;针对TCP/IP数据包实施过滤和限制&#xff0c;属于典型的包过滤防火墙&#xff08;或称为网络层防火墙&#xff09;。Linux系统的防火墙体系基于内核编码实现&#xff0c;具有非常稳定的性能和极高的效率&#xff0c;因…...

网络安全系列-四十七: IP协议号大全

IP协议号列表 这是用在IPv4头部和IPv6头部的下一首部域的IP协议号列表。 十进制十六进制关键字协议引用00x00HOPOPTIPv6逐跳选项RFC 246010x01ICMP互联网控制消息协议(ICMP)RFC 79220x02IGMP...

HTTP协议格式以及Fiddler用法

目录 今日良言:焦虑和恐惧改变不了明天,唯一能做的就是把握今天 一、HTTP协议的基本格式 二、Fiddler的用法 1.Fidder的下载 2.Fidder的使用 今日良言:焦虑和恐惧改变不了明天,唯一能做的就是把握今天 一、HTTP协议的基本格式 先来介绍一下http协议: http 协议(全称为 &q…...

自动写代码?别闹了!

大家好&#xff0c;我是良许。 这几天&#xff0c;GitHub 上有个很火的插件在抖音刷屏了——Copilot。 这个神器有啥用呢&#xff1f;简单来讲&#xff0c;它就是一款由人工智能打造的编程辅助工具。 我们来看看它有啥用。 首先就是代码补全功能&#xff0c;你只要给出函数…...

项目心得--网约车

一、RESTFULPost&#xff1a;新增Put&#xff1a;全量修改Patch&#xff1a;修改某个值Delete: 删除Get&#xff1a;查询删除接口也可以用POST请求url注意&#xff1a;url中不要带有敏感词&#xff08;用户id等&#xff09;url中的名词用复数形式url设计&#xff1a;api.xxx.co…...

【二叉树广度优先遍历和深度优先遍历】

文章目录一、二叉树的深度优先遍历0.建立一棵树1. 前序遍历2.中序遍历3. 后序遍历二、二叉树的广度优先遍历层序遍历三、有关二叉树练习一、二叉树的深度优先遍历 学习二叉树结构&#xff0c;最简单的方式就是遍历。 所谓二叉树遍历(Traversal)是按照某种特定的规则&#xff…...

Spring Cloud微服务架构必备技术

单体架构 单体架构&#xff0c;也叫单体应用架构&#xff0c;是一个传统的软件架构模式。单体架构是指将应用程序的所有组件部署到一个单一的应用程序中&#xff0c;并统一进行部署、维护和扩展。在单体架构中&#xff0c;应用程序的所有功能都在同一个进程中运行&#xff0c;…...

TCP三次握手与四次挥手(一次明白)

TCP基本信息 默认端口号:80 LINUX中TIME_WAIT的默认时间是30s TCP三次握手 三次握手过程:每行代表发起握手到另一方刚刚收到数据包时的状态 客户端服务端客户端状态服务端状态握手前CLOSELISTEN客户端发送带有SYN标志的数据包到服务端一次握手SYN_SENDLISTEN二次握手服务端发送…...

pyside6@Mouse events实例@QApplication重叠导致的报错@keyboardInterrupt

文章目录报错内容鼠标事件演示报错内容 在pyside图形界面应用程序开发过程中,通常只允许运行一个实例 假设您重复执行程序A,那么可能会导致一些意向不到的错误并且,从python反馈的信息不容易判断错误的真正来源 鼠标事件演示 下面是一段演示pyside6的鼠标事件mouseEvent对象…...

订单30分钟未支付自动取消怎么实现?

目录了解需求方案 1&#xff1a;数据库轮询方案 2&#xff1a;JDK 的延迟队列方案 3&#xff1a;时间轮算法方案 4&#xff1a;redis 缓存方案 5&#xff1a;使用消息队列了解需求在开发中&#xff0c;往往会遇到一些关于延时任务的需求。例如生成订单 30 分钟未支付&#xff0…...

< 开源项目框架:推荐几个开箱即用的开源管理系统 - 让开发不再复杂 >

文章目录&#x1f449; SCUI Admin 中后台前端解决方案&#x1f449; Vue .NetCore 前后端分离的快速发开框架&#x1f449; next-admin 适配移动端、pc的后台模板&#x1f449; django-vue-admin-pro 快速开发平台&#x1f449; Admin.NET 通用管理平台&#x1f449; RuoYi 若…...

内网渗透-基础环境

解决依赖&#xff0c;scope安装 打开要给cmd powershell 打开远程 Set-ExecutionPolicy RemoteSigned -scope CurrentUser; 我试了好多装这东西还是得科学上网&#xff0c;不然不好用 iwr -useb get.scoop.sh | iex 查看下载过的软件 安装sudo 安装git 这里一定要配置bu…...

Go语言学习的第一天(对于Go学习的认识和工具选择及环境搭建)

首先学习一门新的语言&#xff0c;我们要知道这门语言可以帮助我们做些什么&#xff1f;为什么我们要学习这门语言&#xff1f;就小wei而言学习这门语言是为了区块链&#xff0c;因为自身是php出身&#xff0c;因为php的一些特性只能通过一些算法模拟的做一个虚拟链&#xff0c…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...