金山WPS面试题
1.windows的handle
1)是一个宏定义#define void* HANDLE
2) HANDLE提供了一种统一的方式去获得系统资源,并对其进行操作。
3) HANDLE使得程序设计的细节得以被隐藏,从而能够更加方便地对细节的实现进行修改。
4) 由于不知道HANDLE所指向的具体的数据结构,所以我们必须根据源码提供者的API使用HANDLE,而且不同种类的HANDLE是无法混用的。例如:GetModuleHandle返回的HANDLE和GetFileHandle返回的HANDLE是不同的,只能在他们对应的函数中使用。
5)HANDLE(句柄)是Windows操作系统中的一个概念。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标示这些资源的标示号,即句柄
无效的返回值为: INVALID_HANDLE_VALUE
编程时可作调试用:
例如:
#include<iostream>
#include<windows.h>
using namespace std;
int main(void)
{
char ch[20] = "Test.dsw";
HANDLE handle;
LPWIN32_FIND_DATA fd;
handle = FindFirstFile(ch,fd);
if(handle != INVALID_HANDLE_VALUE)
cout<<"ok"<<endl;
else
cout<<"no"<<endl;
return 0;
}
2.windows的文件handle和linux的文件系统
同1
3.QT的connect连接的几种方式
//1.Qt::DirectConnection 直接连接,当发送者和接收者在同一个线程的时候
//2.Qt::QueuedConnection 队列的形式连接,当发送者和接收者不在同一个线程的时候
//3.Qt::BlockingQueuedConnection 发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
//4.Qt::AutoConnection 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
//5.Qt::UniqueConnection 这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
4.sizeHint的用途和场景
1)widget->sizeHint().width(); 当widget没有setLayout(layout)设置布局的时候sizeHint是valid不合法的,当设置了布局的时候返回layout的首选尺寸;
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
5.map和hashmap
https://www.cnblogs.com/chengxiao/p/6059914.html hashmap以及数组操作的时间复杂度;
1)map时间复杂度 log(n)
2)hashmap时间复杂度o(1)
3)hashmap牺牲空间来节省时间,数据量比较大的情况下采用能够更好地提升效率
6.QT QObject的线程相关性
1)内部会记录当前线程的id,通过对比发送信号的线程id和接受信号的线程id是否在同一个线程内决定采用哪种连接方式;
https://blog.csdn.net/LynFam/article/details/7081545
7.Https的几种返回码
https://i.cnblogs.com/EditPosts.aspx?postid=10188381
8.json和protoful的区别
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
9.map遍历的时间复杂度
1)map时间复杂度 log(n)
2)hashmap时间复杂度o(1)
10.list插入的时间复杂度
list插入的时间复杂度为o(1) 常量;不支持随机访问;
1)vector
内部数据结构:数组。
在末尾增加或者删除元素所需时间与元素数目无关,在中间或者开头增加或者删除元素所需时间是随元素数目呈线性变化。
2)deque
内部数据结构是:数组
随机访问每个元素,所需要的时间为常量。在开头和末尾增加元素所需时间与元素数目无关,在中间增加或删除所需时间随元素数目呈线性变化。
3)list
内部数据结构:双向环状链表
不能随机访问一个元素,可双向遍历,在开头,末尾和中间的任何地方增加或者删除元素所需时间都是常量。
4)set
键和值相等。
键唯一
元素默认按升序排列、
5)map
键唯一,
元素默认按键的升序排列
11.迭代器和指针的区别
1)迭代器是指针的抽象,每一种容器都有自己对应的迭代器。
2)迭代器是具有指针行为也就是重载了->指针操作符的class template
12.c++11的新特性 Lambada的传值的几种方式
总结几个要点
1)[]()-> type{} 或者 [](){}两种形式都可以(即省略返回值类型),但是赋值给的函数指针的返回值类型要一致;
2)
[] //未定义变量.试图在Lambda内使用任何外部变量都是错误的. [x, &y] //x 按值捕获, y 按引用捕获. [&] //用到的任何外部变量都隐式按引用捕获 [=] //用到的任何外部变量都隐式按值捕获 [&, x] //x显式地按值捕获. 其它变量按引用捕获 [=, &z] //z按引用捕获. 其它变量按值捕获
外部变量的捕获必须用这几种形式;
3)如果lambda表达式捕获了引用传递,不能作为函数参数传入;
4)可以定义auto或者对应的函数指针类型的变量来接收lambda表达式,然后调用;
5)lambda即使是无参的也不能直接执行,必须通过函数指针或者auto类型的变量来调用执行;
13.QML中C++和QML如何交互和传值
14.QEventLoop
15.内存回收机制
16.c++的类型转换
- static_cast: 1)完成基础数据类型,2)同一个继承体系中类型的转换 3)任意类型与空指针类型void*之间的转换。
- dynamic_cast:使用多态的场景,增加了一层对真实调用对象类型的检查
- reinterpret_cast:个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄\
玄虚和其他目的,这是所有映射中最危险的。 - const_cast:去掉常属性,只有转换的当时有效,之后变量恢复常属性;
17.迭代器什么时候会失效
include "stdafx.h"
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vect;
for(int i = 0; i < 10; i++ )
{
vect.push_back(i);
}
vector<int>::iterator iter = vect.begin();
for(; iter != vect.end(); iter++ )
{
if( *iter % 2 == 0 )
{
vect.erase(iter);
}
}
return 0;
}
iter是指向vector这个容器中的某个元素,如果不是在for、while循环中,erase删除元素是没有问题的,但是如果在for、while循环中对容器迭代,删除其中符合条件的所有元素,就可能出现问题。vect.erase(iter)之后,iter及其后面的迭代器已经失效了,不应该再使用这些迭代器了,再执行it++,其行为是未定义的。其它容器也会遇到迭代器失效的问题。
对于vector被删除元素的迭代器以及指向后面元素的迭代器全部失效。对于deque在首部或尾部删除元素则只会使指向被删除元素的迭代器失效,任何其它位置的插入和删除操作将使指向该容器元素的所有迭代器失效。
对于list仅有指向被删除元素的迭代器失效。为什么不同容器迭代器失效情况有差别呢?这主要与各容器的数据结构有关。
18.Qt的图形处理;