浅谈 C/C++ 的输入输出
更好的阅读体验\huge{\color{red}{更好的阅读体验}}更好的阅读体验
文章目录
- 0. 叠甲,过
- 1. 谈谈输入输出缓冲区
- 1.1 基本概念
- 输入输出流
- 标准输入输出流
- 文件输入输出流
- 1.2 输入输出缓冲区
- 什么是输入输出缓冲区?
- 为什么要设置输入输出缓冲区?
- C/C++ 的输入输出缓冲区有何不同?
- 别急别急别急
- 急急急急急急
- 2. 谈谈输入输出的方式
- 2.1 C/C++ 的输入和输出
- scanf() 和 printf()
- cin 和 cout
- getchar() 和 getline()
- stringstream
- 2.2 关闭 C++ 标准流同步
- 3. 最后的练习
- 3.1 泛凯撒加密
- 3.2 题解
0. 叠甲,过
本人水平有限,语言组织能力低下,不保证绝佳的阅读体验,也不保证内容完全准确,如有错误和建议,欢迎指出。才怪。
1. 谈谈输入输出缓冲区
1.1 基本概念
你先别急,我知道你很急,但是别急,所以你先别急。
在了解输入输出输出缓冲区时,需要明确以下几个基本概念:
- 输入输出流
- 标准输入输出流
- 文件输入输出流
输入输出流
- 输入输出流是一种数据传输的概念。
- 构成计算机的其中之一部件为
I/O设备,指的是用于从程序内部向外部设备(屏幕、打印机等)或从外部设备向程序内部传输数据的设备(鼠标、键盘等); - 计算机中通过
I/O设备进行与用户之间的数据交互,而为了适应不同的设备之间数据的传输,提出了输入输出流的概念。 - 即,输入输出流就是一种统一的数据输入输出协议,为不同的设备之间传递数据时提供一致的接口。
标准输入输出流
- 标准输入输出流是指程序与外部设备(例如键盘和显示器)之间的输入输出
- 在
C语言中:- 在
C标准库中,标准输入流输出流分别是stdin和stdout,另外还有标准错误流stderr。 - 使用
<stdio.h>头文件里的scanf()函数和printf()函数。
- 在
- 在
C++语言中:- 在
C++标准库中,没有stdin这样的标准输入流,而是使用std::cin和std::out来进行标准输入和标准输出。 - 使用
<iostream.h>头文件里的getline()函数或是>>和<<操作符。
- 在
- 综上,在
C++中,输入输出流的使用通常是通过iostream库实现的,而在C中则是通过stdio库实现的。
文件输入输出流
- 文件输入输出流则是将数据保存在磁盘上的文件中,通过打开和关闭文件,程序可以使用文件输入输出流进行数据的读取和写入。
- 在
C语言中:- 文件输入输出流使用
C标准库中的文件指针FILE*来实现。 - 操作函数有
fopen(),fclose(),fread(),fwrite()等。
- 文件输入输出流使用
- 在
C++语言中:- 文件输入输出流是基于
C标准库中的文件操作函数封装而成,即fstream类。 - 具体地,通过
std::ifstream和std::ofstream类实现,它们是std::istream和std::ostream类的派生类。
- 文件输入输出流是基于
相比标准输入输出流,文件输入输出流需要显式地指定要读写的文件,因此使用起来比较繁琐,但也更加灵活:文件输入输出流可以处理任何类型的文件,包括文本文件和二进制文件,而标准输入输出流只能处理字符流。此外,文件输入输出流可以通过随机访问文件的方式读写文件,而标准输入输出流只能顺序读写。
1.2 输入输出缓冲区
什么是输入输出缓冲区?
顾名思义,输入输出缓冲区就是输入输出缓冲的区域。
在 C/C++ 中,输入输出缓冲区是用来存储输入输出数据的临时存储区域:
- 输入缓冲区是在数据流输入之前存储输入数据的临时存储区域。
- 输出缓冲区是在数据流输出之前存储输出数据的临时存储区域。
说人话:输入输出缓冲区就是为了保存这些输入输出流而临时开辟出的一块内存。
为什么要设置输入输出缓冲区?
众嗦粥汁,因为需要,所以设置:
- 缓冲区是在内存中,而外设则是在硬件中。
- 相比于从硬件中读取和写入数据,从内存中读取和写入数据更加快速。
因此,当程序需要读取或写入大量数据时,使用缓冲区可以将这些数据先存储到内存中,然后再一次性地写入或读取,避免了频繁访问硬件的开销。此外,缓冲区还可以优化数据的排列和格式,以便更高效地读取和写入数据。
说人话:缓冲区的存在是为了提高输入输出效率,减少对外设的访问次数。
C/C++ 的输入输出缓冲区有何不同?
别急别急别急
首先别急,其次别急,所以我们先来了解下:**输入输出缓冲区的空间由什么来分配?开辟在哪里?何时开辟?**这个问题:
- 输入输出缓冲区的空间通常由操作系统来分配的;
- 一般情况下,是在程序运行时从内存中分配的,在程序运行空间中分配的,不是在操作系统的内核空间中分配;
- 而分配的时机和分配的空间大小会根据具体的实现而不同,一般地,当程序通过输入输出函数向缓冲区写入或者读取数据时,缓冲区就会被分配。
具体地:
-
分配缓冲区的时机:
- 对于标准输入输出流:缓冲区的空间通常是在程序启动时预先分配好的。
- 对于文件输入输出流:缓冲区的空间是在文件流和流缓冲区对象创建时动态分配的,这些对象通常是在程序开始时被初始化的。
- 缓冲区的大小通常是由实现细节所决定的,但是一般来说,缓冲区的大小应该足够容纳输入或输出数据的常规大小,同时又不能过大以致于浪费内存。
-
分配缓冲区的大小:
-
缓冲区的大小应该足够容纳输入或输出数据的常规大小,同时又不能过大以致于浪费内存。
-
由实现库来完成对缓冲区大小的分配,具体实现细节可能会因编译器或操作系统的不同而有所差异。
-
一般来说,实现库会通过调用操作系统提供的系统调用或动态内存分配函数来分配缓冲区的空间。
-
在内存空间紧张的情况下,缓冲区的大小可能会被限制,从而可能影响到程序的性能和可靠性。
-
急急急急急急
我知道你急了,但是你先别急,这部分其实不用太纠结。的。对吧:
- 在
C语言中,标准输入输出库<stdio.h>提供了输入输出缓冲区的实现。- 主要使用了三个函数:
setbuf(),setvbuf(),fflush()。 - 其中,
setbuf()和setvbuf()可以用来设置缓冲区,而fflush()用来清空缓冲区并把缓冲区中的数据输出到文件。 - 因此,
C中的输入输出函数,如scanf()和printf()等,是非类型安全的:- 它们依赖于格式化字符串来指示输入/输出数据的类型。
- 如果格式化字符串不正确,就会导致不可预测的结果,如缓冲区溢出和未定义的行为。
- 主要使用了三个函数:
- 在
C++中,<iostream>库提供了输入输出缓冲区的实现。- 提供了两种不同的缓冲区:
streambuf和filebuf。 streambuf是<iostream>库的基类,提供了对输入输出缓冲区的访问;而filebuf是<fstream>库的基类,提供了对文件输入输出缓冲区的访问。- 但是,
<iostream>库还提供了一些类似setbuf(),setvbuf(),flush()等函数,用来管理输入输出缓冲区。在关闭同步流之后,<iostream>库使用了一种不同于标准输入输出库的机制来提高效率,例如使用字符串流stringstream和缓冲流buffer stream等。 - 因此,
C++中的输入输出函数,如std::cin和std::cout等,是类型安全的:- 它们使用类型安全的
C++流语义,其中数据类型是静态确定的,而不是动态确定的。 - 这意味着数据类型在编译时就已经确定,而不是在运行时根据格式化字符串动态确定。
- 这种静态类型检查可以在编译时检测到类型不匹配的错误,从而使
C++的输入输出更加类型安全。
- 它们使用类型安全的
- 提供了两种不同的缓冲区:
这就是为什么,你仍然可以在 C++ 中使用 scanf() 和 printf(),但是仍建议在 C++ 中使用 <iostream> 库所提供的标准输入输出的原因,以及为什么我们常说 C++ 比 C 更适于面向对象。
总结:这部分真的不用太纠结。中肯的。正确的。理智的。一针见血的。真的。
2. 谈谈输入输出的方式
2.1 C/C++ 的输入和输出
你急了,你急了,你急了,因为你很迷,你不明白 stdin、scanf、cin、std::cin、getline、stringstream 还有 stdout、printf、cout、std::cout 这些都是什么寄吧玩意,对吧?再来明确一下:
stdin是C语言中的标准输入流。cin是C++中的标准输入流,而std::cin是C++标准库命名空间中的标准输入流,cin是使用命名空间std的缩写,即cin是std::cin的别名。scanf()是C语言中的输入函数,而cin和std::cin是C++中的输入流。scanf()的参数需要使用格式化字符串来指定输入数据的类型,而cin和std::cin可以自动识别输入数据的类型。getline()是C++中的输入函数,可以用于从输入流中读取一行文本数据,可以指定分隔符。getline()可以替代scanf()和cin用于读取字符串类型数据。stdout是C语言中的标准输出流。cout是C++中的标准输出流,而std::cout是C++标准库命名空间中的标准输出流。它们之间的区别同cin和std::cin。printf()是C语言中的输出函数,而cout和std::cout是C++中的输出流。printf()的参数需要使用格式化字符串来指定输出数据的类型,而cout和std::cout可以自动识别输出数据的类型。- 至于
stringstream这个逼东西,我们放到最后细嗦。
scanf() 和 printf()
因为我们对这两个东西再熟悉不过了,所以我们对这两个东西根本不陌生,这俩是 C 语言中的标准输入和标准输出函数。
对于 printf(),只需要注意下面几点:
- 用法:
scanf(format, argument_list); - 用于向控制台输出数据,可以输出多种类型的数据,如整数、浮点数、字符、字符串等。
- 在输出字符串时,需要注意字符串中是否包含特殊字符,如换行符、制表符等,需要使用相应的转义字符来表示。
- 可以使用格式化输出来控制输出的格式,如输出精度、对齐方式等。
而对于 scanf(),除了基本注意点:
- 用法:
scanf(format, argument_list); - 用于从控制台输入数据,可以读取多种类型的数据,如整数、浮点数、字符、字符串等。
scanf()输入数据时要求数据格式与format字符串中指定的格式匹配,否则会产生错误。
还需要注意:scanf() 函数的缓冲区不会自动清空,因此需要使用fflush(stdin)语句清空缓冲区,以防止输入的数据被下一个输入函数接收,如果仅仅为了处理掉换行符 \n,可以使用 getchar() 读取,将换行符“吃掉”。
举个栗子:
观察下列代码:
#include <stdio.h>int main(){int n; //声明 int 类型变量 nscanf("%d", &n); //读入 int 类型变量 nprintf("%d\n", n); //输出 int 类型变量 n 并且换行char c = getchar(); //读入一个字符,并存储在 char 类型变量 c 中printf("%c", c); //输出 char 类型变量 cprintf("14\n"); //输出 14 并且换行return 0;
}
假设运行并且在控制台输入如下内容:
114
5
理论上,我期望得到输出:
114
514
但实际上,控制台哼哼哼啊啊啊输出了如下内容:
11414
甚至控制台根本就没有接收你后续输入的 5 这个字符。
在该例子中,scanf("%d", &n)会读取输入流中的数字 114,并将其存储在变量 n 中。但是,由于输入缓冲区中还有一个换行符 \n,getchar()函数会读取这个换行符,并存储在变量 c 中,导致产生了这样的结果。在缓冲区中的数据没有被自动清空,这就是为什么控制台根本没有鸟你后续输入的东西,并输出了不符合预期的内容。
那么继续观察如下代码:
#include <stdio.h>int main(){int n; //声明 int 类型变量 nscanf("%d", &n); //读入 int 类型变量 nprintf("%d\n", n); //输出 int 类型变量 n 并且换行getchar(); //用 getchar() 吃掉缓冲区中的 '\n'char c = getchar(); //读入一个字符,并存储在 char 类型变量 c 中printf("%c", c); //输出 char 类型变量 cprintf("14\n"); //输出 14 并且换行return 0;
}
重新编译运行并在控制台输入如下内容:
114
5
可以发现控制台哼哼哼啊啊啊输出了:
114
514
在该例子中,为了避免上述缓冲区没有清空的情况,我们在读取完数据后手动清空输入缓冲区,利用 getchar() 读取了缓冲区里的换行符 \n,使得后续的字符 5 被成功读入,最终输出了符合预期的内容。
cin 和 cout
cin 和 cout 是 C++ 的输入输出流,可以使用它们来实现控制台的输入输出操作。一般地,使用 cin 和 cout 时可以通过引入 using namespace std; 简化代码,但也可以不引入命名空间,使用完整限定名 std::cin 和 std::cout。
由于 cin 和 cout 的输入输出会自动匹配对应数据类型,所以针对这两者的格式化输入输出并非此处讨论的重点,而在此处,我们需要提及其关于**同步流(synchronized stream)**的概念:
- 同步流意味着在程序流中输出数据时,程序必须等到数据完全输出到设备上,然后才能继续执行后面的代码。
- 同样,当程序尝试从输入设备读取数据时,程序会等待用户输入完整的数据,然后才能继续执行后面的代码。
虽然同步流可以确保输入输出的正确性,但是在一些场景下会影响程序的效率,特别是在大量数据输入输出的情况下。
这就是为什么,即使 C++ 宁愿舍弃 scanf() 和 printf() 的高性能,也要得到输入输出流同步所带来的安全性和正确性,这也使得 C++ 更适合面向对象开发。
getchar() 和 getline()
把这两个放一起存粹是因为他们长得很像,但是两者天差地别:
-
getchar()函数从标准输入(stdin)中读取一个字符,返回该字符的ASCII码值。 -
通常用于读取单个字符或者字符数组,可以实现简单的输入操作。
-
使用时需要注意的是,由于输入的字符是直接通过键盘输入的,因此需要按下回车键才能将输入的字符送入缓冲区,此时
getchar()才能够读取到输入的内容。 -
getline()函数从输入流中读取一行文本,并将其存储到一个字符串对象中,可以读取包含空格在内的一整行输入。 -
使用时需要注意的是,如果使用默认的分隔符
\n,getline()会将换行符读取到缓冲区,如果下一次使用getline()读取输入,就会导致缓冲区中的换行符被读取,而不是期望的输入。此时可以通过调用cin.ignore()来清除缓冲区中的字符,或者指定其他分隔符。
关于 getchar() 缓冲区的问题已经讲过,下面举个 getline() 的栗子:
观察下列代码:
#include <iostream>
#include <string>using namespace std;int main() {string s; getline(cin, s); //读入 string 类型 scout << "First: " << s << endl; //输出 sgetline(cin, s); //在此读入cout << "Second: " << s << endl; //再次输出 sreturn 0;
}
假设运行并且在控制台输入如下内容:
114
514
理论上,我期望得到输出:
First: 114
Second: 514
但实际上,控制台哼哼哼啊啊啊输出了如下内容:
First: 114
Second: 514
你会惊讶地发现符合期望,然后你想:“诶这不是没毛病垃圾 LysLysLys 玩我呢?”
你先别急,让我先急。
getline() 其参数实际上有三个,第三个参数为分隔符参数,即 getline() 会以该参数分割处理数据,默认缺省该参数的情况下,getline() 会以 \n 为分隔符,即默认我们使用的是 getline(cin, s, '\n');。
那么在该例子中,输入 114 后按下回车键,该回车键被视为一个分隔符并从输入流中删除,此时 \n 仍然留在缓冲区中 。然后第二个 getline() 调用会读取缓冲区中剩余的字符,即 "\n514",将其中的 \n 删除并存储 514。因此输出符合预期。
我们重新指定一下 getline() 的分隔符,修改得到如下代码:
#include <iostream>
#include <string>using namespace std;int main() {string s; getline(cin, s, ','); //读入 string 类型 s,并以 ',' 为分隔符cout << "First: " << s << endl; //输出 sgetline(cin, s, ','); //在此读入cout << "Second: " << s << endl; //再次输出 s,并以 ',' 为分隔符return 0;
}
假设运行并且在控制台输入如下内容:
114,
514,
理论上,我期望得到输出:
First: 114
Second: 514
但实际上,控制台哼哼哼啊啊啊输出了如下内容:
First: 114
Second:
514
你会惊讶地发现这次不符合期望了,然后你想:“诶这不废话吗垃圾 LysLysLys 玩我呢?”
你急了,但是你先别急。
在该例子中,输入 114, 后按下回车键,',' 则被视为了一个分隔符并从输入流中删除,但后续输入的 \n 保留在了缓冲区中 。然后第二个 getline() 调用会读取缓冲区中剩余的字符,即 "\n514,",将其中的 ',' 删除并存储 \n514。因此输出了不符合预期的内容。
为了避免这种结果,我们同样需要手动清空缓存区,可以使用 getchar() “吃掉”缓冲区中的 \n,但更建议使用如下方法:
#include <iostream>
#include <string>using namespace std;int main() {string s; getline(cin, s, ','); //读入 string 类型 scout << "First: " << s << endl; //输出 s// 使用 cin.ignore() 忽略掉输入缓冲区中的换行符// 也可以使用 cin.get() 读取缓冲区中的换行符cin.ignore();// cin.get();getline(cin, s, ','); //在此读入cout << "Second: " << s << endl; //再次输出 sreturn 0;
}
最终得到了符合预期的结果。
First: 114
Second: 514
总体而言,getchar()适用于读取单个字符或者字符数组,而getline()适用于读取一整行文本,两者使用时需要注意不同的输入方式和缓冲区处理。
stringstream
stringstream是C++标准库提供的一种数据流对象,用于在内存中对字符串进行输入输出操作。- 它可以像
cin和cout一样进行输入输出,并且具有和输入输出流相似的接口和方法,例如<<和>>操作符。 - 它提供了将一个字符串转换成一个数据类型的方法,方便程序员进行数据处理。
- 在
C++中,stringstream也是类型安全的。
stringstream 和 cin、cout 等输入输出流都有类似的接口和方法,可以进行输入输出操作,但它们的作用域不同。cin、cout 等输入输出流通常用于标准输入输出流,而 stringstream 通常用于字符串的处理。
通常我们可以使用 stringstream 对字符串进行分割、转换、拼接等操作,然后再使用 cin 或 cout 输出到标准输入输出流中:
- 我们可以使用
getline()函数从标准输入读取一行字符串; - 然后使用
stringstream将其转换为数值类型,最后再使用cout输出到标准输出流中。 - 这样的代码既可以处理标准输入输出流,又可以方便地进行字符串操作,提高了程序的可扩展性和复用性。
举个栗子:
观察如下代码:
#include <iostream>
#include <string>
#include <sstream>using namespace std;int main() {stringstream s;string name = "Lys";int age = 13;double height = 1.86;string status = "is a dog";s << "Name: " << name << ", Age: " << age << ", Height: " << height << ", Status: " << status;string str = s.str();cout << str << endl;return 0;
}
在这个示例中,我们首先创建了一个 stringstream 对象 s,然后使用<<运算符将字符串、整数和浮点数和一个字符串插入到 s 中,最后使用 str() 方法将所有插入的数据转换为一个字符串,并将其打印到标准输出中。
再比如,观察如下代码:
#include <iostream>
#include <string>
#include <sstream>using namespace std;int main() {string s;getline(cin, s);stringstream ss(s);string str;while(ss >> str){cout << str << endl;}return 0;
}
编译运行并且在控制台输入如下内容:
Lys is a dog.
然后得到如下输出:
Lys
is
a
dog.
在这个示例中,我们首先创建了一个 string 类型的 s,并用 getline(cin, s) 读入字符串,然后将字符串 s 转换为了stringstream 对象 ss,再通过该对象过滤空格后不断赋值给 str,最终将其打印到标准输出中。
2.2 关闭 C++ 标准流同步
前面提到了,由于 cin 和 cout 的同步流机制,因此,在性能上, scanf() 和 printf() 输入输出的效率显著优于 cin 和 cout,但我们仍然可以通过设置 cin 和 cout 的同步流标志位来关闭同步流,从而提高程序的效率,甚至优于 scanf() 和 printf()。
在 C++ 程序中,添加如下语句以优化输入输出流速度和交互性:
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
ios::sync_with_stdio(false):关闭C++的标准输入输出流与C语言输入输出流的同步,从而加快输入输出的速度。cin.tie(nullptr):解除cin和cout的绑定,从而避免在读取输入时,每次输出缓存区都被刷新的问题。cout.tie(nullptr):解除cout和cin的绑定,从而避免在输出时,每次读取输入都会刷新输出缓存区的问题。
需要注意的是,关闭输入输出流同步后,不能再在 C++ 代码中使用 C 语言的输入输出函数了,否则可能会导致输出不完整或者输出顺序错误等问题。此外,解除绑定后,需要手动刷新输出缓存区,否则输出的内容可能不完整或者不及时。因此,在使用这些语句时,需要谨慎地考虑使用场景和执行顺序,避免出现不可预料的错误。
下列语句:
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
同样可以达到提高输入输出速度的目的。这种写法比使用 nullptr 更加通用,因为在某些旧的 C++ 编译器中可能不支持 nullptr。
总的来说,这两种写法的区别并不大,只是在解除绑定时所使用的空指针常量不同,但都可以实现提高输入输出速度的效果。
3. 最后的练习
3.1 泛凯撒加密
Original Link
描述:
众所周知,在网络安全中分为明文和密文,凯撒加密是将一篇明文中所有的英文字母都向后移动三位(ZZZ 的下一位是 AAA),比如 aaa 向后移动三位就变成了 ddd,AAA 向后移动三位就变成了 DDD,ZZZ 向后移动三位就变成了 CCC,但是泛凯撒加密可没有这么简单,它是将明文中的每个字母向后移动k位得到密文,并且在密文的结尾会附加一个 ?,本题想让你通过得到密文反解出原本的明文。
输入格式:
第一行,输入一个正整数 kkk 表示字母向后移动的位数。
接下来输入若干行字符串,表示密文,数据输入保证仅密文的最后一个字符是 ?。
输出格式:
输出原本的明文。
数据范围:
0≤k≤1000 \le k \le 1000≤k≤100。
3.2 题解
你已经是一个成熟的 ACMer \text{ ACMer } ACMer 了,要学会自己分析并解决问题。实在解决不了就解决自己吧。
#include <iostream>
#include <cstring>using namespace std;void solve(){int k; cin >> k;string s;k %= 26;getchar(); //清空缓冲区中的 '\n'while(getline(cin, s)){for(int i = 0; i < s.size(); i ++){char st = s[i];if(st >= 'a' && st <= 'z') cout << char(st - k < 'a' ? st - k + 26 : st - k);else if(st >= 'A' && st <= 'Z') cout << char(st - k < 'A' ? st - k + 26 : st - k);else if(st == '?') break;else cout << st;}cout << endl;}
}int main(){solve();return 0;
}
相关文章:
浅谈 C/C++ 的输入输出
更好的阅读体验\huge{\color{red}{更好的阅读体验}}更好的阅读体验 文章目录0. 叠甲,过1. 谈谈输入输出缓冲区1.1 基本概念输入输出流标准输入输出流文件输入输出流1.2 输入输出缓冲区什么是输入输出缓冲区?为什么要设置输入输出缓冲区?C/C 的…...
【计算机三级网络技术】 第二篇 中小型系统总体规划与设计
文章目录一、基于网络的信息系统基本结构二、划分网络系统组建工程阶段三、网络需求调研与系统设计原则四、网络用户调查与网络工程需求分析1.网络用户调查2.网络节点的地理位置分布3.应用概要分析4.网络需求详细分析五、网络总体设计基本方法1.网络工程建设总体目标与设计原则…...
Boosting Crowd Counting via Multifaceted Attention之人群密度估计实践
这周闲来无事,看到一篇前不久刚发表的文章,是做密集人群密度估计的,这块我之前虽然也做过,但是主要是基于检测的方式实现的,这里提出来的方法还是比较有意思的,就拿来实践一下。论文在这里,感兴…...
python之面向对象编程
1、面向对象介绍: 世界万物,皆可分类 世界万物,皆为对象 只要是对象,就肯定属于某种类 只要是对象,就肯定有属性 2、 面向对象的几个特性: class类: 一个类即对一类拥有相同属性的对象的…...
常见前端基础面试题(HTML,CSS,JS)(七)
同源策略 浏览器有一个重要的安全策略,称之为同源策略 其中,协议、端口号、域名必须一致,,称之为同源,两个源不同,称之为跨源或跨域 同源策略是指,若页面的源和页面运行过程中加载的源不一致…...
产业链金风控基本逻辑
产业链金风控基本逻辑 产业链金融平台作为一个助贷平台,很大程度上是为银行等金融机构进 行引流,贷款的审批本质上还是依赖金融机构的风控。那么,产业链金融 平台是否还有必要建设自己的风控模型呢?笔者给出的答案是肯定的。 一方面&#x…...
Java高级点的知识
Java 集合框架 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。 对一个集合的扩展和适应…...
MyBatis - 05 - 封装SqlSessionUtil工具类(用于获取SqlSession对象)并测试功能
文章目录1.新建SqlSessionUtils工具类2.编写静态方法3.项目结构及代码项目结构数据库和表pom.xmlParameterMapper接口:User类:ParameterMapper.xmljdbc.propertieslog4j.xml:mybatis-config.xml:ParameterMapperTest测试类:测试结果1.新建Sql…...
Java中BIO、NIO和AIO的区别和应用场景
IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 一、BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信&#…...
Python安装教程(附带安装包)
首先,打开python安装包的下载地址,https://www.python.org/downloads/,会有些慢 点击downloads中的windows 左侧是稳定的版本,我这边下的是3.8的,不想去官网下载的可以直接用我下载的这个3.8版本,https://…...
华为OD机试用Python实现 -【信号发射和接收】(2023-Q1 新题)
华为OD机试题 华为OD机试300题大纲信号发射和接收题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现代码运行结果代码编写思路华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为…...
Springboot整合 Thymeleaf增删改查一篇就够了
很早之前写过Thymeleaf的文章,所以重新温习一下,非前后端分离,仅仅只是学习 官网: https://www.thymeleaf.org/ SpringBoot可以快速生成Spring应用,简化配置,自动装配,开箱即用。 JavaConfigur…...
BigScience bloom模型
简介项目叫 BigScience,模型叫 BLOOM,BLOOM 的英文全名代表着大科学、大型、开放科学、开源的多语言语言模型。拥有 1760 亿个参数的模型.BLOOM 是去年由 1000 多名志愿研究人员,学者 在一个名为“大科学 BigScience”的项目中创建的.BLOOM 和今天其他可用大型语言模型存在的一…...
Squid服务的缓存概念
Squid缓存概念 squid是一个缓存服务器的守护进程 之前涉及的缓存服务:redis 2-8原则:80%的访问就是从20%的数据提供的;因此把20%的数据给到缓存–>完美解决等待时间; nginx是没有缓存的服务的;那么专业的事情就…...
Hadoop YARN
目录Hadoop YARN介绍Hadoop YARN架构、组件程序提交YARN交互流程YARN资源调度器Scheduler调度器策略FIFO SchedulerCapacity SchedulerFair SchedulerHadoop YARN介绍 YARN是一个通用资源管理系统和调度平台,可为上层应用提供统一的资源管理和调度 上图࿱…...
使用 Macrobenchmark 测试 Android 应用性能
etpack Compose 是推荐用于构建原生 Android 界面的新工具包。后续简称Jetpack Compose为Compose。在了解State之前需要先对Compose及申明性编程式有个大概的了解。State初体验好了,在你有一定了解的基础上,我们先来运行几个Demo,初步了解为何…...
【django】django-simpleui配置后,后台显示空白页解决方法
every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 django后台显示空白页解决方法 1. 正文 添加完simpleui以后,后台显示一片空白,一脸问号??? …...
【035】基于Vue的电商推荐管理系统(含源码数据库、超详细论文)
摘 要:基于Vue+Nodejs+mysql的电商推荐管理系统,这个项目论文超详细,er图、接口文档、功能展示、技术栈等说明特别全!!! (文末附源码数据库、课设论文获取方式࿰…...
【c++】模板1—函数模板
文章目录函数模板语法函数模板注意事项案例—数组选择排序普通函数和函数模板的区别普通函数和函数模板调用规则模板的局限性函数模板语法 函数模板作用: 建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表…...
windows10 wsl子系统固定ip启动分配网卡法
WSL设置添加固定IP 在Win端添加一个固定IP 192.168.50.99 用于X-Server界面显示.在WSL端添加一个固定IP 192.168.50.16 用于和Win端通讯 在win端创建批处理文件 创建一个批处理文件 我的文件位置是D:\powershell\static_ip.bat 向vEthernet (WSL)网卡添加一个IP 192.168.50.…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
