【CPP】CPP经典面试题
文章目录
- 引言
- 1. C++ 基础
- 1.1 C++ 中的 `const` 关键字
- 1.2 C++ 中的 `static` 关键字
- 2. 内存管理
- 2.1 C++ 中的 `new` 和 `delete`
- 2.2 内存泄漏
- 3. 面向对象编程
- 3.1 继承和多态
- 3.2 多重继承
- 4. 模板和泛型编程
- 4.1 函数模板
- 4.2 类模板
- 5. STL 和标准库
- 5.1 容器
- 5.2 迭代器
- 6. 高级特性
- 6.1 移动语义和右值引用
- 6.2 Lambda 表达式
- 7. 设计模式
- 7.1 单例模式
- 7.2 工厂模式
- 8. 性能优化
- 8.1 内联函数
- 8.2 缓存友好性
- 9. 并发编程
- 9.1 线程
- 9.2 条件变量
- 10. 异常处理
- 10.1 异常机制
- 11. C++17 和 C++20 新特性
- 11.1 C++17 新特性
- 11.2 C++20 新特性
- 12. 实际应用
- 12.1 智能指针
- 12.2 RAII 原则
- 13. 调试和测试
- 13.1 调试技巧
- 13.2 单元测试
- 13.3 性能分析
- 14. C++ 编码规范
- 14.1 命名规范
- 14.2 代码格式化
- 15. C++ 项目构建
- 15.1 Makefile
- 15.2 CMake
- 16. C++ 未来发展趋势
- 16.1 C++23 新特性
- 16.2 C++ 的未来
- 结语

引言
C++ 是一门强大且复杂的编程语言,广泛应用于系统编程、游戏开发、嵌入式系统和高性能计算等领域。由于其灵活性和性能优势,C++ 程序员在面试中常常会遇到各种深入的问题。本文将探讨一些经典的 C++ 面试题,涵盖从基础语法到高级特性的多个方面,帮助读者更好地准备面试。
1. C++ 基础
1.1 C++ 中的 const 关键字
const 是 C++ 中用于定义常量的关键字。它可以用于修饰变量、函数参数、函数返回值以及成员函数。
问题: const 和 #define 有什么区别?
答案:
const是类型安全的,编译器会进行类型检查,而#define是宏定义,只是简单的文本替换。const定义的常量在编译时分配内存,而#define不分配内存。const可以用于修饰类的成员函数,表示该函数不会修改类的成员变量。
问题: const 成员函数的作用是什么?
答案:
const 成员函数表示该函数不会修改类的成员变量。它可以被 const 对象调用,而非 const 对象既可以调用 const 成员函数,也可以调用非 const 成员函数。
1.2 C++ 中的 static 关键字
static 关键字在 C++ 中有多种用途,包括修饰局部变量、全局变量、类成员变量和类成员函数。
问题: static 局部变量和普通局部变量有什么区别?
答案:
static局部变量的生命周期贯穿整个程序运行期间,即使函数调用结束,static局部变量也不会被销毁。- 普通局部变量的生命周期仅限于函数调用期间,函数调用结束后,局部变量会被销毁。
问题: static 成员函数和普通成员函数有什么区别?
答案:
static成员函数不依赖于类的实例,可以直接通过类名调用。static成员函数不能访问类的非静态成员变量和非静态成员函数,因为它们没有this指针。
2. 内存管理
2.1 C++ 中的 new 和 delete
new 和 delete 是 C++ 中用于动态内存分配和释放的操作符。
问题: new 和 malloc 有什么区别?
答案:
new是 C++ 的操作符,而malloc是 C 标准库函数。new会自动调用对象的构造函数,malloc不会。new返回的是对象类型的指针,malloc返回的是void*,需要显式类型转换。new分配内存失败时会抛出std::bad_alloc异常,malloc失败时返回NULL。
问题: delete 和 free 有什么区别?
答案:
delete是 C++ 的操作符,而free是 C 标准库函数。delete会自动调用对象的析构函数,free不会。delete用于释放new分配的内存,free用于释放malloc分配的内存。
2.2 内存泄漏
内存泄漏是指程序在动态分配内存后,未能正确释放该内存,导致内存占用不断增加。
问题: 如何避免内存泄漏?
答案:
- 使用智能指针(如
std::unique_ptr和std::shared_ptr)来管理动态内存。 - 确保每次
new操作都有对应的delete操作。 - 使用 RAII(Resource Acquisition Is Initialization)原则,将资源的生命周期与对象的生命周期绑定。
3. 面向对象编程
3.1 继承和多态
继承和多态是面向对象编程中的核心概念。
问题: 什么是虚函数?为什么需要虚函数?
答案:
虚函数是用于实现多态的机制。通过在基类中声明虚函数,派生类可以重写该函数,从而实现运行时多态。当通过基类指针或引用调用虚函数时,实际调用的是派生类的重写函数。
问题: 虚函数表(vtable)是什么?
答案:
虚函数表是编译器为每个包含虚函数的类生成的一个表,表中存储了虚函数的地址。每个对象在内存中都有一个指向虚函数表的指针(vptr),通过这个指针可以在运行时确定调用哪个虚函数。
3.2 多重继承
多重继承是指一个类可以从多个基类继承。
问题: 多重继承会带来什么问题?如何解决?
答案:
多重继承可能导致菱形继承问题(Diamond Problem),即一个类从两个基类继承,而这两个基类又共同继承自同一个基类,导致派生类中包含多个相同的基类子对象。可以通过虚继承(virtual inheritance)来解决这个问题。
4. 模板和泛型编程
4.1 函数模板
函数模板允许编写通用的函数,可以处理不同类型的参数。
问题: 函数模板和函数重载有什么区别?
答案:
- 函数模板通过参数类型推导生成具体的函数实例,适用于不同类型的数据。
- 函数重载是通过定义多个同名函数,每个函数处理不同类型的参数。
问题: 如何特化一个函数模板?
答案:
可以通过显式特化或部分特化来为特定类型提供特殊的实现。显式特化是为特定类型提供完全不同的实现,而部分特化是为特定类型的一部分提供不同的实现。
4.2 类模板
类模板允许编写通用的类,可以处理不同类型的数据。
问题: 类模板和模板类的区别是什么?
答案:
- 类模板是模板的定义,尚未实例化。
- 模板类是类模板实例化后的具体类。
问题: 如何特化一个类模板?
答案:
可以通过显式特化或部分特化来为特定类型提供特殊的实现。显式特化是为特定类型提供完全不同的实现,而部分特化是为特定类型的一部分提供不同的实现。
5. STL 和标准库
5.1 容器
STL 提供了多种容器,如 vector、list、map 等。
问题: vector 和 list 有什么区别?
答案:
vector是动态数组,支持随机访问,插入和删除操作在尾部高效,但在中间或头部效率较低。list是双向链表,不支持随机访问,插入和删除操作在任何位置都高效。
问题: map 和 unordered_map 有什么区别?
答案:
map是基于红黑树实现的,元素按键值有序存储,查找、插入和删除操作的时间复杂度为 O(log n)。unordered_map是基于哈希表实现的,元素无序存储,查找、插入和删除操作的平均时间复杂度为 O(1)。
5.2 迭代器
迭代器是用于遍历容器中元素的对象。
问题: 迭代器的种类有哪些?
答案:
- 输入迭代器:只能读取元素,单向移动。
- 输出迭代器:只能写入元素,单向移动。
- 前向迭代器:可以读取和写入元素,单向移动。
- 双向迭代器:可以读取和写入元素,双向移动。
- 随机访问迭代器:可以读取和写入元素,支持随机访问。
6. 高级特性
6.1 移动语义和右值引用
移动语义和右值引用是 C++11 引入的重要特性,用于提高性能。
问题: 什么是右值引用?为什么需要右值引用?
答案:
右值引用是用于绑定临时对象(右值)的引用类型,通过 && 表示。右值引用允许将资源(如动态内存)从一个对象“移动”到另一个对象,避免不必要的拷贝操作,从而提高性能。
问题: 什么是移动构造函数和移动赋值运算符?
答案:
移动构造函数和移动赋值运算符是用于实现移动语义的特殊成员函数。移动构造函数接受一个右值引用参数,将资源从源对象移动到目标对象。移动赋值运算符也接受一个右值引用参数,将资源从源对象移动到目标对象,并释放目标对象原有的资源。
6.2 Lambda 表达式
Lambda 表达式是 C++11 引入的匿名函数,可以方便地定义和使用函数对象。
问题: Lambda 表达式的语法是什么?
答案:
Lambda 表达式的语法为:
[捕获列表](参数列表) -> 返回类型 { 函数体 }
捕获列表用于指定 Lambda 表达式可以访问的外部变量,参数列表和返回类型与普通函数类似。
问题: Lambda 表达式的捕获列表有哪些方式?
答案:
[&]:以引用方式捕获所有外部变量。[=]:以值方式捕获所有外部变量。[&x, =y]:以引用方式捕获x,以值方式捕获y。[this]:捕获当前对象的this指针。
7. 设计模式
7.1 单例模式
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。
问题: 如何实现线程安全的单例模式?
答案:
可以通过双重检查锁定(Double-Checked Locking)或使用局部静态变量来实现线程安全的单例模式。
class Singleton {
public:static Singleton& getInstance() {static Singleton instance;return instance;}private:Singleton() {}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};
7.2 工厂模式
工厂模式是一种创建型设计模式,用于创建对象而不指定具体的类。
问题: 工厂模式和抽象工厂模式有什么区别?
答案:
- 工厂模式定义一个创建对象的接口,但由子类决定实例化哪个类。
- 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
8. 性能优化
8.1 内联函数
内联函数是一种优化技术,通过在调用点展开函数体来减少函数调用的开销。
问题: 内联函数有什么优缺点?
答案:
- 优点:减少函数调用的开销,提高执行效率。
- 缺点:增加代码体积,可能导致缓存不命中,影响性能。
问题: 如何定义内联函数?
答案:
可以通过 inline 关键字定义内联函数,或者在类定义中直接定义成员函数。
inline int add(int a, int b) {return a + b;
}
8.2 缓存友好性
缓存友好性是指程序在访问内存时能够充分利用 CPU 缓存,减少缓存未命中的次数。
问题: 如何编写缓存友好的代码?
答案:
- 尽量使用连续内存访问模式,如数组遍历。
- 避免频繁的内存分配和释放,减少内存碎片。
- 使用适当的数据结构和算法,减少不必要的内存访问。
9. 并发编程
9.1 线程
C++11 引入了多线程支持,提供了 std::thread 类。
问题: 如何创建和启动一个线程?
答案:
可以通过 std::thread 类创建和启动一个线程,线程函数可以是普通函数、Lambda 表达式或成员函数。
#include <iostream>
#include <thread>void threadFunc() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(threadFunc);t.join();return 0;
}
问题: 如何避免数据竞争?
答案:
可以通过互斥锁(std::mutex)、原子操作(std::atomic)或其他同步机制来避免数据竞争。
9.2 条件变量
条件变量是用于线程间同步的机制,允许线程等待某个条件成立。
问题: 如何使用条件变量?
答案:
可以通过 std::condition_variable 和 std::mutex 来实现线程间的条件等待和通知。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void waitForReady() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; });std::cout << "Ready!" << std::endl;
}void setReady() {std::this_thread::sleep_for(std::chrono::seconds(1));{std::lock_guard<std::mutex> lock(mtx);ready = true;}cv.notify_all();
}int main() {std::thread t1(waitForReady);std::thread t2(setReady);t1.join();t2.join();return 0;
}
10. 异常处理
10.1 异常机制
C++ 提供了异常处理机制,允许程序在运行时处理错误。
问题: try、catch 和 throw 的作用是什么?
答案:
try块用于包含可能抛出异常的代码。catch块用于捕获并处理异常。throw用于抛出异常。
问题: 如何自定义异常类?
答案:
可以通过继承 std::exception 类来定义自定义异常类,并重写 what() 方法以提供异常描述。
#include <exception>
#include <string>class MyException : public std::exception {
public:MyException(const std::string& msg) : msg(msg) {}const char* what() const noexcept override {return msg.c_str();}private:std::string msg;
};
11. C++17 和 C++20 新特性
11.1 C++17 新特性
C++17 引入了许多新特性,如结构化绑定、std::optional、std::variant 等。
问题: 什么是结构化绑定?
答案:
结构化绑定允许将结构体或数组的元素绑定到变量上,简化代码。
#include <iostream>
#include <tuple>int main() {std::tuple<int, double, std::string> t(1, 2.0, "hello");auto [a, b, c] = t;std::cout << a << ", " << b << ", " << c << std::endl;return 0;
}
11.2 C++20 新特性
C++20 引入了更多新特性,如概念(Concepts)、范围(Ranges)、协程(Coroutines)等。
问题: 什么是概念(Concepts)?
答案:
概念是用于约束模板参数的机制,可以在编译时检查模板参数是否满足特定要求。
#include <concepts>
#include <iostream>template<typename T>
requires std::integral<T>
void print(T value) {std::cout << value << std::endl;
}int main() {print(42); // OK// print(3.14); // Error: does not satisfy std::integralreturn 0;
}
12. 实际应用
12.1 智能指针
智能指针是 C++11 引入的用于自动管理动态内存的工具。
问题: std::unique_ptr 和 std::shared_ptr 有什么区别?
答案:
std::unique_ptr是独占所有权的智能指针,不能复制,只能移动。std::shared_ptr是共享所有权的智能指针,通过引用计数管理资源,可以复制和移动。
问题: 如何使用 std::make_shared?
答案:
std::make_shared 是用于创建 std::shared_ptr 的工厂函数,可以一次性分配内存并创建对象。
#include <memory>
#include <iostream>int main() {auto ptr = std::make_shared<int>(42);std::cout << *ptr << std::endl;return 0;
}
12.2 RAII 原则
RAII(Resource Acquisition Is Initialization)是 C++ 中的重要原则,用于管理资源。
问题: 什么是 RAII 原则?
答案:
RAII 原则是指将资源的生命周期与对象的生命周期绑定,通过对象的构造函数获取资源,通过析构函数释放资源,确保资源在对象销毁时自动释放。
问题: 如何实现 RAII?
答案:
可以通过类的构造函数和析构函数来实现 RAII。例如,使用智能指针管理动态内存,使用 std::fstream 管理文件资源等。
#include <fstream>
#include <iostream>class FileHandler {
public:FileHandler(const std::string& filename) : file(filename) {if (!file.is_open()) {throw std::runtime_error("Failed to open file");}}~FileHandler() {file.close();}void write(const std::string& data) {file << data;}private:std::ofstream file;
};int main() {try {FileHandler fh("test.txt");fh.write("Hello, RAII!");} catch (const std::exception& e) {std::cerr << e.what() << std::endl;}return 0;
}
13. 调试和测试
13.1 调试技巧
调试是程序开发中的重要环节,掌握调试技巧可以提高开发效率。
问题: 如何使用 GDB 调试 C++ 程序?
答案:
- 编译时添加
-g选项生成调试信息。 - 使用
gdb启动程序,设置断点,单步执行,查看变量值等。
g++ -g -o my_program my_program.cpp
gdb ./my_program
问题: 如何使用 assert 进行调试?
答案:
assert 是用于检查条件的宏,如果条件为假,程序会终止并输出错误信息。
#include <cassert>
#include <iostream>int main() {int x = 5;assert(x == 5);std::cout << "Assertion passed" << std::endl;return 0;
}
13.2 单元测试
单元测试是软件开发中的重要实践,用于验证代码的各个单元(如函数、类)是否按预期工作。
问题: 什么是单元测试?为什么需要单元测试?
答案:
- 单元测试是对代码的最小可测试单元(如函数、方法)进行测试的过程。
- 单元测试可以帮助开发者尽早发现代码中的错误,提高代码质量,减少回归问题的发生。
问题: 如何使用 Google Test 进行单元测试?
答案:
Google Test 是一个流行的 C++ 单元测试框架。以下是一个简单的示例:
#include <gtest/gtest.h>int add(int a, int b) {return a + b;
}TEST(AddTest, HandlesPositiveInput) {EXPECT_EQ(add(1, 2), 3);EXPECT_EQ(add(10, 20), 30);
}TEST(AddTest, HandlesNegativeInput) {EXPECT_EQ(add(-1, -2), -3);EXPECT_EQ(add(-10, -20), -30);
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
编译并运行测试:
g++ -std=c++11 -isystem /path/to/gtest/include -pthread test.cpp /path/to/gtest/libgtest.a /path/to/gtest/libgtest_main.a -o test
./test
13.3 性能分析
性能分析是优化代码性能的关键步骤,帮助开发者找到代码中的性能瓶颈。
问题: 如何使用 gprof 进行性能分析?
答案:
gprof 是一个常用的性能分析工具,可以生成函数调用图和执行时间统计。
-
编译时添加
-pg选项:g++ -pg -o my_program my_program.cpp -
运行程序生成性能数据:
./my_program -
使用
gprof分析性能数据:gprof my_program gmon.out > analysis.txt
问题: 如何使用 valgrind 进行内存分析?
答案:
valgrind 是一个强大的工具,用于检测内存泄漏和内存错误。
-
安装
valgrind:sudo apt-get install valgrind -
使用
valgrind运行程序:valgrind --leak-check=full ./my_program -
查看输出,分析内存泄漏和错误。
14. C++ 编码规范
14.1 命名规范
良好的命名规范可以提高代码的可读性和可维护性。
问题: C++ 中常见的命名规范有哪些?
答案:
- 变量和函数名使用小写字母和下划线分隔(
snake_case)。 - 类名使用大写字母开头的驼峰命名法(
PascalCase)。 - 常量名使用全大写字母和下划线分隔(
UPPER_CASE)。
问题: 为什么命名规范很重要?
答案:
命名规范可以提高代码的可读性,使其他开发者更容易理解代码的意图,减少沟通成本。
14.2 代码格式化
代码格式化是保持代码风格一致的重要手段。
问题: 如何使用 clang-format 格式化代码?
答案:
clang-format 是一个自动格式化 C++ 代码的工具。
-
安装
clang-format:sudo apt-get install clang-format -
创建配置文件
.clang-format:clang-format -style=llvm -dump-config > .clang-format -
格式化代码:
clang-format -i my_program.cpp
15. C++ 项目构建
15.1 Makefile
Makefile 是用于自动化构建 C++ 项目的工具。
问题: 如何编写一个简单的 Makefile?
答案:
以下是一个简单的 Makefile 示例:
CXX = g++
CXXFLAGS = -std=c++11 -Wall
TARGET = my_program
SRCS = main.cpp utils.cpp
OBJS = $(SRCS:.cpp=.o)all: $(TARGET)$(TARGET): $(OBJS)$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS)%.o: %.cpp$(CXX) $(CXXFLAGS) -c $< -o $@clean:rm -f $(OBJS) $(TARGET)
问题: 如何使用 make 构建项目?
答案:
在项目根目录下运行以下命令:
make
15.2 CMake
CMake 是一个跨平台的构建工具,可以生成 Makefile 或其他构建系统的配置文件。
问题: 如何编写一个简单的 CMakeLists.txt?
答案:
以下是一个简单的 CMakeLists.txt 示例:
cmake_minimum_required(VERSION 3.10)
project(MyProgram)set(CMAKE_CXX_STANDARD 11)add_executable(my_program main.cpp utils.cpp)
问题: 如何使用 CMake 构建项目?
答案:
-
创建构建目录并进入:
mkdir build cd build -
运行
cmake生成构建文件:cmake .. -
使用
make构建项目:make
16. C++ 未来发展趋势
16.1 C++23 新特性
C++23 是 C++ 的下一个版本,预计将引入更多新特性。
问题: C++23 可能引入哪些新特性?
答案:
- 模块化标准库(Modular Standard Library)。
- 协程改进(Coroutine Improvements)。
- 更强大的概念支持(Enhanced Concepts)。
16.2 C++ 的未来
C++ 作为一门历史悠久的语言,仍在不断进化。
问题: C++ 的未来发展方向是什么?
答案:
- 更加注重性能和安全性。
- 引入更多现代编程范式,如函数式编程。
- 提高开发效率,减少语言复杂性。
结语
C++ 是一门强大且复杂的语言,掌握其核心概念和高级特性对于成为一名优秀的 C++ 开发者至关重要。本文涵盖了许多经典的 C++ 面试题,希望能够帮助读者更好地准备面试,并在实际开发中运用这些知识。无论是初学者还是经验丰富的开发者,持续学习和实践都是提升技能的关键。
相关文章:
【CPP】CPP经典面试题
文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…...
Windows 中学习Docker环境准备2、Docker Desktop中安装ubuntu
Windows 中学习Docker环境准备1、Win11安装Docker Desktop Windows 中学习Docker环境准备2、Docker Desktop中安装ubuntu Windows 中学习Docker环境准备3、在Ubuntu中安装Docker 需要更多Docker学习视频和资料,请文末联系 一、安装 Docker Desktop 下载 Docker…...
C++11详解(三) -- 可变参数模版和lambda
文章目录 1.可变模版参数1.1 基本语法及其原理1.2 包扩展1.3 empalce系列接口1.3.1 push_back和emplace_back1.3.2 emplace_back在list中的使用(模拟实现) 2. lambda2.1 lambda表达式语法 1.可变模版参数 1.1 基本语法及其原理 1. C11支持可变参数模版&…...
网站打开提示不安全
当网站打开时显示“不安全”提示(通常表现为浏览器地址栏中出现“不安全”字样或红色警告图标),这意味着网站未使用有效的SSL证书或HTTPS协议,导致浏览器认为连接不安全。以下是解决这一问题的详细步骤: 一. 原因分析 …...
OpenCV:特征检测总结
目录 一、什么是特征检测? 二、OpenCV 中的常见特征检测方法 1. Harris 角点检测 2. Shi-Tomasi 角点检测 3. Canny 边缘检测 4. SIFT(尺度不变特征变换) 5. ORB 三、特征检测的应用场景 1. 图像匹配 2. 运动检测 3. 自动驾驶 4.…...
标志的推理
下面的讨论是我对《对编程实现拟人智能可行性的论证》这篇文章的“赋值与对象的标志”这一节的展开讨论。 标志能够使我们更好的思维(比如用轮廓标记物体对象,用兴奋强度标记回忆情况等等)。有思维标志、信息标志,单纯标志、组合…...
python学opencv|读取图像(五十七)使用cv2.bilateralFilter()函数实现图像像素双边滤波处理
【1】引言 前序学习过程中,已经掌握了对图像的基本滤波操作技巧,具体的图像滤波方式包括均值滤波、中值滤波和高斯滤波,相关文章链接有: python学opencv|读取图像(五十四)使用cv2.blur()函数实现图像像素…...
【SQL技术】不同数据库引擎 SQL 优化方案剖析
一、引言 在数据处理和分析的世界里,SQL 是不可或缺的工具。不同的数据库系统,如 MySQL、PostgreSQL(PG)、Doris 和 Hive,在架构和性能特点上存在差异,因此针对它们的 SQL 优化策略也各有不同。这些数据库中…...
链式结构二叉树(递归暴力美学)
文章目录 1. 链式结构二叉树1.1 二叉树创建 2. 前中后序遍历2.1 遍历规则2.2 代码实现图文理解 3. 结点个数以及高度等二叉树结点个数正确做法: 4. 层序遍历5. 判断是否完全二叉树 1. 链式结构二叉树 完成了顺序结构二叉树的代码实现,可以知道其底层结构…...
使用类别数据编码进行连续变量的特征提取
在数据科学和机器学习中,数据预处理是模型构建的重要步骤。对于处理结构化数据时,特别是包含类别型数据的场景,类别数据编码是必不可少的步骤。类别数据通常以文字、标签等形式出现,但大多数机器学习算法只能处理数值型数据,因此需要将类别数据转化为数值格式。编码方式的…...
PCL 最小包围圆(二维)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 最小包围圆是指能够包含给定点集中所有点的最小圆。这个算法通常用于计算几何、计算机图形学、机器学习等领域。以下是该算法的基本原理和实现流程: 1. 初始化:将点集中的所有点加入待处理列表。 2. 查找最远点:…...
技术文档管理最佳实践:高效、专业、可持续
文章目录 技术文档管理最佳实践:高效、专业、可持续1. 技术文档的核心价值1.1 降低知识流失风险1.2 提升开发效率1.3 增强团队协作1.4 规范技术资产管理 2. 技术文档分类与规范2.1 代码相关文档2.2 过程与运维文档2.3 知识与培训文档 3. 工具选型:自动化…...
56. Uboot移植实验
一、NXP官方Uboot编译与测试 1、将NXP提供的uboot拷贝到ubuntu中。 一个开发板也好运行uboot,DDR或者叫DRAM,串口,SD、EMMC、NAND。板子能工作。 测似结果: 1、uboot能正常启动 2、LCD驱动要根据所使用的屏幕修改。 3、NET初始…...
AI大模型:本地部署deepseek
一、安装lmstudio 1、下载网站: LM Studio - Discover, download, and run local LLMs 2、直接安装即可,记住安装的路径 二、下载deepseek模型 2.1、下载的流程 1、下载网站 https://huggingface.co/models 2、在搜索框输入:deepseek …...
(算法竞赛)图论+DFS深搜——图的dfs遍历1
题目描述 给定一个无向图,包含 n 个顶点(编号为 1 到 n)和 e 条边。要求从顶点 1 开始进行深度优先搜索(DFS),并按照访问顺序输出遍历结果。注意:当存在多个邻接点时,优先访问编号较…...
RK3588平台开发系列讲解(DMA篇)DMA engine使用
文章目录 一、DMA 使用步骤二、DMA接口2.1、DMA 通道管理相关接口2.2、DMA 描述符相关接口2.3、DMA 启动与控制接口2.4、DMA 状态检查接口2.5、 DMA 缓存管理接口2.6、DMA 中断与同步机制沉淀、分享、成长,让自己和他人都能有所收获!😄 Linux 内核的 DMA 引擎提供了一组完整…...
报名 | IEEE ICME 2025 音频编码器能力挑战赛正式开启
音频编码器是多模态大模型的重要组件,优秀的音频编码器在构建多模态系统中至关重要。在此背景下,小米集团、萨里大学、海天瑞声共同主办了 IEEE International Conference on Multimedia & Expo (ICME) 2025 Audio Encoder Capability Challenge。 …...
fputs的概念和使用案例
fputs 是 C 语言中用于向文件写入字符串的标准库函数。它与 puts 类似,但不会自动添加换行符,且支持向任意文件流(如磁盘文件、标准输出等)写入数据。 概念解析 函数原型:int fputs(const char *str, FILE *stream); …...
ASP.NET Core标识框架Identity
目录 Authentication与Authorization 标识框架(Identity) Identity框架的使用 初始化 自定义属性 案例一:添加用户、角色 案例二:检查登录用户信息 案例三:实现密码的重置 步骤 Authentication与Authorizatio…...
PFAS(全氟烷基和多氟烷基物质)测试流程详细介绍
PFAS(全氟烷基和多氟烷基物质)测试详细介绍 什么是PFAS? PFAS是(Per-and polyfluoroalkyl substances)的简称,中文名:全氟烷基和多氟烷基物质,是一系列合成有机氟化物的总称,是指至少含有一个…...
宝塔面板端口转发其它端口至MySQL的3306
最近需要把服务器的MySQL服务开放给外网,但又希望公开给所有人。也不想用默认的3306端口。同时也不想改变MySQL的默认端口。 这时候最好的办法就是用一个不常用的端口来转发至3306上去。例如使用49306至3306,外网通过49306来访问,内网依然使用…...
inquirer介绍及配合lerna在Vue中使用示例
目录 安装基本用法使用多个提示框动态选择(动态选项)表单式输入配合lerna在Vue中使用示例 Inquirer 是一个用于创建交互式命令行工具的 Node.js 库,常用于收集用户输入。它提供了多种类型的提示框,可以用于创建交互式应用程序&…...
AI商业化:如何包装技术并找到客户需求?
AI商业化:如何包装技术并找到客户需求? 适用人群:对人工智能技术有一定沉淀,正在探索技术变现和商业模式创新的创业者、技术团队以及企业管理者。同时也适合对 AI 产品包装、市场调研与用户调研感兴趣的从业人员。 一、引言 在过去几年里,从 GPT、Transformer 到 DeepSee…...
基于MODIS/Landsat/Sentinel/国产卫星遥感数据与DSSAT作物模型同化的作物产量估算
基于过程的作物生长模拟模型DSSAT是现代农业系统研究的有力工具,可以定量描述作物生长发育和产量形成过程及其与气候因子、土壤环境、品种类型和技术措施之间的关系,为不同条件下作物生长发育及产量预测、栽培管理、环境评价以及未来气候变化评估等提供了…...
OpenAI 宣布免费开放 ChatGPT 搜索,无需注册
在科技飞速发展的今天,人工智能领域的每一次突破都犹如一颗重磅炸弹,震撼着整个世界。北京时间 2025 年 2 月 6 日凌晨,OpenAI 宣布向所有用户开放 ChatGPT 搜索功能,且无需注册,这一消息瞬间引发了全球范围内的广泛关…...
如何打开vscode系统用户全局配置的settings.json
📌 settings.json 的作用 settings.json 是 Visual Studio Code(VS Code) 的用户配置文件,它存储了 编辑器的个性化设置,包括界面布局、代码格式化、扩展插件、快捷键等,是用户全局配置(影响所有…...
DeepSeek-V3本地Docker容器化部署
1. 安装Docker 确保已安装Docker Desktop for Mac: 下载并安装 Docker Desktop。 安装完成后,启动Docker Desktop。 验证安装: docker --version docker-compose --version 2. 克隆DeepSeek-V3仓库 git clone https://github.com/deeps…...
【Leetcode 每日一题】47. 全排列 II
问题背景 给定一个可包含重复数字的序列 n u m s nums nums,按任意顺序 返回所有不重复的全排列。 数据约束 1 ≤ n u m s . l e n g t h ≤ 8 1 \le nums.length \le 8 1≤nums.length≤8 − 10 ≤ n u m s [ i ] ≤ 10 -10 \le nums[i] \le 10 −10≤nums[i]≤…...
【Uniapp-Vue3】从uniCloud中获取数据
需要先获取数据库对象: let db uniCloud.database(); 获取数据库中数据的方法: db.collection("数据表名称").get(); 所以就可以得到下面的这个模板: let 函数名 async () > { let res await db.collection("数据表名称…...
【重生之学习C语言----杨辉三角篇】
目录 编辑 --------------------------------------begin---------------------------------------- 一、什么是杨辉三角? 二、问题分析 三、算法设计 使用二维数组存储杨辉三角: 递推关系: 格式化输出: 四、代码实现 完…...
