C++面试速通宝典——7
150. 数据库连接池的作用
数据库连接池的作用包括以下几个方面:
-
资源重用:连接池允许多个客户端共享有限的数据库连接,减少频繁创建和销毁连接的开销,从而提高资源的利用率。
-
统一的连接管理:连接池集中管理数据库连接,包括创建、分配、回收等,简化了连接的管理。
-
避免数据库连接泄露:通过池化管理,可以有效避免连接在使用后没有被释放,从而造成资源泄露。
-
更快的系统响应速度:由于连接池预先创建了一些连接并保持在池中,客户端请求连接时可以直接获取已有连接,避免了创建连接的延迟,从而提高了系统的响应速度。
151. int i = 3 , *j = &i; 下面合法的是:
int &k = 5;
int &k = j;
int &k = &j;
int &k = i;
在C++中,引用必须引用一个有效的左值,不能引用一个右值或临时值。因此,给出的选项中,合法性分析如下:
-
int &k = 5;
不合法:5
是一个右值,不能被引用。 -
int &k = j;
不合法:j
是一个指针(int*
),而不是int
类型的左值。 -
int &k = &j;
不合法:&j
是j
的地址(int**
),不是int
类型的左值。 -
int &k = i;
合法:i
是一个整型变量,是一个左值,可以被引用。
152. 用C编写一个死循环
while(1){}
请注意:
很多种途径都可以实现同一种功能,但还是不同的方法时间和空间占用度不同,特别是对于嵌入式软件,处理器速度比较慢,存储空间小,所以时间和空间优势是选择各种方法的首要考虑条件。
153. 编码实现某一变量某位清0或置1
给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清a的bit 3,在以上两个操作中,要保持其他位不变。
#define BIT3(0x1 << 3) Satic int a设置a的bit3:
void set_bit3(void){a |= BIT3; // 将a第3位置1
}
清a的bit3
void set_bit3(void){a &= ~BIT3; //将a的第3位清零
}
请注意:
在置或清变量或寄存器的某一位时,一定要注意不要影响其他位,所以用加减法是很难实现的。
解释:
#include <iostream>#define BIT3 (0x1 << 3) // 将0x1左移3位,得到bit 3的掩码
static int a = 0; // 定义一个静态整型变量a,初始值为0
这里,我们首先定义了一个宏 BIT3
,其值为 0x1 << 3
,即将 0x1
左移 3 位。左移运算符 <<
会将一个数字左移指定的位数,所以 0x1 << 3
就是 0b0001
变成 0b1000
(即十进制的 8)。
void set_bit3(void) {a |= BIT3; // 将a的第3位设置为1
}
解释:
BIT3
的值是0x1 << 3
,即0b1000
。- 按位或运算符
|
用于将a
的第 3 位设置为1
,保持其他位不变。
假设 a
当前值为 0000 0101
(即 0x5
),调用 set_bit3()
后:
BIT3
的值为0b1000
(即0x8
)。- 执行
a |= BIT3
:0000 0101 | 0000 1000 = 0000 1101
a
变为0000 1101
(即0xD
)。
void clear_bit3(void) {a &= ~BIT3; // 将a的第3位清除为0
}
解释:
BIT3
的值是0x1 << 3
,即0b1000
。- 按位与运算符
&
与按位取反运算符~
用于将a
的第 3 位清除为0
,保持其他位不变。
假设 a
当前值为 0000 1101
(即 0xD
),调用 clear_bit3()
后:
BIT3
的值为0b1000
(即0x8
)。~BIT3
的值为~0b1000
,即0b0111
(即0x7
)。- 执行
a &= ~BIT3
:0000 1101 & 0000 0111 = 0000 0101
a
变为0000 0101
(即0x5
)。
154. 堆排序的过程
# 基本思路
-
步骤一:建立大根堆–将n个元素组成的无序序列构建一个大根堆,
-
步骤二:交换堆元素–交换堆尾元素和堆首元素,使堆尾元素为最大元素;
-
步骤三:重建大根堆–将前n-1个元素组成的无序序列调整为大根堆
重复执行步骤二和步骤三,直到整个序列有序。
举个例子:
- 步骤一:建立大根堆
① 无序序列建立完全二叉树
② 从最后一个叶子节点开始,从左到右,从下到上调整,将完全二叉树调整为大根堆
a.找到第1个非叶子节点6,由于6的右子节点9比6大,所以交换6和9。交换后,符合大根堆的结构。
c.找到第2个非叶子节点4,由于的4左子节点9比4大,所以交换4和9。交换后不符合大根堆的结构,继续从右到左,从下到上调整。
- 步骤二:交换堆元素(交换堆首和堆尾元素–获得最大元素)
- 步骤三:重建大根堆(前n-1个元素)
- 重复执行步骤二和步骤三,直到整个序列有序
155. 评论下面这个中断函数
中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展——让标准C支持中断。具体代表事实是,产生了一个新的关键字__interrupt
。下面的代码就使用了__interrupt关键字去定义一个中断服务子程序(ISR),请评论下面代码:
__interrupt double compute_area (double radius) { double area = PI * radius * radius; printf(" Area = %f", area); return area; }
评论:
这段中断服务程序主要有以下四个问题:
- ISR不能返回一个值
- ISR不能传递参数
- 在ISR中做浮点运算是不明智的
- printf()经常有重入和性能上的问题
解释:
这段话是在指出代码中与中断服务程序(Interrupt Service Routine, ISR)相关的不正确用法和潜在问题。我们来看具体有哪些问题以及它们的影响。
问题 1:ISR不能返回一个值
在中断服务程序中,ISR是不会返回值的。中断处理程序应该在处理完特定的任务后,通过恢复被中断的程序继续执行。
示例:
void ISR_example() {// ISR logic here// ISR不能有return语句
}
问题 2:ISR不能传递参数
通常情况下,ISR的原型由硬件和低级驱动程序定义,不允许传递参数。ISR应该是一个无参数函数。
示例:
void ISR_example() {// ISR logic here
}
问题 3:在ISR中做浮点运算是不明智的
浮点运算通常会涉及到较长的处理时间,并且可能需要使用浮点寄存器。ISR应该尽可能短小和快速,避免使用浮点运算。
替代方案:
将需要的浮点运算委托到主程序中处理:
volatile double radius; // 使用全局或静态变量void ISR_example() {// 只设置标志位,并保存必要的数据radius = ...; // 从硬件中读取或计算一个简单的值,避免复杂计算isr_completed_flag = 1; // 标志位
}// 主程序中处理复杂计算
if (isr_completed_flag) {compute_area(radius);isr_completed_flag = 0;
}
问题 4:在ISR中使用printf函数是有问题的
printf
函数不适合在ISR中使用,因为printf
可能不是线程安全的,并且可能会导致重入问题。另外,printf
需要大量的处理时间,影响系统响应速度。
替代方案:
同样,将需要的输出操作放到主程序中:
volatile double area;
volatile int isr_completed_flag;void ISR_example() {// ISR 逻辑radius = ...;isr_completed_flag = 1;
}// 主程序
if (isr_completed_flag) {area = compute_area(radius);printf("Area = %f", area); // 在应用层进行输出isr_completed_flag = 0;
}
正确的ISR编写示例:
#include <stdio.h>#define PI 3.141592653589793volatile double radius;
volatile int isr_completed_flag = 0;void ISR_example() {// 仅设置标志位,并保存必要的值radius = ...; // 从硬件或者中断源读取值isr_completed_flag = 1; // 标志位
}// 主程序复杂计算
double compute_area(double rad) {return PI * rad * rad;
}int main() {while (1) {if (isr_completed_flag) {double area = compute_area(radius);printf("Area = %f\n", area); // 在应用层进行输出isr_completed_flag = 0;}// 其他主程序逻辑}return 0;
}
总结
这段代码指出的四个问题主要集中在ISR的设计和使用上。正确使用ISR对系统的实时性和性能有着至关重要的作用。ISR应该仅仅处理最关键的任务,并使用标志或队列机制将较为复杂的数据处理留给主程序完成,以确保系统的响应速度和稳定性。
重入问题(Reentrancy Issue) 是指在程序运行过程中,一个函数在其执行尚未完成时,被再次调用,引发的一系列问题。这种情况通常在多线程编程或中断处理程序中经常出现。
重入问题的典型场景
-
多线程编程:
在多线程环境下,同一个函数可能会被多个线程并发调用。如果这个函数使用了全局变量、静态变量或者对共享资源进行了不安全的操作,就可能会导致数据竞争和不可预测的行为。 -
中断处理程序:
当一个ISR正在执行时,另一个中断信号到来,此时ISR可能会被再次调用。如果ISR中的代码没有足够的保护机制(例如互斥锁),这种重入问题会导致数据不一致和系统崩溃。
例子分析
假设有一个中断处理程序ISR正在执行printf
函数,而这个函数尚未返回时,另一个中断触发,又进入了同一个ISR并再次调用了printf
,这就会导致重入问题,造成输出混乱或系统崩溃。
#include <stdio.h>volatile int isr_completed_flag = 0;void ISR_example() {static int count = 0; // 使用静态变量作为例子printf("ISR execution count: %d\n", ++count); // printf是重入不安全的isr_completed_flag = 1;
}int main() {while (1) {if (isr_completed_flag) {isr_completed_flag = 0;// 主程序执行}// 其他逻辑}return 0;
}
在这个例子中,如果ISR在第一次调用printf
时被中断,然后再次调用printf
,两个printf
调用会相互干扰,因为printf
需要维护自己的一些内部状态(如缓冲区、指针等),而这些状态并没有被保护。
如何避免重入问题
-
避免在ISR中使用重入不安全的函数:
尽量避免在ISR中调用如printf
、malloc/free
等非线程安全和重入不安全的函数。 -
使用互斥锁:
在多线程编程中,用互斥锁(Mutex)来保护共享资源,但需要注意,互斥锁不能用在ISR中,因为ISR的执行不能被阻塞。 -
禁用中断:
在进入关键区时临时禁用中断,防止ISR被重入,但要慎用,因为长时间禁用中断会影响系统的实时性。 -
使用原子操作:
对于需要并发访问的数据,使用原子操作或更高级别的同步机制来保证数据的一致性。
示例:使用标志位解决重入问题
#include <stdio.h>volatile int isr_started = 0;
volatile int isr_completed_flag = 0;void ISR_example() {if (isr_started == 0) { // 检查是否已经有ISR在执行isr_started = 1;// 执行安全的操作isr_completed_flag = 1;isr_started = 0; // 表示ISR执行完毕} else {// 忽略此中断或将其计入某缓存队列}
}int main() {while (1) {if (isr_completed_flag) {isr_completed_flag = 0;printf("ISR executed successfully\n");}// 其他逻辑}return 0;
}
在这个示例中,我们使用了一个标志位(isr_started
)来检查是否已经有ISR正在执行。这样可以避免同一个ISR被多次重入执行,从而防止重入问题。
总结
重入问题是由于在函数执行过程中再次调用该函数引起的一系列问题,尤其在多线程编程和中断处理程序中容易出现。为了避免重入问题,需要采取适当的同步机制和编程规范,如避开重入不安全的函数、使用互斥锁和原子操作等。
156. 构造函数能否成为虚函数
构造函数不能是虚函数。而且不能在构造函数中调用虚函数,因为那样实际执行的是父类的对应函数,因为自己还没有构造好。析构函数可以是虚函数,而且,在一个复杂类结构中,这往往是必须的。析构函数也可以是纯虚函数,但纯虚析构函数必须有定义体,因为析构函数的调用是在子类中隐含的。
请记住:
虚函数的动态绑定特性是实现重载的关键技术,动态绑定根据实际的调用情况查询相应类的虚函数表,调用相应的虚函数。
157. 析构函数也可以是纯虚函数,但纯虚析构函数必须有定义体,因为析构函数的调用是在子类中隐含的
1. 纯虚函数和析构函数的定义
- 纯虚函数:在类中声明为纯虚函数的成员函数表示,派生类必须实现该函数。纯虚函数的声明一般如下:
virtual void func() = 0;
- 析构函数:析构函数用于释放对象销毁时的资源,格式是:
virtual ~Base() { /* 可选的清理操作 */ }
2. 析构函数可以是纯虚函数
- 纯虚析构函数是一种特殊情况,允许基类的析构函数定义为纯虚函数,这意味着派生类必须继承该析构函数。为了标识一个类是抽象类(不能实例化),我们通常会将析构函数设为纯虚。
class Base {
public:virtual ~Base() = 0; // 纯虚析构函数
};
3. 为什么纯虚析构函数必须有定义体
纯虚函数一般不需要定义体,因为它们需要派生类来实现。但是,纯虚析构函数是特例,必须提供定义体,原因如下:
- 当对象销毁时,析构函数会从派生类向基类依次调用。
- 即使析构函数是纯虚的,基类的析构函数仍然会被调用,因为它负责清理基类中的资源。
- 如果没有定义体,那么当程序试图调用基类的析构函数时就会报错,导致无法正确地销毁对象。
4. 如何理解“析构函数的调用是在子类中隐含的”
在C++的多态机制下,当你使用指向基类的指针或引用去操作派生类对象时,如果该对象被销毁,析构过程将首先调用派生类的析构函数,接着是基类的析构函数。如果基类析构函数是纯虚函数,依然需要调用它。因此,纯虚析构函数的定义体负责基类资源的清理,虽然这部分清理是隐含在子类析构过程中的。
class Base {
public:virtual ~Base() = 0; // 纯虚析构函数声明
};Base::~Base() {std::cout << "Base class destructor\n";
}class Derived : public Base {
public:~Derived() {std::cout << "Derived class destructor\n";}
};int main() {Base* obj = new Derived();delete obj; // 会先调用 Derived 的析构函数,再调用 Base 的析构函数
}
在这个例子中,Derived
的析构函数先被调用,而后调用Base
的纯虚析构函数。如果Base
的纯虚析构函数没有定义体,程序会出错。
总结:
- 纯虚析构函数的存在:它使得类可以被定义为抽象类,并且仍然能执行基类的析构任务。
- 纯虚析构函数必须有定义体:即使是纯虚函数,析构时仍需调用基类的析构函数来完成清理工作。
- 析构调用是隐含的:当销毁派生类对象时,基类的析构函数自动被调用,无需手动干预。
158. 谈谈你对面向对象的认识
面向对象可以理解为对待每一个问题,都是首先要确定这个问题由几个部分组成,而每个部分其实就是一个对象。然后再分别设计这些对象,最后得到整个程序。传统的程序设计多是基于功能的思想来进行考虑和设计的,而面向对象的程序设计则是基于对象的角度来考虑问题。这样做能够使程序更加的简洁清晰。
请记住:
编程中接触最多的“面向对象编程技术”仅仅是面向对象技术中的一个组成部分。发挥面向对象技术的优势是一个综合的技术问题,不仅需要面向对象的分析,设计和编程技术,而且需要借助必要的建模和开发工具。
159. 引用与指针有什么区别?
- 引用必须被初始化,指针不必
- 引用初始化后不能被改变,指针可以改变所指的对象
- 不存在指向空值的引用,但是存在指向空值的指针
160. 描述实时系统的基本特性
在特定时间内完成特定的任务,实时性与可靠性
161. 全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量存储在静态存储区,局部变量在堆栈中。
162. 堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源。
解释:
堆栈溢出(Stack Overflow)是程序运行过程中常见的一种错误,通常由以下几个原因导致:
1. 递归深度过深
当一个函数递归调用自身太多次时,会不断在堆栈中分配新的栈帧。每个函数调用都会在栈中保留一些信息(如局部变量、返回地址等),如果递归深度过深或没有正确的递归终止条件,最终会耗尽栈空间,导致堆栈溢出。
- 示例:
void recursiveFunction() {// 没有基准条件,会一直递归下去recursiveFunction();}int main() {recursiveFunction();return 0;}
2. 无限循环的递归
类似于递归深度过深的情况,如果递归函数没有合适的终止条件,或终止条件无法被满足,递归会一直进行下去,导致堆栈溢出。
void faultyRecursiveFunction(int n) {// 错误的终止条件,导致递归无法终止if (n == 0) return;faultyRecursiveFunction(n - 1);}int main() {faultyRecursiveFunction(10); // 当n是一个无法到达的值时,会堆栈溢出return 0;}
3. 巨量局部变量分配
在函数中声明了大量的局部变量,特别是大数组或结构体,这些大数据结构都会占用大量的栈空间。如果总栈空间不足以容纳这些数据,也会导致堆栈溢出。
void largeArrayFunction() {int largeArray[1000000]; // 大量的局部变量会耗尽栈空间}int main() {largeArrayFunction();return 0;}
4. 无意的无限递归
有时由于程序逻辑错误或意外的条件,可能会导致意外的无限递归,导致堆栈溢出
void unintendedRecursion() {// 逻辑错误导致不断递归unintendedRecursion();}int main() {unintendedRecursion();return 0;}
5. 极深的调用链
即使不是递归函数,如果普通函数之间的调用深度非常深,例如在某些情况下会遇到非常复杂的嵌套调用,也可能导致堆栈溢出。
void A() { B(); }void B() { C(); }void C() { D(); }void D() { E(); }// ...int main() {A();return 0;}
预防和解决方法
- 限制递归深度:
- 在设计递归算法时,确保设定合理的终止条件。
- 可以使用尾递归优化(如果编译器支持),某些情况下能减少栈空间的使用。
- 局部变量放到堆中:
- 将大数组或大结构体的分配从栈上移到堆上,使用
malloc
或new
进行动态分配。
- 将大数组或大结构体的分配从栈上移到堆上,使用
void safeFunction() {int *largeArray = new int[1000000]; // 使用堆分配// 使用 largeArray ...delete[] largeArray;}
- 迭代替换递归:
- 如果递归的深度可能非常深,可以尝试将递归过程转换为迭代过程。
- 优化程序结构:
- 避免不必要的深层次函数调用,通过重构代码提升效率。
通过这些方法,可以有效地防止和解决堆栈溢出问题,提高程序的健壮性和稳定性。
163. IP地址的编码分为哪两个部分?
IP地址由两部分组成,网络号和主机号。
解释:
IP地址的编码通常分为两个主要部分:
- 网络部分(Network Portion)
- 主机部分(Host Portion)
网络部分(Network Portion)
网络部分标识一个特定的网络。它表明IP地址属于哪一个子网或网络。路由器使用网络部分来决定数据包传输的路径,即如何把数据包从源网络传输到目标网络。网络部分的长度由子网掩码(Subnetwork Mask,简称子网掩码)决定。
示例:
- 对于一个IPv4地址
192.168.1.10
,假设子网掩码为255.255.255.0
(通常表示为/24
),那么网络部分为192.168.1
。
主机部分(Host Portion)
主机部分标识网络中的特定设备(主机)。在同一个网络中的每个设备(如计算机、服务器、路由器等)都有一个唯一的主机部分。这个部分允许网络内部的设备彼此进行通信。
- 对于同一个IPv4地址
192.168.1.10
,假设子网掩码为255.255.255.0
,主机部分为最后一个字节10
。
子网掩码(Subnet Mask)
子网掩码用于区分IP地址中的网络部分和主机部分。子网掩码是一个32位的数字,在表示时常使用点分十进制格式(例如255.255.255.0
)。它有一系列的1(对应网络部分)后跟随一系列的0(对应主机部分)。
示例:
- 子网掩码
255.255.255.0
对应的二进制形式为:11111111.11111111.11111111.00000000
。
CIDR表示法
IP地址和子网掩码有时会一起使用以便简洁表示。这种表示方法叫做CIDR(Classless Inter-Domain Routing)。在CIDR中,一个IP地址后面跟随一个斜杠和子网掩码中1的数量。
示例:
- IP地址
192.168.1.10
,子网掩码255.255.255.0
,使用CIDR表示法为192.168.1.10/24
。
实际应用
-
默认网关:默认网关是一个特殊的IP地址,用于将数据包从一个子网传递到另一个子网。它通常具有主机部分中的最小或最大地址。
-
网络地址和广播地址:每个子网中有两个特殊的IP地址:
- 网络地址:网络中所有主机的第一个地址,用于标识子网。它的主机部分全为0。
- 广播地址:网络中所有主机的最后一个地址,用于向子网中的所有设备发送广播消息。它的主机部分全为1。
示例:
- 对于子网
192.168.1.0/24
:- 网络地址:
192.168.1.0
- 广播地址:
192.168.1.255
通过理解IP地址的这两个部分和子网掩码,可以更好地进行IP规划和网络配置,确保网络通信的高效和可靠。
- 网络地址:
相关文章:

C++面试速通宝典——7
150. 数据库连接池的作用 数据库连接池的作用包括以下几个方面: 资源重用:连接池允许多个客户端共享有限的数据库连接,减少频繁创建和销毁连接的开销,从而提高资源的利用率。 统一的连接管理:连接池集中管理数据库连…...

毕业设计 大数据电影数据分析与可视化系统
文章目录 0 简介1 课题背景2 效果实现3 爬虫及实现4 Flask框架5 Ajax技术6 Echarts7 最后 0 简介 今天学长向大家介绍一个机器视觉的毕设项目 🚩基于大数据的电影数据分析与可视化系统 项目运行效果(视频): 毕业设计 大数据电影评论情感分析 …...

第三届图像处理、计算机视觉与机器学习国际学术会议(ICICML 2024)
目录 重要信息 大会简介 组织单位 大会成员 征稿主题 会议日程 参会方式 重要信息 大会官网:www.icicml.org 大会时间:2024年11月22日-24日 大会地点:中国 深圳 大会简介 第三届图像处理、计算机视觉与机器学…...

OJ在线评测系统 微服务技术入门 单体项目改造为微服务 用Redis改造单机分布式锁登录
单体项目改造为微服务 什么是微服务 服务:提供某类功能的代码 微服务:专注于提供某类特定功能的代码 而不是把所有的代码放到同一个项目里 会把一个大的项目按照一定的功能逻辑进行划分 拆分成多个子模块 每个子模块可以独立运行 独立负责一类功能 …...

【机器学习】网络安全——异常检测与入侵防御系统
我的主页:2的n次方_ 随着全球互联网和数字基础设施的不断扩展,网络攻击的数量和复杂性都在显著增加。从传统的病毒和蠕虫攻击到现代复杂的高级持续性威胁(APT),网络攻击呈现出更加智能化和隐蔽化的趋势。面对这样的…...
【C语言】基础篇续
最大公约数HCF与最小公倍数LCM #include<stdio.h> int main(){int n1,n2,i,hcf,lcm;printf("Enter two numbers:");scanf("%d %d",&n1,&n2);for(i 1;i < n1 & i < n2;i){if(n1 % i 0 & n2 % i 0){hcf i;lcm (n1*n2)/hc…...

文件丢失一键找回,四大数据恢复免费版工具推荐!
丢失数据的情况虽然不经常出现,但一旦出现都会让人头疼不已,而这时候,要如何恢复丢失的数据呢?一款免费好用的数据恢复工具就派上用场了!接下来就为大家推荐几款好用的数据恢复工具! 福昕数据恢复 直达链…...

【学习笔记】手写一个简单的 Spring MVC
目录 一、什么是Spring MVC ? Spring 和 Spring MVC 的区别? Spring MVC 的运行流程? 二、实现步骤 1. DispatcherServlet 1. 创建一个中央分发器 拦截所有请求 测试 2. 接管 IOC 容器 1. 创建配置文件 2. 修改 web.xml 配置文件 …...
编程究竟难在哪里?
目录 一、将现实问题转化为代码二、应对需求的不断变化三、设计新算法的挑战结语 编程之难,常被概括为三个方面:首先,是将现实世界的问题转化为计算机语言的挑战;其次,是需求不断变化所带来的适应性难题;最…...

C#医学影像分析源码,医院影像中心PACS系统源码
医学影像系统源码,影像诊断系统PACS源码,C#语言,C/S架构的PACS系统全套源代码。 PACS系统是医院影像科室中应用的一种系统,主要用于获取、传输、存档和处理医学影像。它通过各种接口,如模拟、DICOM和网络,以…...
WooCommerce与wordpress是什么关系
WooCommerce与WordPress之间的关系非常紧密,因为WooCommerce实际上是一个为WordPress设计的插件。WordPress是一个内容管理系统(CMS),广泛用于创建各种类型的网站,包括博客、企业网站等。而WooCommerce则是一个免费且开源的电子商务插件&…...
Web常见的攻击方式及防御方法
Web常见的攻击方式及防御方法如下: 1. 跨站脚本(XSS) 攻击方式:恶意代码被注入到网页中,用户浏览时执行该代码,导致窃取用户信息、伪造页面等。防御: 对用户输入严格过滤、转义。使用安全的编…...

基于STM32的超声波测距仪设计
引言 本项目将基于STM32微控制器设计一个超声波测距仪,通过超声波传感器实现距离测量,并将结果显示在液晶屏上。该项目展示了STM32微控制器与超声波传感器、LCD显示器的接口通信,以及信号处理和距离计算的过程。 环境准备 1. 硬件设备 ST…...
【数据库】Java 集成mongodb— MongoTemplate 详解
MongoTemplate 是 Spring Data MongoDB 提供的核心类,用于简化与 MongoDB 数据库的交互。它封装了许多常见的数据库操作,使开发者能够轻松执行 CRUD(创建、读取、更新、删除)操作,处理复杂查询和聚合等。本文将详细介绍…...
腿和脚的动作透露出你的内心“世界”
离大脑越近的部位越容易受大脑控制,而腿脚离大脑最远,想要在第一时间进行伪装是很难的。当危险靠近时,我们的双腿会自然而然地进入戒备状态,产生一些不自觉的动作。因此,观察一个人的腿脚,可以帮助我们了解…...
Oracle架构之用户,权限,角色讲解
文章目录 1 用户1.1 简介1.1.1 定义1.1.2 用户相关信息1.1.2.1 用户默认表空间1.1.2.2 用户临时表空间1.1.2.3 用户资源文件1.1.2.4 用户表空间限额1.1.2.5 用户管理有关的数据字典 1.1.3 用户、模式、模式对象1.1.4 实例模式 SCOTT1.1.5 各个角色区别 1.2 用户管理1.2.1 创建用…...

Unity_Obfuscator Pro代码混淆工具_学习日志
Unity_Obfuscator Pro代码混淆工具_学习日志 切勿将密码或 API 密钥存储在您附带的应用程序内。 混淆后的热更新暂时没有想到怎么办 Obfuscator 文档 https://docs.guardingpearsoftware.com/manual/Obfuscator/Description.html商店链接Obfuscator Pro(大约$70&a…...

已解决:org.springframework.web.HttpMediaTypeNotAcceptableException
文章目录 写在前面问题描述报错原因分析: 解决思路解决办法1. 确保客户端请求的 Accept 头正确2. 修改 Controller 方法的 produces 参数3. 配置合适的消息转换器4. 检查 Spring 配置中的媒体类型5. 其他解决方案 总结 写在前面 在开发过程中,Spring 框…...
C/C++简单编译原理
我们写的头文件和.cpp文件究竟是如何在电脑中运行的? 先明确几个文件类型: 1、头文件(.h .hpp) 第三方头文件、系统头文件、自编头文件…… 2、编译单位(.cpp .c cu) 自己写的脚本文件 3、目标文件&…...

文件处理不再难:带你轻松攻克C语言文件操作
嘿嘿,家人们,今天咱们来详细剖析C语言中的文件操作,好啦,废话不多讲,开干! 目录 1:为什么使用文件 2:文件的概念 2.1:程序文件 2.2:数据文件 2.3:文件名 3:二进制文件与文本文件 4:文件的打开与关闭 4.1:流与标准流 4.1.1:流 4.1.2:标准流 4.2:文件指针 4.3:文件的…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
前端打包工具简单介绍
前端打包工具简单介绍 一、Webpack 架构与插件机制 1. Webpack 架构核心组成 Entry(入口) 指定应用的起点文件,比如 src/index.js。 Module(模块) Webpack 把项目当作模块图,模块可以是 JS、CSS、图片等…...