后端开发面经系列 -- 美团C++后端开发一面

美团C++后端开发一面

公众号:阿Q技术站

八股

1、指针和引用的区别,常引用了解吗,简单介绍下?

  1. 指针(Pointer):
    • 指针是一个变量,其值为另一个变量的地址。
    • 通过指针,我们可以直接访问和操作内存中的数据。
    • 指针使用解引用操作符*来访问其指向的变量的内容。
    • 指针在内存管理和数据结构中非常有用,但需要小心使用,以避免出现错误和安全问题。
  2. 引用(Reference):
    • 引用是变量的别名,它提供了一个已存在变量的新名称。
    • 引用在创建时必须初始化,并且在其生命周期内不能改变绑定的对象。
    • 引用在语法上类似于指针,但在语义上更接近于常规变量。
    • 引用通常用于函数参数传递和返回值,可以避免指针可能引发的一些问题,比如空指针异常。
  3. 常量引用(Const Reference):
    • 常量引用是指被声明为常量的引用。
    • 常量引用的主要特点是不能通过该引用修改其引用的值,但可以通过其他途径修改。
    • 常量引用通常用于传递函数参数,以确保被引用的值不会被意外修改。

2、说下多态,多态的作用和使用场景?

  1. 多态的作用:
    • 简化代码:通过多态,可以使用统一的接口来处理不同类的对象,从而简化了代码的逻辑。
    • 提高灵活性:可以在不改变代码结构的情况下,轻松地添加新的类和方法。
    • 降低耦合度:不同类之间通过接口进行交互,而不是直接依赖于具体的实现,从而降低了类之间的耦合度。
    • 可扩展性:在需要添加新的功能时,可以通过扩展现有的类和接口来实现,而不需要修改现有的代码。
  2. 多态的使用场景:
    • 继承关系中:多态通常与继承结合使用。通过继承,子类可以重写父类的方法,并且可以根据实际对象的类型调用相应的方法。
    • 方法重写(Override):子类可以重写父类的方法,当调用这些方法时,根据实际对象的类型会调用相应的重写方法。
    • 抽象类和接口:抽象类和接口定义了统一的方法接口,具体的子类可以根据需要实现这些方法,从而实现多态。

示例(C++):

#include <iostream>
using namespace std;// 基类
class Animal {
public:virtual void makeSound() {cout << "Animal makes a sound" << endl;}
};// 派生类
class Dog : public Animal {
public:void makeSound() override {cout << "Dog barks" << endl;}
};class Cat : public Animal {
public:void makeSound() override {cout << "Cat meows" << endl;}
};int main() {Animal* animal1 = new Dog();Animal* animal2 = new Cat();animal1->makeSound();  // 输出:Dog barksanimal2->makeSound();  // 输出:Cat meowsdelete animal1;delete animal2;return 0;
}

3、构造函数和析构函数可以是虚函数吗?

  1. 虚构造函数:
    • C++中并没有虚构造函数的概念,因为构造函数在对象创建时被调用,但在对象构造之前虚函数表还没有建立,因此构造函数不能是虚函数。换句话说,在构造函数中使用虚函数是没有意义的,因为在构造函数执行期间,对象的类型是不完整的,虚函数机制无法正常工作。
  2. 虚析构函数:
    • 虚析构函数是允许的,它允许在继承关系中正确地释放资源。如果一个类可能会被其他类继承,且通过基类指针删除派生类对象时,通常应该将析构函数声明为虚函数,以确保正确地调用派生类的析构函数。
    • 虚析构函数应该声明为virtual并且在基类中实现。这样,当通过基类指针删除派生类对象时,会首先调用派生类的析构函数,然后再调用基类的析构函数,确保资源得到正确释放。

示例(C++):

class Base {
public:virtual ~Base() { // 虚析构函数cout << "Base destructor" << endl;}
};class Derived : public Base {
public:~Derived() override { // 虚析构函数的重写cout << "Derived destructor" << endl;}
};int main() {Base* ptr = new Derived();delete ptr; // 输出:Derived destructor Base destructorreturn 0;
}

4、C++中内存区域分布是怎样的?

  1. 栈(Stack):

    • 栈是由编译器自动管理的,用于存储局部变量、函数参数、函数返回地址等。栈内存的分配和释放是自动进行的,当函数调用结束时,其在栈上分配的内存会自动被释放。
    • 栈内存的特点是大小固定,且分配释放速度快,但是生命周期短暂,不能用于存储动态分配的内存。
  2. 堆(Heap):

    • 堆是由程序员手动管理的,用于存储动态分配的内存。堆内存的分配和释放需要程序员显式地调用相关函数(如newdelete)来进行操作。
    • 堆内存的特点是大小不固定,分配释放速度较慢,但是生命周期可以很长,适合存储动态数据结构(如链表、树等)。
  3. 全局/静态存储区:

    • 全局变量和静态变量存储在这个区域中,它们在程序运行期间始终存在,直到程序结束才会被销毁。
    • 全局变量存储在程序的全局作用域中,静态变量可以在函数内部定义,也可以在全局作用域中定义,但是它们都具有静态生存期。
  4. 常量存储区:

    常量数据存储在这个区域中,包括字符串常量和其他类型的常量。这些常量在程序运行期间不可修改。

  5. 代码区:

    • 代码区存储程序的机器代码,包括所有的可执行代码和只读数据(如常量字符串)。
    • 代码区通常是只读的,不允许写入操作,用于存储程序的执行指令。

5、拷贝构造函数介绍下,如何用?

拷贝构造函数是在C++中用于创建一个对象的副本的特殊构造函数。当使用一个对象来初始化同类的另一个对象时,拷贝构造函数会被调用。拷贝构造函数通常有以下两种形式:

  1. 默认拷贝构造函数:

    如果你没有显式地定义一个类的拷贝构造函数,编译器会为你生成一个默认的拷贝构造函数。默认的拷贝构造函数会按照成员变量的顺序逐个进行拷贝构造,对于指针类型的成员变量,会进行浅拷贝(复制指针本身,而不是指针指向的对象)。

  2. 自定义拷贝构造函数:

    如果你需要实现自定义的拷贝行为,可以显式地定义一个拷贝构造函数。自定义的拷贝构造函数通常以引用方式接受一个同类对象作为参数,并且通常需要在函数体内实现对成员变量的深度拷贝(复制指针指向的对象)。

拷贝构造函数的用法:

  • 当你需要将一个对象的值传递给另一个对象时,会调用拷贝构造函数。例如,通过值传递方式传递对象给函数时,或者在函数中返回对象时,都会调用拷贝构造函数。
  • 当你需要创建一个对象的副本时,也会调用拷贝构造函数。例如,通过一个对象初始化另一个对象,或者将一个对象作为另一个对象的参数传递给构造函数时,都会调用拷贝构造函数。

示例(C++):

#include <iostream>
using namespace std;class MyString {
private:char* buffer;public:// 自定义拷贝构造函数MyString(const MyString& other) {// 深度拷贝 bufferint length = strlen(other.buffer);this->buffer = new char[length + 1];strcpy(this->buffer, other.buffer);cout << "Custom copy constructor called" << endl;}// 构造函数MyString(const char* input) {int length = strlen(input);this->buffer = new char[length + 1];strcpy(this->buffer, input);}// 析构函数~MyString() {delete[] this->buffer;}// 输出字符串void display() {cout << buffer << endl;}
};int main() {MyString str1("Hello");MyString str2 = str1;  // 调用拷贝构造函数str2.display();  // 输出:Helloreturn 0;
}

6、浅拷贝和深拷贝区别?

  1. 浅拷贝:
    • 浅拷贝是指将一个对象的成员变量逐个复制到另一个对象中。对于基本数据类型的成员变量,会直接进行值复制;对于指针类型的成员变量,只会复制指针的值,而不会复制指针所指向的对象。
    • 浅拷贝只复制了对象的表面结构,而没有复制指针所指向的动态分配的内存,因此两个对象共享同一块内存,容易造成悬空指针和内存泄漏等问题。
  2. 深拷贝:
    • 深拷贝是指将一个对象的所有成员变量以及指针所指向的对象都复制到另一个对象中。这意味着会递归地复制指针所指向的对象,而不是简单地复制指针的值。
    • 深拷贝会创建一个新的对象及其拷贝,两个对象各自拥有独立的内存空间,不会相互影响。因此,深拷贝通常需要对指针所指向的对象进行动态内存分配,并在拷贝时进行相应的内存管理。

区别总结:

  • 浅拷贝只复制对象的表面结构,对于指针成员变量只复制指针的值,不复制指针所指向的对象;深拷贝会递归地复制对象的所有内容,包括指针所指向的对象。
  • 浅拷贝容易造成对象间的数据共享和悬空指针问题;深拷贝能够完整地复制对象及其所有内容,不会出现共享和悬空指针问题。

示例:

#include <iostream>
#include <cstring>
using namespace std;class DeepCopyExample {
private:char* buffer;public:// 深拷贝构造函数DeepCopyExample(const DeepCopyExample& other) {int length = strlen(other.buffer);this->buffer = new char[length + 1];strcpy(this->buffer, other.buffer);}// 析构函数~DeepCopyExample() {delete[] this->buffer;}// 输出字符串void display() {cout << buffer << endl;}// 设置字符串void setBuffer(const char* input) {int length = strlen(input);this->buffer = new char[length + 1];strcpy(this->buffer, input);}
};int main() {DeepCopyExample obj1;obj1.setBuffer("Hello");DeepCopyExample obj2 = obj1;  // 深拷贝obj1.display();  // 输出:Helloobj2.display();  // 输出:Helloobj1.setBuffer("World");  // 修改 obj1 的 bufferobj1.display();  // 输出:Worldobj2.display();  // 输出:Hello(obj2 的 buffer 不受 obj1 的影响)return 0;
}

7、虚拟地址了解吗?

虚拟地址是指在计算机系统中由操作系统管理的一种抽象地址空间,它使得每个进程都拥有独立的地址空间,从而实现了进程间的隔离和保护。虚拟地址与物理地址相对应,物理地址是指内存中实际的存储位置,而虚拟地址是进程在访问内存时使用的地址。

虚拟地址的特点和作用如下:

  1. 隔离和保护:

    • 每个进程都拥有独立的虚拟地址空间,使得不同进程的内存访问彼此隔离,互不干扰。
    • 操作系统通过虚拟地址空间的管理,实现了对进程的保护,防止进程越界访问其他进程的内存空间或者操作系统内核的关键数据结构。
  2. 地址映射:

    • 虚拟地址需要通过地址映射机制才能转换为物理地址,这个过程由硬件的内存管理单元(MMU)和操作系统共同完成。
    • 操作系统会维护一个虚拟地址到物理地址的映射关系,通过这个映射关系,操作系统可以将进程的虚拟地址映射到实际的物理内存地址。
  3. 虚拟内存:

    • 虚拟地址的使用使得操作系统可以实现虚拟内存技术,这是一种将部分数据存储在磁盘上的技术,可以扩展系统的可用内存空间。
    • 当进程访问的数据不在物理内存中时,操作系统会将需要的数据从磁盘加载到内存,并更新虚拟地址到物理地址的映射关系。
  4. 虚拟地址空间布局:

    虚拟地址空间通常被划分为多个区域,包括代码区、数据区、堆区、栈区等。不同区域有不同的用途和访问权限。

8、虚拟内存作用(进程隔离,内存连续,mmap),优势和缺点?

  1. 作用:
    • 进程隔离:每个进程拥有独立的虚拟地址空间,使得不同进程的内存访问彼此隔离,互不干扰。
    • 内存连续性:虚拟内存可以使得物理内存的分配更加灵活,不需要连续的物理内存空间,从而解决了内存碎片问题。
    • 内存映射文件(mmap):虚拟内存可以将文件映射到进程的地址空间,从而实现文件的读写操作,这种技术常用于文件映射到内存进行快速访问,如内存映射文件、共享内存等。
  2. 优势:
    • 提高内存利用率:虚拟内存使得操作系统可以将实际内存和硬盘空间结合起来使用,从而提高了内存的利用率。
    • 简化内存管理:虚拟内存通过地址映射机制,使得操作系统可以更加灵活地管理内存,简化了内存管理的复杂度。
    • 提供了更大的地址空间:虚拟内存使得每个进程可以拥有更大的地址空间,从而支持更大的程序和数据。
  3. 缺点:
    • 性能开销:虚拟内存需要硬盘等外部存储设备作为支撑,因此在访问速度上会有一定的性能开销。
    • 额外的复杂性:虚拟内存增加了操作系统的复杂性,包括地址映射、页表管理、页面置换等方面的实现。
    • 容易产生页错误:由于虚拟内存需要将部分数据存储在硬盘上,因此在访问时可能会产生页错误,需要操作系统进行页面置换操作,影响了访问速度。

9、七层网络模型,每层的作用?

  1. 物理层:
    • 物理层负责在物理媒体上传输原始比特流,主要关注的是传输媒体、数据传输速率、接口标准等物理细节。
    • 物理层的作用是将比特流转换为电信号、光信号或者其他物理形式的信号,并负责在网络设备之间进行数据的传输。
  2. 数据链路层:
    • 数据链路层负责通过物理链路传输数据帧,处理帧的开始和结束标记,以及错误检测和纠正。
    • 数据链路层的作用是确保相邻节点之间的可靠数据传输,通过帧的确认和重传机制来实现数据的可靠性。
  3. 网络层:
    • 网络层负责在多个网络之间进行路由选择和数据转发,实现了不同网络之间的通信。
    • 网络层的作用是实现端到端的数据传输,通过路由选择算法确定数据传输的路径,并负责将数据包从源主机传输到目标主机。
  4. 传输层:
    • 传输层负责端到端的数据传输,提供了数据传输的可靠性和顺序性,同时也负责流量控制和拥塞控制。
    • 传输层的作用是建立端到端的连接,并且确保数据的可靠传输,同时通过流量控制和拥塞控制来管理网络的流量。
  5. 会话层:
    • 会话层负责建立、管理和终止会话连接,提供了数据交换的逻辑通路。
    • 会话层的作用是在通信节点之间建立会话连接,并负责会话的管理和维护,以实现数据的可靠传输和有效管理。
  6. 表示层:
    • 表示层负责数据的格式转换、加密和解密、数据压缩和解压缩等功能,以便于不同系统之间的数据交换。
    • 表示层的作用是将应用层的数据格式转换为网络能够识别和传输的格式,同时也负责数据的安全性和可靠性。
  7. 应用层:
    • 应用层是最高层,负责为用户提供网络服务和接口,包括各种网络应用程序和协议。
    • 应用层的作用是为用户提供各种网络服务,如电子邮件、文件传输、远程登录等,同时也负责处理应用层协议的交互和管理。

10、TCP三次握手四次挥手的具体过程,为什么不能是三次挥手?

三次握手:

  1. 第一步(SYN):

    客户端发送一个带有 SYN(同步)标志的数据包给服务器,并进入 SYN_SENT 状态,表示客户端请求建立连接。

  2. 第二步(SYN + ACK):

    服务器收到 SYN 数据包后,如果同意建立连接,则会发送一个带有 SYN/ACK 标志的数据包给客户端,并进入 SYN_RCVD 状态。

  3. 第三步(ACK):

    客户端收到服务器的 SYN/ACK 数据包后,会发送一个带有 ACK 标志的数据包给服务器,表示确认连接建立,双方可以开始通信。

四次挥手:

  1. 第一步(FIN):

    客户端发送一个带有 FIN(结束)标志的数据包给服务器,表示客户端希望关闭连接,进入 FIN_WAIT_1 状态。

  2. 第二步(ACK):

    服务器收到客户端的 FIN 数据包后,发送一个带有 ACK 标志的数据包给客户端,表示收到了关闭请求,但仍然允许数据传输,服务器进入 CLOSE_WAIT 状态,客户端进入 FIN_WAIT_2 状态。

  3. 第三步(FIN):

    服务器完成数据传输后,发送一个带有 FIN 标志的数据包给客户端,表示服务器也准备关闭连接,服务器进入 LAST_ACK 状态。

  4. 第四步(ACK):

    客户端收到服务器的 FIN 数据包后,发送一个带有 ACK 标志的数据包给服务器,表示确认收到了关闭请求,客户端进入 TIME_WAIT 状态。

为什么不能是三次挥手?

三次握手建立连接时,客户端向服务器发送 SYN 数据包,服务器收到后回复 SYN/ACK 数据包,客户端再回复一个 ACK 数据包,这样双方就确认了连接的建立。但是在关闭连接时,为了保证数据的可靠传输,需要在双方都确认关闭之后才能断开连接。如果使用三次挥手,可能会出现以下问题:

  • 客户端发送 FIN 数据包后,服务器收到并发送 ACK 数据包,表示接受了关闭请求,但此时服务器可能还有数据需要传输。
  • 如果服务器在发送 ACK 数据包后立即关闭连接,客户端可能会因为网络延迟而没有收到服务器的所有数据。
  • 如果服务器在发送 ACK 数据包后等待一段时间再关闭连接,客户端可能会在此期间再次发送数据,导致服务器无法正确处理。

11、UDP和TCP的区别?

  1. 连接性:
    • TCP是一种面向连接的协议,通过三次握手建立连接,并且在传输数据时保证数据的可靠性和顺序性。
    • UDP是一种无连接的协议,不需要建立连接,也不会保证数据的可靠性和顺序性,数据包的发送和接收是独立的。
  2. 数据可靠性:
    • TCP保证数据的可靠性,通过序号、确认和重传机制来确保数据的正确传输和顺序到达,适用于需要可靠传输的应用。
    • UDP不保证数据的可靠性,数据包发送后不会进行确认和重传,适用于实时性要求高、数据丢失可以容忍的应用。
  3. 传输效率:
    • TCP的传输效率相对较低,因为它需要进行连接的建立、数据的确认和重传等操作,这些都会增加传输的延迟和开销。
    • UDP的传输效率相对较高,因为它不需要进行连接的建立和数据的确认,数据包的发送和接收是独立的,适用于实时性要求高的应用。
  4. 应用场景:
    • TCP适用于对数据可靠性要求较高的应用,如文件传输、网页访问等,这些应用需要保证数据的完整性和正确性。
    • UDP适用于对实时性要求较高的应用,如视频直播、音频通话等,这些应用对数据的实时性要求高,可以容忍一定的数据丢失。

12、进程和线程的区别?

  1. 定义:
    • 进程是程序在执行过程中的一个实例,它包含了程序的代码、数据和执行环境等资源,是操作系统进行资源分配和调度的基本单位。
    • 线程是进程内的一个独立执行流,是操作系统进行调度的基本单位,一个进程可以包含多个线程,它们共享进程的资源。
  2. 资源拥有:
    • 进程拥有独立的地址空间、文件描述符、信号处理器、优先级等资源,各个进程之间的资源是相互独立的。
    • 线程共享所属进程的地址空间和其他资源,如打开的文件、信号处理器等,线程之间可以方便地共享数据和通信。
  3. 调度和切换开销:
    • 进程的切换开销较大,因为它涉及到地址空间的切换、文件描述符的重定向等操作。
    • 线程的切换开销相对较小,因为它们共享了进程的地址空间等资源,切换时只需要保存和恢复线程的上下文即可。
  4. 并发性:
    • 进程是操作系统进行资源分配和调度的基本单位,不同进程之间的执行是并发的,它们各自拥有独立的地址空间和资源。
    • 线程是进程内的执行流,不同线程之间的执行是并发的,它们共享了进程的资源,可以方便地进行通信和数据共享。
  5. 创建和销毁开销:
    • 创建和销毁进程的开销较大,涉及到内存分配、资源初始化和清理等操作。
    • 创建和销毁线程的开销较小,因为它们共享了进程的资源,不需要额外的内存分配和资源初始化。

13、网页请求中get和post区别?

  1. 请求方式:
    • GET:通常用于获取数据,通过 URL 提交数据,数据在 URL 中可见,以键值对的形式出现在 URL 的查询字符串中,如 http://example.com/resource?param1=value1&param2=value2
    • POST:通常用于提交数据,数据在请求体中,不会显示在 URL 中,适用于提交表单数据等需要保密的情况。
  2. 数据传输:
    • GET:数据以查询字符串的形式附加在 URL 后面,长度有限制,一般不适用于传输大量数据。
    • POST:数据放在请求体中,没有长度限制,适用于传输大量数据。
  3. 安全性:
    • GET:由于数据在 URL 中可见,不适合传输敏感信息,如密码等。
    • POST:数据在请求体中,相对于 GET 更安全,适合传输敏感信息。
  4. 幂等性:
    • GET:幂等,多次请求相同的 URL,结果应该是一样的。
    • POST:不幂等,多次提交相同的数据,可能会产生不同的结果。
  5. 使用场景:
    • GET:适用于获取资源,如查看网页、下载文件等。
    • POST:适用于提交数据,如提交表单、上传文件等。

算法题

1、给n个区间(左闭右开,n <= 1e5),值域在1e9内,现在所有区间会合并,输出合并后的结果?

如有3个区间[1,3),[2,4),[4,6] => [1,4),[4,6]

LeetCode 56题

思路:

  1. 排序区间列表:

    首先,需要对给定的区间列表按照起点进行排序,以便后续合并操作。

  2. 初始化结果数组:

    初始化一个空的结果数组merged,用于存储合并后的区间。

  3. 依次合并区间:

    • 接下来,我们从第二个区间开始,依次与merged中的最后一个区间进行比较。
    • 如果当前区间的起点在merged中最后一个区间的终点之后(不相交),则将当前区间加入merged中。
    • 如果当前区间的起点在merged中最后一个区间的终点之前(相交),则更新merged中最后一个区间的终点为两者的最大值。
  4. 返回合并后的结果:

    最后,返回合并后的结果数组merged即可。

参考代码:

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;class Solution {
public:// 定义区间类型typedef vector<int> Interval;// 比较函数,用于区间按照起点排序static bool compareInterval(const Interval &a, const Interval &b) {return a[0] < b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {// 对区间列表按照起点进行排序sort(intervals.begin(), intervals.end(), compareInterval);// 初始化结果数组vector<vector<int>> merged;merged.push_back(intervals[0]);// 依次合并区间for (int i = 1; i < intervals.size(); i++) {if (intervals[i][0] > merged.back()[1]) {// 不相交,直接加入merged.push_back(intervals[i]);} else {// 相交,更新终点merged.back()[1] = max(merged.back()[1], intervals[i][1]);}}// 返回合并后的结果return merged;}
};int main() {// 测试示例vector<vector<int>> intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};Solution sol;vector<vector<int>> result = sol.merge(intervals);// 输出合并后的结果for (auto interval : result) {cout << "[" << interval[0] << ", " << interval[1] << "] ";}cout << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/11688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Shell三剑客之grep

前言&#xff1a; Shell三剑客是grep、sed和awk三个工具的简称,因功能强大&#xff0c;使用方便且使用频率高&#xff0c;因此被戏称为三剑客&#xff0c;熟练使用这三个工具可以极大地提升运维效率。 grep是文本查找或搜索工具,用于查找内容包含指定的范本样式的文本。它会一行…

Co-Driver:基于 VLM 的自动驾驶助手,具有类人行为并能理解复杂的道路场景

24年5月来自俄罗斯莫斯科研究机构的论文“Co-driver: VLM-based Autonomous Driving Assistant with Human-like Behavior and Understanding for Complex Road Scenes”。 关于基于大语言模型的自动驾驶解决方案的最新研究&#xff0c;显示了规划和控制领域的前景。 然而&…

call、apply、bind三者的区别

call、apply、bind都是可以改变函数 this 对象指向的方法&#xff0c;但它们也有各自的特点。 call() 写了就等于直接调用函数。写法如下&#xff1a; fun.call(obj,要传给函数的参数1,要传给函数的参数2...) call() 接收多个参数&#xff0c;第一个为函数上下文也就是this…

Bittensor怎么挖?手把手教你,使用bitget钱包

4月 Binance 上新 TheBittensorHub (TAO), 这个项目究竟做了什么可以令其在上大舞台前就已经在所有通证中排名前 30&#xff1f; 本文将深度解析。 该项目既不直接贡献数据&#xff0c;也不直接贡献算力。 而是通过区块链网络和激励机制&#xff0c;来对不同的算法进行调度和…

【HarmonyOS】综合应用-《校园通》

概念 本文结合之前的笔记文章知识点&#xff0c;做一个综合性的小应用。 创建一个ArkTS语言的鸿蒙项目&#xff0c;搭建首页面 其界面代码如下&#xff0c;该界面使用了垂直布局&#xff0c;相对布局&#xff0c;轮播布局&#xff0c;以及图片&#xff0c;文本等组件的综合运…

【CTF MISC】XCTF GFSJ0510 this_is_flag Writeup(信息收集)

this_is_flag Most flags are in the form flag{xxx}, for example:flag{th1s_!s_a_d4m0_4la9} 解法 大多数标志的形式都是flag{xxx}&#xff0c;例如&#xff1a;flag{th1s_!s_a_d4m0_4la9} Flag flag{th1s_!s_a_d4m0_4la9}声明 本博客上发布的所有关于网络攻防技术的文章…

具身智能论文(一)

目录 1. PoSE: Suppressing Perceptual Noise in Embodied Agents for Enhanced Semantic Navigation2. Embodied Intelligence: Bionic Robot Controller Integrating Environment Perception, Autonomous Planning, and Motion Control3. Can an Embodied Agent Find Your “…

免费的国内版 GPT 推荐,5个国产ai工具

提起AI&#xff0c;大家第一个想到的就是GPT。 虽然它确实很厉害&#xff0c;但奈何于我们水土不服&#xff0c;使用门槛有些高。 不过随着GPT的爆火&#xff0c;现在AI智能工具已经遍布到各行各业了&#xff0c;随着时间的推移&#xff0c;国内的AI工具也已经“百花盛放”了…

Pencils Protocol 提供层次化的 Staking,品牌升级不断

Pencils Protocol 是一个 Scroll 生态中的一个综合应用平台&#xff0c;在全新的品牌升级后(原为 Penpad)&#xff0c;其在原有的 LaunchPad 的基础上&#xff0c;进一步向收益聚合器、RWA 等板块进行全新的拓展。目前&#xff0c;Pencils Protocol 生态的整体功能板块包括 Lau…

人脸识别技术在访客管理中的应用

访客办理体系&#xff0c;能够使用于政府、戎行、企业、医院、写字楼等众多场所。在办理时&#xff0c;需求对来访人员身份进行精确认证&#xff0c;才能保证来访人员的进入对被访单位不被外来风险入侵。在核实身份时&#xff0c;比较好的方法就是选用人脸辨认技能&#xff0c;…

bat xcopy 解析

echo off set source_folder"C:\path\to\source" set destination_folder"C:\path\to\destination" set exclude_file"C:\path\to\excluded_folders.txt"REM 创建目标文件夹&#xff08;如果不存在&#xff09; mkdir %destination_folder% 2>…

【QEMU系统分析之实例篇(三十二)】

系列文章目录 第三十二章 QEMU系统仿真的机器创建分析实例 pcie.0 文章目录 系列文章目录第三十二章 QEMU系统仿真的机器创建分析实例pcie.0 前言一、QEMU是什么&#xff1f;二、QEMU系统仿真的机器创建分析实例1.系统仿真的命令行参数2. 将当前机器配置导出到文件qmp_x_exit…

JDK的串行收集器介绍与优化指南-01

JDK串行收集器概述 定义与背景 串行收集器&#xff08;Serial Collector&#xff09;是Java虚拟机&#xff08;JVM&#xff09;中的一种单线程垃圾收集器&#xff0c;它在垃圾收集过程中会暂停所有工作线程&#xff0c;直至收集完成。它适用于内存资源受限、对吞吐量要求不高…

探索Java的未来!

Java是一种成熟、稳定且广泛使用的编程语言&#xff0c;它在企业级应用、Android 应用开发和大数据处理等领域有着广泛的应用。虽然Java已经存在了30多年&#xff0c;但它依然在不断发展和进化。以下是一些可能会影响 Java 未来的因素&#xff1a; 新版本的发布&#xff1a;Jav…

【玄机平台】应急响应

前言&#xff1a; 感谢玄机平台靶机的提供&#xff0c;让我学到了不少东西 平台题解 &#xff1a; 第一章 应急响应-webshell查杀 1.黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx} ssh连接 下载/var/www/html源码&#xff08;finsehll连直接下&#xff09;压缩丢…

JavaWeb--15 tlias-web-management 黑马程序员 部门管理(修改部门信息)

tlias 1 需求分析和开发规范2 部门管理2.1 查询部门2.2 删除部门2.3 添加部门2.4 更新部门 1 需求分析和开发规范 需求说明–接口文档–思路分析–开发–测试–前后端联调 查看页面原型明确需求 根据页面原型和需求&#xff0c;进行表结构设计、编写接口文档(已提供) 阅读接口…

vue3专栏项目 -- 四、前后端结合(下)

一、async 和 await 1、使用async 和 await 改造异步请求 在接触后端API以后就遇到了越来越多的异步请求&#xff0c;现在我们就使用async 和 await 改造异步请求。 async function是把返回内容包裹成个Promise返回Promise await 它在async function里面才起作用&#xff0…

PHP 使用常量实现枚举类

PHP 使用常量实现枚举类 <?php abstract class Enum {private static $constCacheArray NULL;private static function getConstants() {if (self::$constCacheArray NULL) {self::$constCacheArray [];}$calledClass get_called_class();if (!array_key_exists($call…

ini配置文件怎么存取False

1、ini文件介绍 INI文件&#xff08;全称为Initialization File&#xff0c;初始化文件&#xff09;是一种简单的文本文件格式&#xff0c;用于存储配置数据。它广泛应用于操作系统和各种应用程序中&#xff0c;用来保存设置、参数或初始化信息。INI文件的基本结构包括节&…

服务器之间传输文件

服务器1传输到10.140.8.8里面&#xff0c;其中root账户 先-r参数递归压缩文件夹Dir为Dir.zip&#xff0c;然后传输Dir.zip会快一些&#xff0c;当然了&#xff0c;如果你scp递归传输也是可以用的 方法1&#xff1a;压缩后传输&#xff0c;非递归&#xff0c;推荐 zip -r Dir.z…