1 元素基本有序的情况下,时间复杂度?
数据结构——排序
https://blog.csdn.net/skyejy/article/details/88428495
2 设计模式七大原则
1、单一职责原则
对于类来说,就是一个类应该只负责一项职责,如果类A负责了职责1和职责2,当职责1的需求发生改变时,可能对职责2的执行造成影响,因此需要将类A分解为类A1和类A2。
- 为了降低类的复杂度,做到一个类只负责一项职责;
- 可以提高类的可读性和可维护性,降低变更引起的风险;
- 通常情况下,我们应当逻辑单一职责原则,只有逻辑足够简单才能在代码上违反单一职责原则,只有类中方法数量很少,才可以只在方法级别上遵守单一职责原则。
2、接口隔离原则
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
为什么会有接口隔离?考虑这么一种情况,现有一个接口包含了三个方法,有类A和类B实现了该接口,而类C和类D依赖于该接口。(这里依赖的意思,类C和D中有方法的参数是接口,而我们可以将实现了接口的类A和B作为C和D方法的参数)。
3、依赖倒转原则
- 高层模块不应该依赖底层模块,二者都应该依赖于抽象
- 抽象不应该依赖于细节,细节要依赖于抽象
- 抽象在Java中就是指接口或抽象类,细节就是具体的实现类
- 依赖倒转的中心思想就是面向接口编程
- 使用接口或抽象类的目的是为了制定好规范,而不涉及任何具体的作用,把展现细节的任务交给它们的实现类。
依赖倒转小结:
- 底层模块尽量都要有抽象类或接口,这样程序稳定性更好!
- 变量的声明类型尽量都是抽象类或接口,这样我们的变量引用和实际对象间就有一个缓冲,利于程序扩展和优化。
- 继承时遵循里氏替换。
4、里氏替换原则
- 所有引用基类的地方,必须能透明的使用其子类。
- 因此,在继承时,子类尽量不要重写父类的方法。
- 继承会让两个类的耦合性增强,因此适当情况下,可以通过聚合、组合、依赖来解决问题。(假如A继承于B,我们可以抽取其公共部分为Base类,然后使用组合,在A类中创建B的对象)
5、开闭原则
- 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则
- 一个软件实体,例如类、模块、函数应该对扩展开发(针对开发方),对修改关闭(针对使用方)。用抽象构建框架,用实现扩展细节。
- 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有代码来实现变化。
- 编程中遵循的其他原则,以及使用设计模式的目的就是遵守开闭原则。
6、迪米特法则
- 一个对象应该对其他对象保持最少的了解
- 类与类关系越密切,耦合度越大
- 迪米特法则也叫最少知道原则,即一个类对自己依赖的类知道的越少越好。对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供public方法外,不要泄露任何信息。
- 迪米特法则还有个更简单的定义:只与直接朋友通信。
- 直接朋友:只要两个对象间有耦合关系,那么它们就是朋友。耦合包括依赖、关联、组合、聚合等等。其中,我们将成员变量、方法参数、方法返回值中的类称为直接朋友,而出现在局部变量中的类(例如class A的一个方法里有class B对象)不是直接朋友。换句话说,陌生的类最好不要以局部变量的形式出现在类的内部。
注意:迪米特法则的核心只要求降低类之间的耦合,并不是完全没有依赖。
设计模式目的以及遵循的七大原则
https://blog.csdn.net/qq_39763246/article/details/114546544
单例模式【饿汉式、懒汉式、双重检查、静态内部类、枚举】
https://blog.csdn.net/qq_39763246/article/details/114553165
《设计模式:可复用面向对象软件的基础》学习并理解 23 种设计模式
https://cloud.tencent.com/developer/article/1782278
7、合成复用原则
尽量使用合成/聚合的方式,而不是使用继承。
3 管道通信以文件写入和读出
管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据
4 windows编程,定时器消息-WM_TIMER
5 modbus协议读取保持寄存器功能码-03
6 请选择正确的描述。( )
A. 静态变量和全局变量是在程序一开始时分配内存的,这部分内存无法回收,直至程序结束
B. 通常常来说,在堆上分配内存比在栈上分配内存效率更高
C. 当我预先知道待分配内存大小时,我就可以直接在栈上分配内存,只要不超过当前操作系统的可用内存大小,就永远会成功
D. 内存泄漏就是指当A程序申请一块内存时,有可能操作系统把B程序的一块内存先交给A程序使用,等A程序结束后再返回给B程序,在内存借用的这段时间内,B程序就产生了内存泄漏
栈上分配内存效率更高;栈上申请内存并不总是成功;内存泄漏是使用完成之后未回收又无法使用的区域。
7 并发-同一个对象被多个线程同时操作
C++11 并发编程基础(一):并发、并行与C++多线程
https://cloud.tencent.com/developer/article/2356767
8
操作系统调度基本单位:进程【系统为进程分配资源,不对线程分配资源】
操作系统调度最小单位:线程
cpu调度基本单位:线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
进程与线程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些
一个线程可以创建另一个线程
9
经常用于搜索、排序和分组的字段
如果某个字段经常用于WHERE子句中的搜索条件、ORDER BY子句中的排序或GROUP BY子句中的分组,那么为这个字段建立索引通常会带来性能提升。
唯一性约束的字段
对于具有唯一性约束的字段(如主键),MySQL会自动为其建立唯一索引。这样的索引不仅有助于确保数据的唯一性,还能提高查询性能。
外键关联的字段
在关系型数据库中,外键用于建立表与表之间的关系。为外键字段建立索引可以加速连接查询(如JOIN操作)的性能。
低基数字段
基数(Cardinality)是指某个字段中不同值的数量。如果一个字段的基数很低(即该字段的值重复度很高),那么为这个字段建立索引可能不太有价值。因为索引的主要目的是减少需要扫描的数据行数,而低基数字段通常意味着大部分数据行都有相同的值,因此索引的效果不明显。
文本字段的前缀索引
对于长文本字段,如VARCHAR或TEXT类型,为其整个内容建立索引可能不太实际,因为这会占用大量存储空间并降低更新性能。在这种情况下,可以考虑为文本字段的前缀(如前N个字符)建立索引。这样既能提高查询性能,又能节省存储空间。
复合索引的选择性字段
复合索引是指在多个字段上建立的索引。在选择复合索引的字段时,应该考虑字段的选择性(即不同值的数量与总行数之比)。具有较高选择性的字段应该放在复合索引的前面,以便更好地利用索引的优势。
避免过度索引
虽然索引可以提高查询性能,但过多的索引也会导致性能下降。每个额外的索引都会占用额外的存储空间,并增加插入、更新和删除操作的开销。因此,在选择建立索引的字段时,应该权衡查询性能和存储/更新开销之间的平衡。
10 MVVM框架?
Model-ViewModel-View-Controller
11
C++中左值(lvalue)和右值(rvalue)是比较基础的概念,虽然平常几乎用不到,但C++11之后变得十分重要,它是理解 move/forward 等新语义的基础。
左值与右值这两个概念是从 C 中传承而来的,左值指既能够出现在等号左边,也能出现在等号右边的变量;右值则是只能出现在等号右边的变量。
int a; // a 为左值
a = 3; // 3 为右值
左值是可寻址的变量,有持久性;
右值一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。
左值和右值主要的区别之一是左值可以被修改,而右值不能。
++i在C中不是左值,在C++中才是
i++在C和C++中都不能作左值。
#include<bits/stdc++.h>
using namespace std;
int main(){
int a = 1;
a += (a++);
cout << a << endl;
int b = 1;
b += (++b);
cout << b << endl;
int c = 1;
(c++) += c;
cout << c << endl;
int d = 1;
(++d) += (d++);
cout << d << endl;
return 0;
}
12
https://cloud.tencent.com/developer/article/2356767
https://blog.csdn.net/qq_39763246/article/details/114553165
https://blog.csdn.net/weixin_62676865/article/details/130162356
https://blog.csdn.net/mrqzgmzlb/article/details/130070772
https://blog.csdn.net/DQ1005/article/details/50854550
https://zhuanlan.zhihu.com/p/143699501
https://cloud.baidu.com/article/3295526
https://zhuanlan.zhihu.com/p/566841506
https://blog.csdn.net/zhanghuaichao/article/details/52788169
https://blog.csdn.net/sinat_31608641/article/details/123017378#:~:text=Explicit Linking 即显式链接,Implicit Linking 即隐式链接,这两种都是 动态链接库 的使用方式。 一、显式链接,动态库 的函数,Linux 里比如用 dlopen 函数打开并加载动态库,Windows 里一般用 LoadLibrary 打开并加载动态库,只有当程序代码执行到这些函数时,其参数里的动态库才会被加载,这就是显式链接。