c++ 函数 类
一、函数定义
在 C++ 中,函数是组织代码逻辑的基本单元,用于实现模块化、复用、结构清晰的程序设计。
1、函数的基本结构
返回类型 函数名(参数列表) {
// 函数体
return 值; // 可选,视返回类型而定
}
声明(Declaration):
告诉编译器函数存在,通常放在头文件中:
int add(int a, int b); // 函数声明
定义(Definition):
提供函数实现,通常放在 .cpp
文件中:
int add(int a, int b) {
return a + b;
}
2、函数重载(Overload)
同一个函数名可以定义多个参数不同的函数:
void print(int x);
void print(double x);
void print(std::string s);
注意:参数数量或类型不同才能构成重载,返回类型不同不能单独构成重载。
3、默认参数值
void greet(std::string name = "Guest") {
std::cout << "Hello, " << name << "!\n";
}
greet(); // 输出 Hello, Guest!
greet("Alice"); // 输出 Hello, Alice!
4、内联函数(inline
)
建议编译器将函数代码插入调用处,适用于短小频繁调用的函数。
inline int square(int x) {
return x * x;
}
5、虚函数与纯虚函数
在 C++ 中,虚函数(virtual
)和纯虚函数(= 0
)是实现 多态性 的关键机制,但它们在语法、用途、作用上有所不同。
特性 | 虚函数(Virtual Function) | 纯虚函数(Pure Virtual Function) |
---|---|---|
定义方式 | virtual void foo(); |
virtual void foo() = 0; |
是否有实现 | 可以有实现(也可以没有) | 必须在子类中实现(抽象接口) |
是否必须重写 | 子类可选是否重写 | 子类必须重写(除非子类也是抽象类) |
所在类 | 可以在任何类中 | 必须出现在抽象类中(即包含纯虚函数的类) |
创建对象 | 可以实例化含虚函数的类 | 抽象类不可被实例化 |
用途 | 提供多态行为的默认实现 | 强制子类实现,作为接口规范 |
1. 虚函数示例(可重写)
class Animal {
public:
virtual void speak() {
std::cout << "Animal speaks\n";
}
};
class Dog : public Animal {
public:
void speak() override {
std::cout << "Dog barks\n";
}
};
Animal* p = new Dog();
p->speak(); // 输出:Dog barks(多态)
如果 Dog
不重写 speak()
,则会使用 Animal
的默认实现。
2. 纯虚函数示例(强制重写)
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing Circle\n";
}
};
// Shape s; // 错误,抽象类不能实例化
Shape* p = new Circle();
p->draw(); // 输出:Drawing Circle
若 Circle
不实现 draw()
,它也将变为抽象类。
接口类(interface)
C++ 没有 interface
关键字,但你可以用纯虚函数模拟接口类:
class IStream {
public:
virtual void read() = 0;
virtual void write() = 0;
virtual ~IStream() {} // 接口类应定义虚析构
};
6、Lambda 表达式(C++11 起)
[捕获列表](参数列表) -> 返回类型 {
函数体
}
其中:
[]
:捕获列表(可以捕获外部变量)()
:参数列表->
:返回类型(可省略){}
:函数体
匿名函数,通常用于简洁回调:
auto add = [](int a, int b) -> int {
return a + b;
};
std::cout << add(3, 5); // 输出:8
//返回类型如果能推导,可以省略 `-> int`:
auto add = [](int a, int b) {
return a + b;
};
std::cout << add(3, 4); // 输出 7
Lambda 表达式是 C++11 引入的一种匿名函数,用于定义可内联的函数对象,特别适合临时、小巧的函数使用场景,如算法回调、事件处理、线程创建等。
捕获外部变量(capture)
捕获方式 | 示例 | 说明 |
---|---|---|
值捕获 | [x] |
捕获变量 x 的值(拷贝) |
引用捕获 | [&x] |
捕获变量 x 的引用 |
捕获全部(值) | [=] |
捕获所有外部变量的值 |
捕获全部(引用) | [&] |
捕获所有外部变量的引用 |
混合捕获 | [=, &y] |
除 y 外其他变量值捕获 |
int x = 10;
int y = 5;
auto f = [=, &y]() {
// x 是值捕获,y 是引用捕获
std::cout << x + y << "\n";
y += 1; // 允许修改 y
};
f();
常见应用场景
- 与 STL 算法结合(如
std::sort
)
std::vector<int> v = {4, 2, 5, 1};
std::sort(v.begin(), v.end(), [](int a, int b) {
return a < b;
});
- 与线程一起使用:
#include <thread>
std::thread t([] {
std::cout << "In thread\n";
});
t.join();
可变 lambda(mutable
)
默认情况下,值捕获的变量是不可修改的。加上 mutable
可以让其变为可变:
int x = 5;
auto f = [x]() mutable {
x += 1; // 允许修改捕获变量的副本
std::cout << x;
};
f(); // 输出 6,但外部 x 不变
特殊函数类型
类型 | 用途 |
---|---|
构造函数 | 创建对象时自动调用 |
析构函数 | 对象销毁时自动调用 |
拷贝构造函数 | 对象以另一个对象初始化时调用 |
移动构造函数 | 右值初始化对象时调用 |
运算符重载函数 | 重载 + , == 等 |
虚函数 | 用于多态 |
纯虚函数 | 抽象类成员函数 |
二、函数参数值传递与引用传递
在 C++ 中,函数参数默认是值传递(pass-by-value),但 并不都是值传递,C++ 支持多种参数传递方式,主要包括以下几种:
1. 值传递(Pass by Value)
- 将实参的副本传入函数
- 函数内对参数的修改不会影响原变量
void foo(int x) {
x = 100;
}
int main() {
int a = 10;
foo(a);
std::cout << a; // 输出 10,不变
}
2. 引用传递(Pass by Reference)
- 传入变量的别名,函数内对其修改会影响原变量
void foo(int& x) {
x = 100;
}
int main() {
int a = 10;
foo(a);
std::cout << a; // 输出 100,被修改了
}
3. 指针传递(Pass by Pointer)
- 函数接收变量的地址,通过指针访问和修改
void foo(int* x) {
*x = 100;
}
int main() {
int a = 10;
foo(&a);
std::cout << a; // 输出 100
}
4. 常引用传递(Pass by const Reference)
- 适用于避免拷贝开销,但又不允许函数修改实参
- 常用于传递大型对象,如
std::string
,std::vector
void print(const std::string& s) {
std::cout << s;
}
5. 右值引用(Pass by rvalue reference)C++11+
- 支持移动语义,避免不必要的深拷贝
void foo(std::string&& s) {
std::cout << s;
}
foo("hello"s); // 移动传参
小结对照表:
方式 | 是否复制 | 是否可修改原变量 | 适用场景 |
---|---|---|---|
值传递 | 是 | 否 | 小数据类型(int, float) |
引用传递 | 否 | 是 | 需要修改原变量 |
指针传递 | 否 | 是 | 类似引用,但更灵活 |
const 引用传递 | 否 | 否 | 传大型对象且不修改 |
右值引用传递 | 否 | 是 | 支持移动,避免拷贝 |
结论:
C++ 中函数参数默认是值传递,但你可以通过
&
(引用)、*
(指针)或&&
(右值引用)来实现其他传参方式。
三、构造函数 析构函数
构造函数Constructor
构造函数是当对象被创建时自动调用的特殊函数,用于初始化对象的成员变量。
- 名字与类名相同
- 没有返回值
- 可以有多个
类型 | 用途 |
---|---|
默认构造函数 | 不带参数或所有参数有默认值 |
带参构造函数 | 用户提供初始化参数 |
拷贝构造函数 | 用已有对象创建新对象(传值方式) |
移动构造函数(C++11) | 用于资源“窃取”(效率更高) |
委托构造函数(C++11) | 在一个构造函数中调用另一个构造函数 |
拷贝构造函数 Copy Constructor
如果你没有显式定义 operator=()
,C++ 会默认生成一个浅拷贝的赋值运算符,对每个成员做成员赋值。但如果你类中包含裸指针等资源,默认赋值将产生浅拷贝问题(资源共享,析构冲突),此时应自定义赋值运算符。
拷贝构造作用:
- 通过一个已有对象初始化另一个对象
- 将对象按值传递给函数
- 函数按值返回对象
ClassName(const ClassName& other);
参数是
const &
避免递归调用自身
禁止拷贝构造:
// 在 C++11/14/17 中,推荐使用 `= default` 和 `= delete` 明确指定:
class MyClass {
public:
MyClass() = default;
MyClass(const MyClass&) = delete;
~MyClass() = default;
};
析构函数 Destructor
析构函数是在对象销毁时自动调用的特殊函数,用于释放资源、关闭文件、清理指针等。
- 名字为
~类名
- 没有参数,没有返回值
- 每个类最多只能有一个析构函数
- 可以是虚的(用于多态删除)
示例
将定义和实现全部写在头文件中的写法:
#include <iostream>
#include <string>
class Person {
public:
std::string name;
int* age;
// 1. 默认构造函数(委托给带参构造)
Person() : Person("unknown", 0) {
std::cout << "Default constructor called (delegated)\n";
}
// 2. 带参构造函数
Person(const std::string& name_, int age_) {
name = name_;
age = new int(age_);
std::cout << "Parameterized constructor called\n";
}
// 3. 拷贝构造函数(深拷贝)
Person(const Person& other) {
name = other.name;
age = new int(*other.age);
std::cout << "Copy constructor called\n";
}
// 4. 移动构造函数(C++11)
Person(Person&& other) noexcept {
name = std::move(other.name); // string 自带 move
age = other.age; // 窃取指针
other.age = nullptr; // 避免析构 double free
std::cout << "Move constructor called\n";
}
// 5. 析构函数
~Person() {
std::cout << "Destructor called for " << name << "\n";
delete age;
}
};
现代c++推荐头文件和源文件分离,分离的写法:
// Person.h
#ifndef PERSON_H
#define PERSON_H
#include <string>
class Person {
public:
std::string name;
int* age;
// 1.默认构造函数
Person();
// 2.带参构造函数
Person(const std::string& name_, int age_);
// 3.拷贝构造函数(深拷贝)
Person(const Person& other);
// 4.移动构造函数(C++11)
Person(Person&& other) noexcept;
// 5.析构函数
virtual ~Person();
// 拷贝赋值运算符(可选)
Person& operator=(const Person& other);
// 移动赋值运算符(可选)
Person& operator=(Person&& other) noexcept;
// const表示该函数不会修改类成员变量,如果在常函数里修改成员变量会报错
virtual void introduce() const;
};
#endif
// Person.cpp
#include "Person.h"
#include <iostream>
// 1.默认构造函数
Person::Person() : Person("unknown", 0) {
std::cout << "Default constructor called\n";
}
// 2.带参构造函数
Person::Person(const std::string& name_, int age_) {
name = name_;
age = new int(age_);
std::cout << "Parameterized constructor called\n";
}
// 3.拷贝构造函数(深拷贝)
Person::Person(const Person& other) {
name = other.name;
age = new int(*other.age);
std::cout << "Copy constructor called\n";
}
// 4.移动构造函数(C++11)
Person::Person(Person&& other) noexcept {
name = std::move(other.name);
age = other.age;
other.age = nullptr;
std::cout << "Move constructor called\n";
}
// 5.析构函数
Person::~Person() {
std::cout << "Person destructor called for " << name << "\n";
delete age;
}
// 拷贝赋值运算符(可选)
Person& Person::operator=(const Person& other) {
if (this != &other) {
name = other.name;
delete age;
age = new int(*other.age);
}
return *this;
}
// 移动赋值运算符(可选)
Person& Person::operator=(Person&& other) noexcept {
if (this != &other) {
name = std::move(other.name);
delete age;
age = other.age;
other.age = nullptr;
}
return *this;
}
void Person::introduce() const {
std::cout << "Hi, I am " << name << ", age " << *age << ".\n";
}
默认构造/拷贝/析构行为总结
函数类型 | 是否自动生成 | 什么时候需要自定义? |
---|---|---|
构造函数 | (如果没写) | 成员需要特殊初始化逻辑时 |
拷贝构造函数 | (如果没写) | 含指针资源、句柄或禁止拷贝 |
析构函数 | (如果没写) | 成员包含动态资源(如 new)时需释放 |
移动构造函数 | (C++11+) | 优化效率或防止拷贝 |
- 如果你不写,编译器会自动生成一个“浅拷贝”版本。
- 如果类中有裸指针,一定要自己写拷贝构造,否则可能引发双重释放错误。
深拷贝和浅拷贝
C++ 中的 深拷贝(deep copy) 与 浅拷贝(shallow copy) 是对象复制时的两种方式,区别在于是否真正复制了堆上资源。理解这两者对掌握类的构造函数、拷贝构造函数和析构函数至关重要。
一、定义和区别
特性 | 浅拷贝(Shallow Copy) | 深拷贝(Deep Copy) |
---|---|---|
拷贝内容 | 只复制指针的地址 | 分配新内存并复制数据内容 |
资源共享 | 原对象和副本指向同一内存 | 原对象和副本各自拥有独立内存 |
安全性 | 改变一个对象会影响另一个;易发生悬垂指针、双重释放 | 对象互不影响 |
析构风险 | 多次析构同一块内存(如果未正确管理) | 每个对象析构各自拥有的内存 |
二、示例演示
#include <iostream>
#include <cstring>
class Person {
public:
char* name;
// 构造函数
Person(const char* n) {
name = new char[strlen(n) + 1];
strcpy(name, n);
}
// 浅拷贝构造函数(默认)
// Person(const Person& other) = default;
// 深拷贝构造函数
Person(const Person& other) {
name = new char[strlen(other.name) + 1];
strcpy(name, other.name);
}
// 析构函数
~Person() {
delete[] name;
}
void print() {
std::cout << "Name: " << name << std::endl;
}
};
如果不写深拷贝构造函数,编译器默认使用浅拷贝,即只是复制了指针 name
的地址,两个对象共用同一块堆内存。这样一来,修改 p2.name
会影响 p1.name
,两个对象析构时还会重复释放同一块内存,导致崩溃。
三、默认拷贝行为说明
操作类型 | 默认行为 | 是否安全 |
---|---|---|
拷贝构造函数 | 浅拷贝 | |
赋值运算符 = |
浅赋值 | |
析构函数 | 默认释放 | (若使用裸指针) |
const在类中的作用
const
可以修饰类的成员函数、函数参数与返回值和对象,但它不能直接修饰整个类本身。
const
修饰函数(常成员函数)
class MyClass {
public:
int getValue() const; // 表示该函数不会修改类成员变量
private:
int value = 42;
};
int MyClass::getValue() const {
// this->value = 10; 编译错误:不能修改成员变量
return value;
}
const MyClass obj; // **只能调用 const 成员函数**
MyClass obj2; // **既可以调用 const 成员函数,也可以调用非常成员函数**
const
修饰函数参数和返回值
修饰参数
void printName(const std::string& name); // 避免拷贝 + 保证不修改参数
修饰返回值
const std::string& getName() const; // 返回值不能被修改(防止误用)
注意:
const
修饰返回值时,通常用于返回引用或指针,不太常用于值返回。
不能直接修饰类
const class MyClass {}; // 不常见,基本无意义
四、继承
基类函数用 virtual
修饰,子类可以 override
它
继承方式 修饰符可见性
c++ Java中的继承方式是完全一样的,继承方式
继承方式 | 基类的 public 成员在子类中变成 |
基类的 protected 成员在子类中变成 |
基类的 private 成员 |
---|---|---|---|
public 继承 |
public |
protected |
不可访问 |
protected 继承 |
protected |
protected |
不可访问 |
private 继承 |
private |
private |
不可访问 |
可见性
修饰符 | 类内访问 | 派生类访问 | 类外访问 |
---|---|---|---|
public |
可访问 | 可访问 | 可访问 |
protected |
可访问 | 可访问 | 不可访问 |
private |
可访问 | 不可访问 | 不可访问 |
示例
//student.h
#ifndef STUDENT_H
#define STUDENT_H
#include "Person.h"
class Student : public Person {
public:
std::string school;
Student();
Student(const std::string& name_, int age_, const std::string& school_);
~Student() override;
void introduce() const override;
};
#endif
//student.cpp
#include "Student.h"
#include <iostream>
Student::Student() : Person("unknown_student", 18), school("Unknown School") {
std::cout << "Student default constructor\n";
}
Student::Student(const std::string& name_, int age_, const std::string& school_)
: Person(name_, age_), school(school_) {
std::cout << "Student parameterized constructor\n";
}
Student::~Student() {
std::cout << "Student destructor called for " << name << "\n";
}
void Student::introduce() const {
std::cout << "Hi, I am student " << name << ", age " << *age
<< ", studying at " << school << ".\n";
}
构造函数和析构函数的顺序
- 构造顺序:先构造基类 → 再构造派生类
- 析构顺序:先析构派生类 → 再析构基类
class Base {
public:
Base() { std::cout << "Base()\n"; }
~Base() { std::cout << "~Base()\n"; }
};
class Derived : public Base {
public:
Derived() { std::cout << "Derived()\n"; }
~Derived() { std::cout << "~Derived()\n"; }
};
输出顺序:
Base()
Derived()
~Derived()
~Base()
C++特有:多继承与虚继承 菱形继承问题
多继承
class A { public: int x; };
class B { public: int x; };
class C : public A, public B {}; // 多继承,C 有两个 x,需区分 A::x 和 B::x
“菱形继承问题(Diamond Problem)”是 C++ 多继承中特有的一种继承结构冲突问题,会导致:
- 基类子对象重复
- 数据二义性 / 歧义访问
- 构造和析构混乱
- 资源浪费
一、什么是菱形继承结构?
如下图所示,B
和 C
都继承自 A
,而 D
同时继承自 B
和 C
:
A
/ \
B C
\ /
D
class A {
public:
int value;
};
class B : public A {};
class C : public A {};
class D : public B, public C {};
二、菱形继承引发的问题
1. 产生 多个 A 子对象
在 D
中包含了 两个 A 对象:
- 一个来自
B
(B→A) - 一个来自
C
(C→A)
2. 访问 value
发生歧义
D d;
d.value = 10; // 错误:编译器不知道是 B::A::value 还是 C::A::value
必须手动指定:
d.B::value = 10;
d.C::value = 20;
三、解决方法:虚继承(virtual
)
用 virtual
修饰继承关系,让 B 和 C 共享同一个 A 子对象。
class A {
public:
int value;
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
虚继承效果:
D
中只有 一个 A 对象,由编译器自动协调- 访问成员不再歧义:
D d;
d.value = 10; // 正常访问,无歧义
五、友元
在 C++ 中,友元(friend)机制允许非成员函数或其他类访问某个类的私有(private
)和受保护(protected
)成员。友元关系是 单向、不传递 的,常用于操作符重载、调试工具或两个类之间的紧密协作等场景。
一、友元的三种形式
1. 友元函数(Friend Function)
class Box {
private:
int width;
public:
Box(int w) : width(w) {}
// 声明友元函数
friend void printWidth(const Box& b);
};
// 非成员函数,可以访问 Box 的私有成员
void printWidth(const Box& b) {
std::cout << "Width: " << b.width << std::endl;
}
特点:
- 非类成员函数,但拥有类的访问权限
- 常用于重载
operator<<
等操作符
2. 友元类(Friend Class)
class Engine;
class Car {
private:
int speed;
public:
Car(int s) : speed(s) {}
friend class Engine; // Engine 可以访问 Car 的私有成员
};
class Engine {
public:
void showSpeed(const Car& c) {
std::cout << "Speed: " << c.speed << std::endl;
}
};
特点:
- 一个类可以将另一个类声明为友元
- 该友元类的所有成员函数都能访问被友元类的私有成员
- 单向:Engine 是 Car 的朋友,但 Car 不可访问 Engine 的私有成员
3. 成员函数作为友元
class B;
class A {
private:
int a_val;
public:
A(int v) : a_val(v) {}
friend void B::printA(const A& a); // 只让 B 的某个成员函数成为友元
};
class B {
public:
void printA(const A& a) {
std::cout << a.a_val << std::endl;
}
};
注意:这种方式必须 先声明 B 类,否则编译器不知道 B::printA
是什么。
二、友元的特性总结
特性 | 说明 |
---|---|
单向访问 | 被声明为友元的类/函数可以访问声明类的私有成员,反之不行 |
非成员也可声明为友元 | 普通函数、类、类的成员函数都可以作为友元 |
不破坏封装性 | 尽管能访问私有成员,但访问范围被显式限定 |
编译时绑定 | 友元关系在编译时建立,无法在运行时动态设置 |
不继承、不传递 | 子类不会继承友元权限,友元类的友元也无访问权 |
三、示例:重载 <<
运算符
class Person {
private:
std::string name;
int age;
public:
Person(std::string n, int a) : name(n), age(a) {}
friend std::ostream& operator<<(std::ostream& os, const Person& p);
};
std::ostream& operator<<(std::ostream& os, const Person& p) {
os << "Name: " << p.name << ", Age: " << p.age;
return os;
}
c++ 函数 类的更多相关文章
- hdwiki model目录下的函数类
model目录下的函数类 actions.class.php(站内地图相关) getHTML:获得页面菜单和相关信息 getMap:生成站内地图 adv.class.php 对wiki_adve ...
- MyEclipse上有main函数类运行报错:Editor does not contain a main type
MyEclipse下有main函数类运行报错:Editor does not contain a main type 出现这种问题的原因是,该java文件所在的包没有被MyEclipse认定为源码包. ...
- bitMap算法实现以及ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串
ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串 说明 1.所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来 ...
- SQL函数类的操作,增加,查询
数据库连接: 表的创建: 创建连接对象,命令对象类: 添加函数: 查询函数类: List<>集合,里面专门放对象 函数主体: 查询: foreach只能修改,不能添加删除
- 爬虫写法进阶:普通函数--->函数类--->Scrapy框架
本文转载自以下网站: 从 Class 类到 Scrapy https://www.makcyun.top/web_scraping_withpython12.html 普通函数爬虫: https:// ...
- MyEclipse上有main函数类运行报错:Editor does not contain a
MyEclipse下有main函数类运行报错:Editor does not contain a main type?出现这种问题的原因是,该java文件 MyEclipse下有main函数类运行 ...
- React函数类组件及其Hooks学习
目录 函数类组件 函数式组件和类式组件的区别: 为什么要使用函数式组件? Hooks概念及常用的Hooks 1. useState: State的Hook 语法 useState()说明: setXx ...
- 常用PHP函数类目录
说明:用来记录我在开发过程中,经常用到的一些常用函数或者常用类. 常用函数 PHP常用函数 (1) 常用类 PHP表单数据校验类
- 泛函编程(4)-深入Scala函数类
既然是泛函编程,多了解一下函数自然是免不了的了: 方法(Method)不等于函数(Function) 方法不是函数但可以转化成函数:可以手工转换或者由编译器(compiler)在适当的情况下自动转换. ...
- PHP输出当前进程所有变量 / 常量 / 模块 / 函数 / 类
<?php /* 不知道怎么打印某个函数的参数和相关分类类型的所有函数 以下函数如果没有参数,返回的都是一个数组get_defined_functions() 获取所有已经定义的函数get_de ...
随机推荐
- 实现领域驱动设计 - 使用ABP框架 - 系列文章汇总
系列文章汇总 前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 Implementing Domain Driven Design 实现领域驱动设计 - 使用ABP框架 - ...
- windows 本地部署DeepSeek
一:前言: 那么为什么要本地部署,主要就是企业或者个人为了数据安全和防止受限网络等其 数据安全:数据不用上传到外面,在本地处理,不用担心数据泄露,像金融.医疗这些对数据安全要求高的行业特别需要. 功能 ...
- 面试题-JVM性能调优
前言 JVM性能调优是一个很大的话题,很多中小企业的业务规模受限,没有迫切的性能调优需求,但是如果不知道JVM相关的理论知识,写出来的代码或者配置的JVM参数不合理时,就会出现很严重的性能问题,到时候 ...
- 深入掌握FastAPI与OpenAPI规范的高级适配技巧
title: 深入掌握FastAPI与OpenAPI规范的高级适配技巧 date: 2025/03/30 01:16:11 updated: 2025/03/30 01:16:11 author: c ...
- IP地址查询服务
IP地址查询站点 https://ip.cn/ http://ip.qq.com/ http://ip138.com/ https://www.apnic.net/ ... IP计算 ip地址在线计算 ...
- zk源码—1.数据节点与Watcher机制及权限
大纲 1.ZooKeeper的数据模型.节点类型与应用 (1)数据模型之树形结构 (2)节点类型与特性(持久 + 临时 + 顺序 ) (3)节点的状态结构(各种zxid + 各种version) (4 ...
- 面试官:如果某个业务量突然提升100倍QPS你会怎么做?
"假设你负责的系统,某个业务线的QPS突然暴增100倍,你会怎么应对?" --这是上周朋友去面试,被问到一道题,他答了"加机器扩容",结果面试官眉头一皱:&qu ...
- Java程序员的Go入门笔记
系列文章目录和关于我 0.背景 3年java开发背景(因此这篇文章的特点是:比较适合java程序员doge),业余时间有了解过一些go,如今主要技术栈是go,此篇主要结合go语言圣经和团队内go项目, ...
- 机器人操作系统ROS2之简介
什么是ROS2? ROS(机器人操作系统)是用于机器人应用的开源软件开发工具包.ROS 为各行业的开发者提供了一个标准的软件平台,帮助他们从研究和原型设计一直推进到部署和生产,从驱动程序到最先进的算法 ...
- MySQL 的查询优化器如何选择执行计划?
MySQL 的查询优化器负责决定如何执行 SQL 查询,它会根据多个因素选择最优的执行计划.查询优化器的目标是选择一个成本最低.性能最优的执行计划,以便高效地处理查询.执行计划的选择是基于 MySQL ...