zoukankan      html  css  js  c++  java
  • 【面试攻略】C++面试基础篇

    基础篇
    1.const *和* const的区别
    如果const修饰在*p前则不能改的是*p,而不是指p;
    如果const是直接写在p前,则p不能改

    举个栗子:

    int i1=30
    int i2=40;

    const int *p = &i1
    p前并没有用const修饰,所以p是指针变量。能被赋值重新指向另一个内存地址。
    p=&i2;        //正确 
    *p=i2;        //错误             

    int * const p
    指针p因为有了const的修饰,所以为指针常量,即,指针p不能修改了。
    p=&i2;              //错误
    *p=i2;                //正确

    说真的把 * const的应用场景非常少,好像我都想不起来我哪里用过。。。


    2.不借助第3个变量交换a和b的值(c语言)

    标准算法
    int a,b; 
    a=10; b=15; 
    int t; 
    t=a; a=b; b=t; 

    算术运算 
    int a,b; 
    a=10;b=12; 
    a=b-a; //a=2;b=12 
    b=b-a; //a=2;b=10 
    a=b+a; //a=12;b=10 

    指针地址操作 
    int *a,*b; //假设 
    *a=new int(10); 
    *b=new int(20); //&a=0x00001000h,&b=0x00001200h 
    a=(int*)(b-a); //&a=0x00000200h,&b=0x00001200h 
    b=(int*)(b-a); //&a=0x00000200h,&b=0x00001000h 
    a=(int*)(b+int(a)); //&a=0x00001200h,&b=0x00001000h 

    位运算 
    int a=10,b=12; //a=1010^b=1100; 
    a=a^b; //a=0110^b=1100; 
    b=a^b; //a=0110^b=1010; 
    a=a^b; //a=1100=12;b=1010; 

    而从实际的软件开发看,标准算法无疑是最好的,能够解决任意类型的交换问题。
    我个人觉得这样的面试毫无意义,谁要是在项目开发的逻辑代码写位运算的方法,我TM想打他一顿,当然如果是封装的接口可以这样写,你写好接口的注释即可,我不关心你实现过程。

    3.进程和线程的区别,进程间通信方法,线程间通信方法
    进程和线程的关系:
    (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
    (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
    (3)处理机分给线程,即真正在处理机上运行的是线程。
    (4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
    (5)线程是指进程内的一个执行单元,也是进程内的可调度实体.

    与进程的区别:

    (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
    (2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
    (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
    (4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。+++

    进程间的通信方式:
    (1).管道(pipe)及有名管道(named pipe):
    管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
    (2).信号(signal):
    信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。
    (3).消息队列(message queue):
    消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。
    (4).共享内存(shared memory):
    可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。
    (5).信号量(semaphore):
    主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。
    (6).套接字(socket);
    这是一种更为常用的进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

    一般我最常用的就是socket,共享内存用过,的确很方便,很效率,但是不能跨越物理机,用于服务器的架构的话不能跨越物理机,承载就形成了瓶颈。其他的我都没用过,

    线程之间的同步通信:
    (1).信号量
    (2).消息队列
    (3).事件event

    4.同步和互斥的区别:
    当 有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中 的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互不相干的任务分 别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。
    所 谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这 个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资 源的访问顺序,即访问是无序的
    所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

    我个人理解:有一个门,如果我进去不出来,其他人不能进,这是互斥;任何人任何时候都能进出,这就是同步。

    5.类和结构体的区别
    在C++中,类中定义的成员变量或成员函数默认都是private属性的,而struct的成员变量或成员函数默认都是public属性的。
    (1).结构体(sturct)是一种值类型,而类(class)是引用类型。区别在于复制方式,值类型的数据是值赋值,引用类型的数据是引用复制。
    (2).结构体使用栈存储(Stack Allocation),而类使用堆存储(Heap Allocation)。  
    如何选择结构体还是类
    (1).堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
    (2).结构体表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构体的成本较低。
    (3).在表现抽象和多级别的对象层次时,类是最好的选择,因为结构体不支持继承
    (4).大多数情况下该类型只是一些数据时,结构体时最佳的选择
    (5).在模板定义中,只能用class 或者typename 而不能用struct

    我个人理解吧,如果类是进程,那么结构体就是线程。实际应用就是,我们创建一个对象用类,对象的各种属性用结构体.

  • 相关阅读:
    CSS 字体
    列表排列
    IE6 fixed 页面抖动
    HTML中css和js链接中的版本号(刷新缓存)
    CSS3 box-shadow
    CSS3的文字阴影—text-shadow
    [LeetCode][JavaScript]Add Digits
    [LeetCode][JavaScript]Max Points on a Line
    [LeetCode][JavaScript]Subsets II
    [LeetCode][JavaScript]Subsets
  • 原文地址:https://www.cnblogs.com/byfei/p/14104086.html
Copyright © 2011-2022 走看看