站长检测同ip网站很多怎么办,上海公司排行榜,企业网站适合响应式嘛,昆明网站建设博滇一、c基础知识
1、进程和线程的同步方式 进程#xff1a;1#xff09;管道#xff0c;是内核里的一串缓存 2#xff09;消息队列 3#xff09;共享内存 4#xff09;信号量机制 5#xff09;信号 6#xff09;socket 线程#xff1a;1#xff09;等待通知机制 2基础知识
1、进程和线程的同步方式 进程1管道是内核里的一串缓存 2消息队列 3共享内存 4信号量机制 5信号 6socket 线程1等待通知机制 2共享内存 3管道 5并发工具 信号量、读写锁、互斥锁和条件变量 线程的死锁概念 线程间相互等待临界资源而造成彼此无法继续执行 方式一 1创建一个线程类的子对象继承QThread 2重写父类的run()方法在该函数内部编写子线程要处理的具体业务流程 3在主线程中创建子线程对象new一个 4启动子线程调用start()方法 方式二 1创建一个新的类QObject派生 2类中添加一个公有的自定义成员函数函数体就是子线程中执行的业务逻辑 3主线程中创建一个 QThread 对象就是子线程对象 4在主线程中创建工作的类对象,不要给创建的对象指定父对象 5Mywork对象移动到创建的子线程对象中需要调用QObject类提供的 moveToThread() 方法 注意事项: 业务对象, 构造的时候不能指定父对象 子线程中不能处理ui窗口(ui相关的类) 子线程中只能处理一些数据相关的操作, 不能涉及窗口 2、什么是堆栈 栈区stack 堆区heap抽象数据结构后进先出 全局区静态区static 文字常量区 程序代码区 栈是自动分配释放一级缓存类似数组的结构。 堆是由程序员分配释放二级缓存速度慢些先进后出。 3、常用的排序 插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序 冒泡排序 时间复杂度最好On,最坏O(n的2次方)。 空间复杂度O1 4、数组和链表的区别 1数组连续储存、固定长度、增删需要移动其他元素。链表动态分配不连续需要malloc或 new申请内存不用时要free或delete. 2数组访问效率高链表删插效率高 3数组利用下标定位查找的时间复杂度是O(1)链表通过遍历定位元素查找的时间复杂度是O(N)。 4数组插入和删除需要移动其他元素时间复杂度是O(N)链表的插入或删除不需要移动其他元素时间复杂度是O(1)。 5、回调函数的三种典型使用场景 1实现函数功能重定义 2扩展函数功能 3实现程序分层设计 6、区分static和const static 1 修饰全局变量变量只在本模块内可见在定义不需要与其他文件共享的全局变量时加上 static 关键字能够有效地降低程序模块之间的耦合避免不同文件同名变量的冲突且不会误使用。 2 修饰局部变量变量在全局数据区分配内存空间编译器自动对其初始化其作用域为局部作用域当定义它的函数结束时其作用域随之结束。 3 修饰函数函数的使用方式与全局变量类似在函数的返回类型前加上 static就是静态函数静态函数只能在声明它的文件中可见其他文件不能引用该函数不同的文件可以使用相同名字的静态函数互不影响。 const 被 const 修饰的变量是只读变量本质还是变量有人称其为常变量和普通变量的区别在于常变量不能用于左值其余的用法和普通常量一样变量名不可以改变。 7、工作中有没有使用过动态库和静态库能不能简单说下两者的区别 答静态库在链接阶段将汇编生成的目标文件.o与引用库一起链接打包到可执行文件中可简单看成.o或者.obj文件的集合。1对函数库的链接是放在编译时期完成的2程序在运行时与函数库没有瓜葛移植方便3浪费空间和资源 动态库1将库函数的链接载入推迟到程序运行时期2可以实现进程间的资源共享因此也称为共享库3将一些程序升级变得简单4可以真正的做到链接载入完全由程序员在程序代码中控制显示调用 8、虚函数 父类型的指针指向其子类的实例 存在虚函数的类都有一个一维的虚函数表叫做虚表 类的对象有一个指向虚表开始的虚指针。虚表是和类对应的虚表指针是和对象对应的。 默认构造函数、初始化构造函数、拷贝构造函数、移动构造函数 构造函数为什么不能被声明为虚函数 虚函数对应一个vtale,这个表的地址是存储在对象的内存空间的。如果将构造函数设置为虚函数 就需要到vtable 中调用可是对象还没有实例化没有内存空间分配如何调用 9、STL相关知识 STL由6部分组成容器(Container)、算法Algorithm、 迭代器Iterator、 仿函数Function object、适配器Adaptor、空间配制器Allocator 容器、算法、迭代器、仿函数、适配器、空间配置器 容器数组(array) , 链表(list), tree(树)栈(stack), 队列(queue), 集合(set),映射表(map) string容器 Vector容器是单向开口的连续内存空间deque则是一种双向开口的连续线性空间 stack是一种先进后出 Queue是一种先进先出 list容器链表是一种物理存储单元上非连续、非顺序的存储结构 set/multiset二叉树 map/multimap二叉树 交换查找,遍历复制修改反转排序合并等 10、智能指针auto_ptr17后已遗弃、unique_ptr、shared_ptr 和 weak_ptr 智能指针本质就是一个类模板当智能指针对象使用完后对象就会自动调用析构函数去释放该指针所指向的空间。 shared_ptr采用的是引用计数原理来实现多个shared_ptr对象之间共享资源 shared_ptr在内部会维护着一份引用计数用来记录该份资源被几个对象共享。 当一个shared_ptr对象被销毁时调用析构函数析构函数内就会将该计数减1。 如果引用计数减为0后则表示自己是最后一个使用该资源的shared_ptr对象必须释放资源。 如果引用计数不是0就说明自己还有其他对象在使用则不能释放该资源否则其他对象就成为野指针。 11、指针和引用的区别 指针是一个实体而引用仅是个别名。 引用只能在定义时被初始化一次之后不可变但指针可以改变。 指针可以有多级但引用只有一级。 引用不能为空指针可以为空。 sizeof 引用”得到的是所指向的变量(对象)的大小而“sizeof 指针”得到的是指针本身的大小 指针和引用的自增()运算意义不一样 引用是类型安全的而指针不是 引用比指针多了类型检查。 引用没有const指针有constconst的指针不可变。 访问实体方式不同指针需要显式解引用引用编译器自己处理
二、网络编程
1、描述QT的TCP通讯流程 服务端QTcpServer ①创建QTcpServer对象 ②监听list需要的参数是地址和端口号 ③当有新的客户端连接成功回发送newConnect信号 ④在newConnection信号槽函数中调用nextPendingConnection函数获取新连接QTcpSocket对象 ⑤连接QTcpSocket对象的readRead信号 ⑥在readRead信号的槽函数使用read接收数据 ⑦调用write成员函数发送数据 客户端QTcpSocket ①创建QTcpSocket对象 ②当对象与Server连接成功时会发送connected 信号 ③调用成员函数connectToHost连接服务器需要的参数是地址和端口号 ④connected信号的槽函数开启发送数据 ⑤使用write发送数据read接收数据 1长连接的保活问题 标准TCP层协议里把对方超时设为2小时若服务器端超过了2小时还没收到客户的信息它就发送探测报文段若发送了10个探测报文段每一个相隔75S还没有收到响应就假定客户出了故障并终止这个连接。因此应对tcp长连接进行保活。 2TCP提供了强制数据立即传送的操作指令pushTCP软件收到该操作指令后就立即将本段数据发送出去而不必等待发送缓冲区满 解决方法二发送固定长度的消息 解决方法三把消息的尺寸与消息一块发送 解决方法四双方约定每次传送的大小 解决方法五双方约定使用特殊标记来区分消息间隔 解决方法六标准协议按协议规则处理如Sip协议 3粘包问题 TCP产生粘包问题的主要原因是TCP是面向连接的所以在TCP看来并没有把消息看成一条条的而是全部消息在TCP眼里都是字节流 因此A、B消息混在一起后TCP就分不清了。 粘包问题的最本质原因在与接收对等方无法分辨消息与消息之间的边界在哪。我们通过使用某种方案给出边界例如 包头加上包体长度。包头是定长的4个字节说明了包体的长度。接收对先接收包体长度依据包体长度来接收包体。 解决方法一TCP提供了强制数据立即传送的操作指令pushTCP软件收到该操作指令后就立即将本段数据发送出去而不必等待发送缓冲区满 解决方法二发送固定长度的消息 解决方法三把消息的尺寸与消息一块发送 解决方法四双方约定每次传送的大小 解决方法五双方约定使用特殊标记来区分消息间隔 解决方法六标准协议按协议规则处理如Sip协议 发送端给每个数据包添加包首部首部中应该至少包含数据包的长度这样接收端在接收到数据后通过读取包首部的长度字段便知道每一个数据包的实际长度了。 发送端将每个数据包封装为固定长度不够的可以通过补0填充这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。 可以在数据包之间设置边界如添加特殊符号这样接收端通过这个边界就可以将不同的数据包拆分开。 指定数据长度的解决方法主要思路 我们在数据结构中有个成员代表了长度消息头我们准备一个足够大的消息缓冲区程序中是1024000个字节循环使用socket中的recv每次读取最多102400个字节然后把循环接收的消息拼接到消息缓冲区中直到接收到的消息大于消息头指示的长度则接收到了一个完整的消息所以我们的消息缓冲区要比完整的消息还要大才行进行消息处理。 4TCP与UDP区别总结 1、TCP面向连接如打电话要先拨号建立连接;UDP是无连接的即发送数据之前不需要建立连接 2、TCP提供可靠的服务。也就是说通过TCP连接传送的数据无差错不丢失不重复且按序到达;UDP尽最大努力交付即不保 证可靠交付 3、TCP面向字节流实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 UDP没有拥塞控制因此网络出现拥塞不会使源主机的发送速率降低对实时应用很有用如IP电话实时视频会议等 4、每一条TCP连接只能是点到点的;UDP支持一对一一对多多对一和多对多的交互通信 5、TCP首部开销20字节;UDP的首部开销小只有8个字节 6、TCP的逻辑通信信道是全双工的可靠信道UDP则是不可靠信道 7、三次握手和四次挥手具体流程 SYN:请求建立连接FIN请求断开连接ACK:确认是否有效 seq:序列号 ack:确认号 1三次握手 1.客户端向服务端发送⼀个SYN1请求建立连接并生成一个序列号seqj。 2.服务端接收到SYN1后给客户端发送⼀个SYN1与ACK1并将ack置为j1;同时生成一个序列号seqk。 3.客户端接收到会检查ack是否为j1与ACK是否为1如果是则会给服务端发送一个ACK1与ackk1以及自己的序列号seqj1; 服务端接收到会检查ACK是否为1与ack是否为k1,如果是则代表连接建立成功两者间可以传递数据。 2四次挥手 1.客户端向服务端发送FIN1请求关闭连接并生成一个序列号seqx。 2.服务端接收FIN后向客户端发送ACK1ackx1并生成序列号seqy客户端无数据发送但服务器端需发送完最后的数据。 3.服务端处理完所有数据后向客户端发送FIN1与ACK1ackx1并生成序列号z表示服务端现在可以断开连接。 4.客户端收到服务端的数据包后会向服务端发送ACK1,seqx1ackz1需要等待2MSL后才可断开连接。 8、指针和引用的区别 指针是一个实体而引用仅是个别名。 引用只能在定义时被初始化一次之后不可变但指针可以改变。 指针可以有多级但引用只有一级。 引用不能为空指针可以为空。 sizeof 引用”得到的是所指向的变量(对象)的大小而“sizeof 指针”得到的是指针本身的大小 指针和引用的自增()运算意义不一样 引用是类型安全的而指针不是 引用比指针多了类型检查。 引用没有const指针有constconst的指针不可变。 访问实体方式不同指针需要显式解引用引用编译器自己处理 9、HTTP 是一种 超文本传输协议 因特网的协议栈由五个部分组成物理层、链路层、网络层、运输层和应用层 URL即网址 浏览器会向DNS域名服务器后面会说提供网址 HTML 称为超文本标记语言 http协议是应用层协议主要是解决如何包装数据。而tcp协议是传输层协议主要解决数据如何在网络中传输。 通俗点说http的任务是与服务器交换信息它不管怎么连到服务器和保证数据正确的事情。而tcp的任务是保证连接的可靠它只管连接它不管连接后要传什么数据。 http协议是建立在tcp之上的http是无状态的短链接而tcp是有状态的长链接。 HTTPS是以安全为目标的 HTTP 通道是 HTTP 的安全版。HTTPS 的安全基础是 SSL。 SSL 协议位于 TCP/IP 协议与各种应用层协议之间为数据通讯提供安全支持。 二、HTTP 与 HTTPS 的区别 1、HTTPS 协议需要到 CA Certificate Authority证书颁发机构申请证书一般免费证书较少因而需要一定费用。 (以前的网易官网是http而网易邮箱是 https 。) 2、HTTP 是超文本传输协议信息是明文传输HTTPS 则是具有安全性的 SSL 加密传输协议。 3、HTTP 和 HTTPS 使用的是完全不同的连接方式用的端口也不一样前者是80后者是443。 4、HTTP 的连接很简单是无状态的。HTTPS 协议是由 SSLHTTP 协议构建的可进行加密传输、身份认证的网络协议 比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。 无连接的意思是指通信双方都不长久的维持对方的任何信息。)
三、QT相关知识
1、什么是元对象系统 元对象系统是一个基于标准C的扩展为QT提供了信号与槽机制、实时类型信息、动态属性系统。 元对象系统的三个基本条件:类必须继承自QObject、类声明Q_OBJECT宏(默认私有)、元对象编译器moc。 信号与槽类似观察者模式 回调函数的本质是基于“你想让别人的代码执行你的代码而别人的代码你又不能动”这种产生的 对象树 信号与槽的实现是借助了Qt 的元对象系统元对象系统有一个元对象编译器 程序编译之前会有一个预处理过程预处理将一个类/对象中的信号槽的字符串值分别保存在一个容器中可能是字符串或者其他的有序容器 第5个参数跟线程相关Qt::AutoConnection 1Qt信号槽机制的优势 1类型安全。需要关联的信号和槽的签名必须是等同的 2松散耦合。 3信号和槽机制增强了对象间通信的灵活性。一个信号可以关联多个槽也可以多个信号关联一个槽。 2Qt信号槽机制的不足 同回调函数相比信号和槽机制运行速度有些慢。通过传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢10倍。原因如下 1需要定位接收信号的对象 2安全地遍历所有的关联如一个信号关联多个槽的情况 3编组/解组传递的参数 4多线程的时候信号可能需要排队等待。 然而与创建对象的new操作及删除对象的delete操作相比信号和槽的运行代价只是他们很少的一部分。信号和槽机制导致的这点性能损耗对实时应用程序是可以忽略的。 知道QT事件机制有几种级别的事件过滤吗能大致描述下吗 答根据对Qt事件机制的分析, 我们可以得到5种级别的事件过滤,处理办法. 以功能从弱到强, 排列如下: 1重载特定事件处理函数. 最常见的事件处理办法就是重载象mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数. 2重载event()函数. 通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(象keyPressEvent())处理它. 比如, 当我们想改变tab键的默认动作时,一般要重载这个函数. 在处理一些不常见的事件(比如:LayoutDirectionChange)时,evnet()也很有用,因为这些函数没有相应的特定事件处理函数. 当我们重载event()函数时, 需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件. 3 在Qt对象上安装事件过滤器. 安装事件过滤器有两个步骤: (假设要用A来监视过滤B的事件) 首先调用B的installEventFilter( const QOject *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对象安装任意个数的事件。 自定义界面 UI设计器集成了Qt样式表的编辑功能 前景色color 背景色background-color 选中后颜色selection-color 背景图片background-image 选择器:QPushButton 、QDialog QPushButton、QPushButton#btnOk 子控件:drop-down、up-button、down-button 伪状态:hover(鼠标移动到条目上方时)active(处于活动的窗体) 属性min_width、padding-top、border-width、 1、使用Qt Designer 2、qApp-setStyleSheet(“QLineEdit{ background-color: gray}”); 自定义QT控件 1、自定义Widget子类QmyBattery paintEvent()事件 QmyBattery继承于QWidget Q_UNUSED(event) QPainter/QRect/QColor 提升法 2、自定义Qt Designer插件 编译器用MSVC2015 32bit Q_INTERFACES声明了实现接口 Q_PLUGIN_METADATA声明了元数据名称 要把dll和lib放到插件目录下 D:\Qt\Qt5.9.1\Tools\QtCreator\bin\plugins\designer D:\Qt\Qt5.9.1\5.9.1\msvc2015\plugins\designer QWT,是一个基于LGPL版权协议的开源项目 可生成各种统计图 QT和MFC消息机制比较 mfc的消息机制其实就是消息映射机制程序员需要将自定义消息和对应的处理函数添加到消息映射表中。通过PostMessage和SendMessage来实现异步和同步消息。 QT的信号槽机制是信号和槽函数通过QObject::connect动态链接上后存储到元对象系统中通过emit发送信号对应的槽函数执行。 比较 Qt的信号槽是动态链接的而MFC的消息映射是静态的 Qt的信号支持自定义参数且类型安全 在多线程中MFC需要向已知线程对象发布消息而Qt可以不考虑多线程之间的信号槽关系 总结 Qt相比较MFC的消息机制使用起来更方便最大的优势是Qt支持动态链接信号槽。 四、项目相关 1、定位问题 请问下如果软件除了问题Bug如何快速定位主要方法有哪些 答打印输出/代码调试/日志记录/分析工具/找同事讨论。 1二分法定位技巧 无论是有多复杂的代码利用二分法定位技巧一般都是可以定位到问题所在。 从二分法定位技巧可以延伸出一些具体的处理bug的方法比如对输入数据二分、对代码版本二分、注释掉部分代码、在不同位置插入试探性代码、对运行环境二分。 2IDE调试 IDE的VS debug的功能简直就是立竿见影。它可以加断点单步调试。 单步调试可以让我们对代码逻辑执行顺序以及各种中间结果更加清晰。 至于本身容易出错的BUG用IDE调试简直是再合适不过了。 3重新读一遍程序 相对新手程序员来说如果代码出现bug可以重新读一遍程序。这种方法是最有效、最快速的 Debug 方式。 4必杀重写一遍 如果你发现无论如何也找不到BUG而且代码只是复杂本身不是很长直接重写代码吧! 5小黄鸭调试法 小黄鸭调试法是程序员们经常使用的调试代码方法之一。 小黄鸭不懂程序所以我们可以向他解释每一行程序的作用以此来激发灵感。 内存泄露及解决办法 什么是内存泄露 简单地说就是申请了一块内存空间使用完毕后没有释放掉。1new和malloc申请资源使用后没有用delete和free释放2子类继承父类时父类析构函数不是虚函数。3Windows句柄资源使用后没有释放。 怎么检测 第一良好的编码习惯使用了内存分配的函数一旦使用完毕,要记得使用其相应的函数释放掉。 第二将分配的内存的指针以链表的形式自行管理使用完毕之后从链表中删除程序结束时可检查改链表。 第三使用智能指针。 第四一些常见的工具插件如ccmalloc、Dmalloc、Leaky、Valgrind等等。 数据库相关 什么是事务 并发控制 原子性、一致性、隔离性、持续性 valueChanged(int) QMutex mutex; QMutexLocker locker(mutex); waitForReadyRead() 常用的设计结构 工厂方法 Factory Method 定义了创建对象的接口让子类决定实例化哪个类 单例 Singleton 确保一个类只有一个实例并提供一个访问它的全局访问点 原型 Prototype 通过拷贝原型对象创建新的对象。 适配器 Adapter 将一个类的接口转换成希望的另外一个接口使得原本不兼容的接口可以协同工作。 观察者 Observer 定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。 单例懒汉模式和饿汉模式 饿汉就是类一旦加载就把单例初始化完成保证getInstance的时候单例是已经存在的了线程安全。 而懒汉比较懒只有当调用getInstance的时候才回去初始化这个单例 线程不安全就只有在实例化之前调用的时候加锁后面不加锁。 C新特性主要包括包含语法改进和标准库扩充两个方面主要包括以下11点 语法的改进 1统一的初始化方法允许构造函数或其他函数像参数一样使用初始化列表 2成员变量默认初始化 3类型推导 auto关键字 用于定义变量编译器可以自动判断的类型前提定义一个变量时对其进行初始化 4decltype 求表达式的类型 5智能指针 shared_ptr 6空指针 nullptr原来NULL nullptr表示空指针是一个关键词 NULL是老版本的是一个0的宏 7基于范围的for循环 8右值引用和move语义 让程序员有意识减少进行深拷贝操作 标准库扩充往STL里新加进一些模板类比较好用 9无序容器哈希表 用法和功能同map一模一样区别在于哈希表的效率更高 10正则表达式 可以认为正则表达式实质上是一个字符串该字符串描述了一种特定模式的字符串 11Lambda表达式