Qt 每日面试题 -5

41、单继承和多继承

  • 单继承(派生类只从一个直接基类继承)时派生类的定义∶

    class 派生类名:继承方式 基类名

    {

    成员声明;

    }

  • 多继承 时派生类的定义∶

    class 派生类名:继承方式1 基类名1,继承方式2 基类名2,...

    {

    成员声明;

    }

注意:每一个"继承方式",只用于限制对紧随其后之基类的继承。

42、知道QT事件机制有几种级别的事件过滤吗?能大致描述下吗?

根据对Qt事件机制的分析,我们可以得到5种级别的事件过滤,处理办法.以功能从弱到强,排列如下:

  1. 重载特定事件处理函数

    最常见的事件处理办法就是重载像mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数.

  2. 重载event()函数

    通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(象keyPressEvent())处理它.比如,当我们想改变tab键的默认动作时,一般要重载这个函数.在处理一些不常见的事件(比如:LayoutDirectionChange)时,evnet()也很有用,因为这些函数没有相应的特定事件处理函数.当我们重载event()函数时,需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件.

  3. 在Qt对象上安装事件过滤器

    安装事件过滤器(假设要用A来监视过滤B的事件)有两个步骤:

    • 首先调用B的installEventFilter( const QObect *obj ),以A的指针作为参数.这样所有发往B的事件都将先由A的eventFilter()处理.
    • A要重载QObject:eventFilter()函数,在eventFilter()中书写对事件进行处理的代码.
  4. 给QAppliction对象安装事件过滤器

    一旦我们给qApp(每个程序中唯一的QApplication对象)装上过滤器,那么所有的事件在发往任何其他的过滤器时,都要先经过当前这个eventFilter().在debug的时候,这个办法就非常有用,也常常被用来处理失效了的widget的鼠标事件,通常这些事件会被QApplication::notify()丢掉.(在QApplication:notify()中,是先调用qApp的过滤器,再对事件进行分析,以决定是否合并或丢弃)

  5. 继承QApplication类,并重载notify()函数.

    Qt是用QApplication::notify()函数来分发事件的.想要在任何事件过滤器查看任何事件之前先得到这些事件,重载这个函数是唯一的办法.通常来说事件过滤器更好用一些,因为不需要去继承QApplication类.而且可以给QApplication对象安装任意个数的事件。

43、有没有使用过Qt4 ? Qt5的信号槽与Qt4相比有什么改进?

  • 编译期∶检查信号与槽是否存在,参数类型检查,Q_OBJECT是否存在
  • 信号可以和普通的函数、类的普通成员函数、lambda函数连接(而不再局限于信号函数和槽函数)
  • 参数可以是typedef的或使用不同的namespace specifier
  • 可以允许一些自动的类型转换(即信号和槽参数类型不必完全匹配)

44、信号槽是同步的还是异步的?分别如何实现?

通常使用的connect,实际上最后一个参数使用的是Qt:AutoConnection类型:Qt支持6种连接方式,其中3中最主要:

  1. Qt::DirectConnection(直连方式)(信号与槽函数关系类似于函数调用,同步执行) 当信号发出后,相应的槽函数将立即被调用。emit语句后的代码将在所有槽函数执行完毕后被执行。
  2. Qt::QueuedConnection(排队方式)(此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信,异步执行) 当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕。
  3. Qt::AutoConnection(自动方式)(Qt的默认连接方式) 如果信号的发出和接收这个信号的对象同属一个线程,那个工作方式与直连方式相同﹔否则工作方式与排队方式相同。
  4. Qt::BlockingQueuedConnection**(信号和槽必须在不同的线程中,否则就产生死锁)** 这个是完全同步队列只有槽线程执行完成才会返回,否则发送线程也会一直等待,相当于是不同的线程可以同步起来执行。
  5. Qt:UniqueConnection与默认工作方式相同 ,只是不能重复连接相同的信号和槽,因为如果重复连接就会导致一个信号发出,对应槽函数就会执行多次。
  6. Qt::AutoCompatConnection工作方式与Qt::AutoConnection一样。

45、知道死锁吗?死锁是如何产生的?

死锁的产生有如下四个必要条件:

  1. 资源是互斥的,同一时刻只能有一个进程占有该资源
  2. 资源的释放只能由该进程自己完成
  3. 线程在获取到需要资源之前,不会释放已有资源
  4. 存在这么一条循环等待的队列,线程T1,T2,T3...,Tn
    (T1持有自己的资源请求T2的资源...Tn持有自己的资源请求T1的资源)

46、Qt线程同步的方法有哪些?

  1. 互斥量(QMutex)
cpp 复制代码
QMutex 	m_Mutex;	
m_Mutex.lock();	
m_Mutex.unlock()
  1. 互斥锁(QMutexLocker)
cpp 复制代码
QMutexLocker  mutexLocker(&m_Mutex);

从声明处开始(在构造函数中加锁),出了作用域自动解锁(在析构函数中解锁)

  1. 等待条件(QWaitCondition)
cpp 复制代码
QWaitCondtion	m_WaitCondition;	
m_WaitConditon.wait(&m_muxtex,time);
m_WaitCondition.wakeAll();
  1. QReadWriteLock类
    • 一个线程试图对一个加了读锁的互斥量进行上读锁,允许;
    • 一个线程试图对一个加了读锁的互斥量进行上写锁,阻塞;
    • 一个线程试图对一个加了写锁的互斥量进行上读锁,阻塞;
    • 一个线程试图对一个加了写锁的互斥量进行上写锁,阻塞。

读写锁比较适用的情况是︰需要多次对共享的数据进行读操作的阅读线程。

QReadWriterLock 与QMutex相似,除了它对"read" ,"write"访问进行区别对待。它使得多个读者可以共时访问数据。使用QReadWriteLock而不是QMutex,可以使得多线程程序更具有并发性。

  1. 信号量QSemaphore

    但是还有些互斥量(资源)的数量并不止一个,比如一个电脑安装了2个打印机,我已经申请了一个,但是我不能霸占这两个,你来访问的时候如果发现还有空闲的仍然可以申请到的。于是这个互斥量可以分为两部分,已使用和未使用。

  2. QReadLocker类和QWriteLocker类对QReadWriteLock进行加解锁

47、工作中有没有使用过动态库和静态库?能不能简单说下两者的区别?

  • 静态库∶在链接阶段将汇编生成的目标文件.o与引用库一起链接打包到可执行文件中,可简单看成( .o或者.obj文件的集合)。

    1. 对函数库的链接是放在编译时期完成的
    2. 程序在运行时与函数库没有瓜葛,移植方便
    3. 浪费空间和资源
  • 动态库:

    1. 将库函数的链接载入推迟到程序运行时期
    2. 可以实现进程间的资源共享(因此也称为共享库)
    3. 将一些程序升级变得简单
    4. 可以真正的做到链接载入完全由程序员在程序代码中控制(显示调用)

动态库一般也会有个lib文件,那么和静态库lib文件有什么区别?

动态库中的.lib文件叫做导入库,对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

静态库中的.lib叫做静态库,本身就包含了实际执行代码、符号表等等。

48、设计模式平时有使用到吗? 能不能说下常见的设计模式有哪些? 能不能说说大致的概念? 能不能具体说下工作中如何使用的?

总体来说设计模式分为三大类︰

  • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

  • 结构型模式,共七种︰适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

49、HTTP协议有使用过吗? Qt5中使用的相关联的主要的几个类?

QNetworkAccessManager

QNetworkRequest

QNetworkReply

50、平时使用算法比较多吗?能简单说下快排的思想吗?时间复杂度是多少?

  • 基本思想是∶通过一趟排序将要排序的数据分割成独立的两部分 ,其中一部分的所有数据都比另外一部分的所有数据都要小 ,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
  • 时间复杂度: 平均为O(nlogn),最好为O(nlogn),最差为O(logn2)
相关推荐
嵌入式郑工1 分钟前
LINUX驱动开发: 设备和驱动是怎么匹配的?
linux·运维·服务器
nongcunqq30 分钟前
abap 操作 excel
java·数据库·excel
诸葛悠闲1 小时前
XCP协议在以太网上实现的配置
学习
rain bye bye1 小时前
calibre LVS 跑不起来 就将setup 的LVS Option connect下的 connect all nets by name 打开。
服务器·数据库·lvs
郭式云源生法则1 小时前
归档及压缩、重定向与管道操作和综合使用,find精确查找、find处理查找结果、vim高级使用、vimdiff多文件使用
linux·运维·服务器
小池先生2 小时前
服务请求出现偶发超时问题,经查服务本身没问题,问题出现在nginx转发。
运维·服务器·nginx
mapbar_front2 小时前
面试问题—我的问题问完了,你还有什么想问我的吗?
前端·面试
倔强青铜三2 小时前
苦练Python第67天:光速读取任意行,linecache模块解锁文件处理新姿势
人工智能·python·面试
遇印记2 小时前
大二java学习笔记:二维数组
java·笔记·学习
阿里云大数据AI技术2 小时前
云栖实录|MaxCompute全新升级:AI时代的原生数据仓库
大数据·数据库·云原生