C++入门语法总结和STL回顾

目录

    • iostream和命名空间
      • 输入输出流
      • 循环输入输出
    • vector容器
    • string字符串
    • cpp链表操作
    • hashTable哈希表
      • set集合
      • map映射
      • 范围for循环
    • stack栈
    • queue队列
    • list列表
    • 类和面向对象


iostream和命名空间

输入输出流

内置库iostream提供了输入和输出功能,允许开发者从键盘读取输入并在屏幕上输出结果:

#include <iostream>

iostream库包含了两个基础类型,分别是istream(输入流) 和 ostream(输出流)
在 iostream 库 中,我们有两个对象可以使用,分别是 cin 和cout:

  • cin是一个标准输入流对象,用于从键盘读取输入
  • cout是一个标准输出流对象,用于向屏幕输出结果
std::cin >> a >> b;
std::cout << a + b << std::endl;

std是命名空间,::符号是作用域操作符
当使用C++标准库的功能时,需要使用命名空间限定符来指明你要使用的内容位于哪个命名空间中。通常,会使用std::的前缀,表示正在使用C++标准库中的内容
也就是说,为了避免我们使用的变量和标准库定义的变量名称相同而引起冲突,以及避免不同标准库之间的变量名冲突,标准库定义的所有名字都在命名空间std中,如果我们要使用cin的话,就要先找到命名空间,然后再使用cin,即:std::cin

每次使用命名空间里的对象都要加上std::,就显得十分繁琐,可以在开头统一申明使用命名空间std:

using namespace std;
int main(void) {int a, b;cin >> a >> b;cout << a + b;}

endl表示结束当前行
我们在输出结果的时候,每一个结果都要单独占一行,也就是说 每个输出结果后面要有一个回车

循环输入输出

持续输入 a 和 b,直到不输入时才会结束:

//  控制多组数据的输入和输出
while (cin >> a >> b) {}

指定循环输入次数:

cin >> n;
while (n--) {}

循环终止条件判断:

// 1.
while (cin >> n && n) {}
//  与下方代码等效
while (cin >> n) {if (!n) break;//  ...
}// 2.
while (n--) {cin >> m;
}
//  与下方代码等效
while (n-- && cin >> m) {}

vector容器

vector,作为C++标准库中的一个容器类,表示对象的集合,它可以动态地存储一组元素,所以你可以根据需要轻松地调整 vector 的大小

包含头文件:

#include <vector>

容器创建方式:

vector<int> myVector; // 创建一个空vector, 元素是int类型的
vector<int> myVector = {1, 2, 3, 4, 5}; // 创建一个包含整数元素的容器并初始化元素
vector<int> myVector(10); // 创建一个包含10个元素的容器,元素为int类型(值被系统默认初始化为0)
vector<int> myVector(10, -1); // 创建一个包含10个重复元素的容器,每个元素的值都是-1

与数组类似,可用下标操作符[]访问 vector 中的元素:

int value = myVector[0]; // 获取第一个元素的值,即 1

内置的一些方法:

int size = myVector.size(); // 获取vector的大小
myVector.push_back(6); // 往容器的最末端添加数字6
myVector.pop_back(); // 删除vector末尾的元素
myVector.clear(); // 清空vector中的所有元素
myVector.empty(); // 判断vector是否不含有任何元素,如果长度为0,则返回真,否则,返回假

vector 容器的遍历输入:

vector<int> nums;
while (n-- && cin >> num) {nums.push_back(num);
}//与下方代码等效
vector<int> nums(n, 0);
for (int i = 0; i < n; ++i) {cin >> nums[i];
}

string字符串

引入头文件:

#include <string>

声明和初始化:

string s1; // 默认初始化,s1是一个空的字符串
string s2 = "hello"; // 初始化一个值为hello的字符串
string s3(5, 'a') // 连续5个字符a组成的串,即'aaaaa'

字符串操作:

string s1 = "hello";
string s2 = "world";
string s3 = s1 + " " + s2; // 对字符串进行连接,拼接之后的字符串是"hello world", 中间加了空格int length = s1.size(); // 字符串的长度即字符串中字符的个数,"hello"的长度为5
char c1 = s1[1]; // 下标从0开始,表示字符串的第一个字符
if (s1.empty()) {// 如果字符串为空则返回true, 否则返回false
}

输入输出string:

cin >> s;
cout << s;

因为字符串读取遇到空格就会停止,表示这是一个单词,但有的时候我们想读取完整的一行,这就要求我们的读取不会在空格处停止,这种情况下可以使用到getline(),它会一直读取字符,直到遇到换行符(Enter键)文件结束符(如果从文件读取)才结束:

string line;
// 获取用户输入的一行文本,并将其存储到line变量中
getline(cin, line);
// 输出读取的一行文本
cout << line << endl;// 比如有多组测试用例,每组测试数据占一行
string s;
while (getline(cin, s)) {}

cpp链表操作

空指针值通常表示为:

int* ptr = nullptr;

使用构造函数(名称与结构体名称相同,无返回类型)初始化结点:

struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}
};

尾插结点:

void insertNodeAtTail(ListNode* dummyNode, int val) {ListNode* move = dummyNode;while (move->next) {move = move->next;}ListNode* newNode = new ListNode(val);move->next = newNode;
}

指定位置插入结点:

inline bool insertNodeAtIndex(ListNode* dummyNode, int index, int val) {if (index <= 0) return false;ListNode* move = dummyNode;while (--index) {move = move->next;if (!move) return false;}ListNode* newNode = new ListNode(val);newNode->next = move->next;move->next = newNode;return true;
}

指定位置删除结点:

    if (index <= 0) return false;ListNode* move = dummyNode;while (--index) {move = move->next;if (!move) return false;}if (!move->next) return false;ListNode* tmp = move->next;move->next = move->next->next;delete tmp;return true;
}

打印链表:

inline void printList(ListNode* dummyNode) {ListNode* move = dummyNode;while (move->next) {move = move->next;cout << move->val;if (move->next) {cout << ' ';} else {cout << endl;}}}

打印指定位置结点:

bool printNode(ListNode* dummyNode, int index) {if (index <= 0) return false;ListNode* move = dummyNode;while (index--) {move = move->next;if (!move) return false;}cout << move->val << endl;return true;
}

hashTable哈希表

哈希表是根据关键码的值而直接进行访问的数据结构

哈希函数
通过hashCode把键值转化为数值,一般hashCode是通过特定编码方式,可以将其他数据格式转化为不同的数值

哈希碰撞
指不同的输入数据通过相同的哈希函数后生成了相同的哈希值

一般哈希碰撞有两种解决方法

拉链法:
发生冲突的元素会被存储在链表里,要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间

线性探测法:
一定要保证数据规模大于哈希表大小,放入元素位置若有冲突,会将该元素放入下一个空位位置

set集合

集合底层实现是否有序数值是否可以重复能否修改数值查询效率增删效率
set红黑树有序O(log n)O(log n)
multiset红黑树有序O(log n)O(log n)
unordered_set哈希表无序O(1)O(1)

红黑树是一种平衡二叉搜索树,所以底层实现是红黑树的set的key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加

当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的,如果需要集合是有序的,那么就用set,如果要求不仅有序还要有重复数据的话,那么就用multiset

引入头文件:

#include <set>
#include <unordered_set>

创建一个集合:

// 创建一个存储整数的无序集合
unordered_set<int> myUnorderedSet;
// 创建一个存储整数的set
set<int> mySet;
// 创建一个存储整数的 multiset
multiset<int> myMultiSet; 

插入、删除元素:

mySet.insert(7);
mySet.insert(77);
mySet.insert(777);
// 删除
mySet.erase(7);

find()方法用于查找特定元素是否存在于集合中,如果find()方法找到了要查找的元素,它会返回指向该元素的迭代器,如果未找到要查找的元素,它会返回一个 指向集合的end() 的迭代器,表示未找到:

//  表示元素i在集合中
if (mySet.find(i) != mySet.end()) {
}

map映射

集合底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
set红黑树有序O(log n)O(log n)
multiset红黑树有序O(log n)O(log n)
unordered_set哈希表无序O(1)O(1)

引入头文件:

#include <map>
#include <unordered_map>

声明一个map映射需指定键和值的类型:

// 整数类型映射到整数类型的无序映射
unordered_map<int, int> myOrderedMap;
// 将字符串映射到整数的映射
map<string, int> myMap;

插入键值对:

myOrderedMap[0] = 10;
myOrderedMap[10] = 0;myMap["Math"] = 120;
myMap["English"] = 138;// 如果键不存在,[]会创建创建一个新的键值对,将其插入到map中
// 并将值初始化为默认值(对于整数来说,默认值是0)myMap.insert("Math", 120);
myMap.emplace("English", 138);
myMap.emplace("Chinese", 99);

set类似,可以使用find函数来检查某个键是否存在于map中,它会返回一个迭代器。如果键存在,迭代器指向该键值对,否则指向 map的末尾 :

// 表示键存在
if (myMap.find("English") != myMap.end()) {
}

for循环遍历map中所有键值对:

for(const pair<int, int>& kv : myMap) {}

C++中的pair类型会将两个不同的值组合成一个单元, 常用于存储键值对
pair对象,两个值的类型都是int, 在使用时通过first 和 second 成员来访问 pair 中的第一个和第二个元素, 它的 first 成员存储键,而 second 成员存储值:

    for (const pair<string, int>& kv : myMap) {cout << kv.first << ' ' << kv.second << endl;}

const:这个关键字用来修饰常量,一旦变量被初始化,就不能再修改其值,表示你只能读取容器中的元素,而不能修改它们

&:这个符号表示kv是一个引用(reference),而不是值的拷贝, 如果不使用引用的话,那在每次循环迭代中都会重新创建一个新的pair对象来复制键值对,而这会导致不必要的内存分配和拷贝操作

以上数据结构都是哈希法的使用方式,即依靠键(key)来访问值(value)

范围for循环

C++11引入了范围for循环,用于更方便地遍历容器中的元素。这种循环提供了一种简单的方式来迭代容器中的每个元素,而不需要显式地使用迭代器或索引

for (类型 变量名 : 容器) {// 在这里使用一个变量名,表示容器中的每个元素
}// eg:
vector<int> numbers = {1, 2, 3, 4, 5};
// 使用范围for循环遍历容器中的元素
for (int num : numbers) {cout << num << " ";
}

范围for循环不会修改容器中的元素,它只用于读取元素。如果需要修改容器中的元素,需要使用传统的for循环或其他迭代方式

此外,还可以使用auto关键字来让编译器自动推断元素的类型,这样代码会更通用:

for (auto num : numbers) {cout << num << " ";
}

stack栈

引入头文件:

#include <stack>

创建一个栈:

stack<int> stack;

栈的常用操作:

stack.push(7);
stack.push(77);
stack.push(777); // 往栈中添加元素,现在栈底元素是7,栈顶元素是777
stack.pop(); // 移除栈顶元素777,新的栈顶元素是77int topNumber = st.top(); // 获取栈顶元素77bool isEmpty = st.empty(); // 如果栈为空,返回true;否则返回falseint stackSize = st.size(); // 获取栈的长度(元素数量)

queue队列

队列在计算机领域中应用也十分广泛,比如在网络通信中,请求和响应通常以队列的形式进行排队,以确保数据按照正确的顺序进行传输,又比如说不同进程可以通过消息队列来传递数据和消息

引入头文件:

#include <queue>

创建一个字符串类型的队列:

queue<string> queue;

队列的常用操作:

queue.push("Jackson");
queue.push("Mickey");  // 从队尾依次入队了两个名称字符串
queue.pop(); // 移除队列头部的元素string name = queue.front(); // 获取队列头部的元素但是不会将其移除bool isEmpty = queue.empty(); //  如果队列为空,返回true;否则返回falseint queueSize = queue.size(); // 获取队列中元素的数量

list列表

list双向链表(doubly linked list) 实现而成,元素也存放在堆中,每个元素都是放在一块内存中,他的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存取变得非常没有效率,因此它没有提供[]操作符的重载。但是由于链表的特点,它可以很有效率的支持任意地方的插入和删除操作

引入头文件:

#include <list>

声明和初始化:

list<int> a; // 定义一个int类型的列表a
list<int> a(10); // 定义一个int类型的列表a,并设置初始大小为10
list<int> a(10, 1); // 定义一个int类型的列表a,并设置初始大小为10且初始值都为1
list<int> b(a); // 定义并用列表a初始化列表b
deque<int> b(a.begin(), ++a.end()); // 将列表a中的第1个元素作为列表b的初始值// 还可以直接使用数组来初始化
int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5); // 将数组n的前5个元素作为列表a的初值

列表的基本操作:

lst.size();  // 容器大小
lst.max_size();  // 容器最大容量
lst.resize(0);  // 更改容器大小为0
lst.empty();  // 容器判空lst.push_front(const T& x);  // 头部添加元素
lst.push_back(const T& x);  // 末尾添加元素
lst.insert(iterator it, const T& x);  // 任意位置插入一个元素
lst.insert(iterator it, int n, const T& x);  // 任意位置插入 n 个相同元素
lst.insert(iterator it, iterator first, iterator last);  // 插入另一个向量的 [first, last] 间的数据lst.pop_front();  // 头部删除元素
lst.pop_back();  // 末尾删除元素
lst.erase(iterator it);  // 任意位置删除一个元素
lst.erase(iterator first, iterator last);  // 删除 [first,last] 之间的元素:
lst.clear();  // 清空所有元素lst.front();  // 访问第一个元素
lst.back();  // 访问最后一个元素

类和面向对象

引用

引用就是一个对象的别名,其声明形式如下:

int x;
int& r = x;  //  声明 r 是 x 的引用

引用一旦被初始化,就不能改变引用关系,不能在作为其他对象的引用:

int x, y;
int &r = x;
//&r = y;  错误 r 不能再是别的对象的引用

声明一个引用类型变量时,必须同时初始化它,声明他是那个对象的别名,即绑定对象:

//  int &r;  错误
int x, &r = x;

指定类型的引用不能初始化到其他类型的对象上:

double f;
int& r = f;

取一个引用的地址和取一个对象的地址完全一样,都是用去地址运算:

int x, &r = x;
int* p1 = &x;
int* p2 = &r;

对象的引用就可以作为函数的参数传入:

void swap(int& a, int& b) {int tmp = a;a = b;b = tmp;
}//  指针作为函数形参
void swap(int* a, int* b) {int tmp = *a;*a = *b;*b = tmp;
}

函数名既代表函数,又代表函数的指针(地址):

int max(int a, int b);
int min(int a, int b);int (*p)(int a, int b);  //  定义函数指针变量
p = max;
c = p(a, b);  //  等价于 c = max(a, b);
//  p可以指向所有与它有相同的返回值类型、参数个数、参数类型的函数(max,min)

假设 p 是指向结构体对象的指针,通过 p 访问结构体成员有两种方式:

int age = (*p).age;  //  对象法
int age = p->age;  //  指针法

所有的成员必须在类的内部声明,一旦完成类定义完成后,就没有任何其他方式可以在增加成员了

在类的外部定义成员函数:

class Data {private:int data;public:void set(int d);int get(void) {return data;}
};// 成员函数的外部定义,使用作用域限定符::限定
void Data::set(int d) {data = d;  //  访问类的数据成员
}

内联成员函数:类的成员函数可以指定为inline,即内联函数
默认情况下,在类体中定义的成员函数若不包括循环等控制结构,函数体程序简单,符合内联函数体要求时,C++会自动将它们作为内联函数处理(隐式 inline)。
也可显式地将成员函数声明为 inline:

class Data {int getX(void) { return x; }  //  内联成员函数inline void setX(int _x);  //  显式指定内联成员函数void display(void);int x;// 内联成员函数
inline void Data::set(int d) {x = _x;
}
// 非内联成员函数
void Data::display(void) {// ..
}

对象成员的引用:

class Data {// ...public:int data;void fun(int a, int b);
}void caller(void) {//  使用对象名Data A;A.data = 100;A.fun(7, 77);//  使用对象指针Data A, *p1, *p2;  //  定义对象指针变量指向 Ap1 = &A;p1->data = 100;p1->fun(7, 77);p2 = new Data;  //  动态分配 Data 对象p2->data = 100;p2->fun(7, 77);delete p2;// 使用对象的引用变量Data A, &r = A;r.data = 100;r.fun(7, 77);
}

构造函数,作用是将对象初始化为一个特定的初始状态
构造函数可以是内联函数、重载函数、带默认参数值的函数,如未在程序中声明构造函数,则系统会自动生成一个默认构造函数,其参数列表为空

下面两个都是默认构造函数,如果在类中同时出现,将产生编译错误:

Data();
Data(int x, int y, int z);

析构函数,在对象的生存期结束前的时刻系统自动调用,完成一些被删除前的清理工作
如程序中未声明析构函数,编译器将自动产生一个隐含的析构函数:

class Point {private:int x, y;public:Point(int _x, int _y);~Point();  //  析构函数
}Point::Point(int _x, int _y) {x = _x;y = _y;
}Point::~Point() {//  析构函数的实现
}

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

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

相关文章

[渗透测试] 反序列化漏洞

反序列化漏洞 ​ 序列化&#xff1a;将对象的状态信息转换为可以传输或存储的形式的过程。简单的来说&#xff0c;就是将一个抽象的对象转换成可以传输的字符串 &#xff0c;以特定的形式在进行之间实现跨平台的传输。 序列化大多以字节流、字符串、json串的形式来传输。将对…

linux/windows wps node.js插件对PPT状态监听并且通知其他应用

需求背景 公司要求对Window系统&#xff0c;和国产操作系统&#xff08;UOS&#xff09;的wps 软件在 PPT开始播放 结束播放&#xff0c;和播放中翻页 上一页 下一页 等状态进行监听&#xff0c;并通知到我们桌面应用。 技术方案 开发WPS插件&#xff0c;使用node.JS 插件开…

系统架构设计师①:计算机组成与体系结构

系统架构设计师①&#xff1a;计算机组成与体系结构 计算机结构 计算机的组成结构可以概括为以下几个主要部分&#xff1a;中央处理器&#xff08;CPU&#xff09;、存储器&#xff08;包括主存和外存&#xff09;、输入设备、输出设备&#xff0c;以及控制器、运算器、总线和…

如何查看jvm资源占用情况

如何设置jar的内存 java -XX:MetaspaceSize256M -XX:MaxMetaspaceSize256M -XX:AlwaysPreTouch -XX:ReservedCodeCacheSize128m -XX:InitialCodeCacheSize128m -Xss512k -Xmx2g -Xms2g -XX:UseG1GC -XX:G1HeapRegionSize4M -jar your-application.jar以上配置为堆内存4G jar项…

使用puma部署ruby on rails的记录

之前写过一篇《记录一下我的Ruby On Rails的systemd服务脚本》的记录&#xff0c;现在补上一个比较政治正确的Ruby On Rails的生产环境部署记录。使用Puma部署项目。 创建文件 /usr/lib/systemd/system/puma.service [Unit] DescriptionPuma HTTP Server DocumentationRuby O…

C语言中的文件创建、写入与读取

在C语言编程中&#xff0c;文件操作是一项基本且重要的技能。它允许程序与外部数据进行交互&#xff0c;如保存用户输入、读取配置文件或处理日志文件等。下面&#xff0c;我们将详细介绍如何在C语言中创建文件、向文件写入数据以及从文件中读取数据。 点击这里➡️➡️➡️ 锁…

[AWS]MSK调用,报错Access denied

背景&#xff1a;首先MSK就是配置一个AWS的托管 kafka&#xff0c;创建完成之后就交给开发进行使用&#xff0c;开发通常是从代码中&#xff0c;编写AWS的access_key 和secret_key进行调用。 但是开发在进行调用的时候&#xff0c;一直报错连接失败&#xff0c;其实问题很简单&…

Electron 企业级开发通信与本地存储实用解决方案

背景 之前写了一篇Electron通信的方式&#xff0c;讲述了一下三者之间的通信机制&#xff0c;比较恶心&#xff0c;后来发现有个electron/remote&#xff0c; Electron 渲染进程直接调用主进程的API库electron/remote引用讲解-CSDN博客文章浏览阅读58次。remote是个老库&…

蓝队黑名单IP解封提取脚本

应用场景&#xff1a;公司给蓝队人员一个解封IP列表&#xff0c;假如某个IP满足属于某某C段&#xff0c;则对该IP进行解封。该脚本则是进行批量筛选出符合条件的白名单IP 实操如下&#xff1a;公司给了一个已经封禁了的黑名单IP列表如下&#xff08;black&#xff09; 公司要求…

高清视频,无损音频,LDR6023——打造极致视听与高效充电的双重享受!

Type-C PD&#xff08;Power Delivery&#xff09;芯片是一种支持USB Type-C接口规范的电源管理单元&#xff0c;其主要功能包括&#xff1a; 快速充电&#xff1a;Type-C PD芯片支持高功率传输&#xff0c;能够提供更快的充电速度&#xff0c;使电子设备在短时间内充满电&…

微信小程序:多图片显示及图片点击放大,多视频显示

微信小程序&#xff1a;多图片显示及图片点击放大&#xff0c;多视频显示 01 多图片显示及图片点击放大02 多视频03 全部代码 01 多图片显示及图片点击放大 <view><view class"title">图片&#xff1a;</view><block wx:if"{{photoUrlList…

源码搭建国内微短剧系统(APP+小程序)云存储配置流程

国内微短剧系统很多人不知道云存储和配置的操作流程&#xff0c;我整理了一份非常详细的操作文档流程&#xff0c;给大家介绍短剧系统云存储配置的详细操作流程。顺便推荐一下国内微短剧系统。 推荐下他们的开源地址&#xff1a;https://gitee.com/nymaite_com_2878868888/tjg…

CrowdStrike更新致850万Windows设备宕机,微软紧急救火!

7月18日&#xff0c;网络安全公司CrowdStrike发布了一次软件更新&#xff0c;导致全球大范围Windows系统宕机。 预估CrowdStrike的更新影响了将近850万台Windows设备&#xff0c;多行业服务因此停滞&#xff0c;全球打工人原地放假&#xff0c;坐等吃瓜&#xff0c;网络上爆梗…

适用于 Mac 或 MacBook 的最佳数据恢复软件

Apple 设计的电脑可靠且用户友好&#xff0c;但即使是最好的最新款 MacBook硬件也会出现故障。当您的存储出现问题时&#xff0c;数据恢复软件可以帮助您恢复丢失和损坏的文件。 数据丢失的另一个原因是有时会发生令人尴尬的错误。如果您不小心丢弃了所需的文件&#xff0c;然…

【RaspberryPi】树莓派Matlab/Simulink支持包安装与使用

官网支持与兼容性 Raspberry Pi Support from MATLAB - Hardware Support - MATLAB & Simulink Raspberry Pi Support from Simulink - Hardware Support - MATLAB & Simulink Matlab与树莓派兼容性 Simulink与树莓派兼容性 树莓派Matlab&Simulink RaspberryPi支…

本地部署 mistralai/Mistral-Nemo-Instruct-2407

本地部署 mistralai/Mistral-Nemo-Instruct-2407 1. 创建虚拟环境2. 安装 fschat3. 安装 transformers4. 安装 flash-attn5. 安装 pytorch6. 启动 controller7. 启动 mistralai/Mistral-Nemo-Instruct-24078. 启动 api9. 访问 mistralai/Mistral-Nemo-Instruct-2407 1. 创建虚拟…

240722视频识别红色物体

文章目录 1.实验目的2.实验思路3.实验代码4.实验结果展示1.实验目的 针对需求,拍摄视频并实时识别其中红色物体。 2.实验思路 针对HSV模型可以很好的区分色彩这一特性,所以我们可以很好的找到我们需要的ROI 3.实验代码 # @File: 13.2拍视频识别其中的红色物体.py # @Au…

Github 2024-07-22开源项目日报Top10

根据Github Trendings的统计,今日(2024-07-22统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目1Kotlin项目1Rust项目1Java项目1HTML项目1非开发语言项目1C++项目1C#项目1Lua项目1PowerShell项目1JavaScript项目1免费编程书籍和学…

【测开能力提升-fastapi框架】fastapi能力提升 - 中间件与CORS

1. 中间件 1.1 介绍&#xff08;ChatGPT抄的&#xff0c;大致可以理解&#xff09; 一种机制&#xff0c;用于在处理请求和响应之前对其进行拦截、处理或修改。中间件可以在应用程序的请求处理管道中插入自定义逻辑&#xff0c;以实现一些通用的功能&#xff0c;如身份验证、…

llama_index中使用Ollama是出现timed out 问题

现象&#xff1a; File "~/anaconda3/envs/leo_py38/lib/python3.8/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptionsraise mapped_exc(message) from exc httpx.ReadTimeout: timed out代码&#xff1a; from llama_index.core …