• 面试题-01


    1、虚拟内存与物理内存的关系;
            虚拟内存是一种实现在计算机软硬件之间的内存管理技术,它将程序使用到的内存地址(虚拟地址)映射到计算机内存中的物理地址,虚拟内存使得应用程序从繁琐的管理内存空间任务中解放出来,提高了内存隔离带来的安全性,虚拟内存地址通常是连续的地址空间,由操作系统的内存管理模块控制,在触发缺页中断时利用分页技术将实际的物理内存分配给虚拟内存,而且64位机器虚拟内存的空间大小远超出实际物理内存的大小,使得进程可以使用比物理内存大小更多的内存空间。

    2、代码是被加载到虚拟内存里运行,谁加载?谁运行?该虚拟内存分为几个部分(内核区、不可访问区域);

            1. 代码段

                    存储程序的机器指令,这段区域的内存一般可读可执行,但不可写

            2. 数据段

                    ① 存储程序中已经初始化且不为0的全局变量和静态变量

                    ② 这些变量的初值会存储在程序编译后的二进制文件中,然后被加载到内存中

            3. BSS(Block Started by Symbol)段

                    ① 存储程序中未初始化或初始化为0的全局变量和静态变量

                    ② 由于他们的初值为0,因此不需要在程序编译后的二进制文件中存储那么多0,只需要记录他们的起止地址即可

                    ③ 操作系统在加载程序时,会根据记录的BSS段起止地址初始化相应的内存区域

                    ④ BSS除了Block Started by Symbol,从功能上也可以理解为Better Save Space

            4. 堆 & 栈

            堆空间和栈空间不是从磁盘上加载,而是在程序运行过程中申请的内存空间

            说明1:Linux 0.11内核支持的a.out文件格式与内存布局,就是如上图所示

            说明2:现代应用程序除了上面的内存段,还会包含如下内存区域

            ① 存放加载的共享库的内存空间

            如果一个进程使用共享库(动态库),该共享库的代码段、数据段和BSS段也需要被加载到进程的地址空间中

            ② 共享内存段

            可以通过系统调用映射一块匿名内存作为共享内存,用来进行进程间通信

            ③ 内存映射文件

            可以将磁盘上的文件映射到内存中,用来进行文件编辑或以类似共享内存的方式进行进程间通信

            

     


    3、全局变量定义后不赋值会直接被初始化为0,为什么?空间是在哪部分配的?
        int a; 会被直接初始化为0,是因为直接在.bss段分配的空间,该空间已被系统初始化为0。
        int b = 10; 变量的空间是在.data段中分配;

    4、static 关键字修饰的(全局或局部)变量的空间是在哪部分配的? (static 关键字 作用: 隐藏、续命)
        全局变量默认带有static修饰(对吗?),就是是否赋值,分配到具体的空间里(.bss ,  .data)
        局部变量在定义时设置为static修饰,空间在数据段中,该变量只会被定义初始化一次,且空间会在代码结束后才被系统回收。

    5、宏与typedef、内联函数的各自区别
        宏可以用文本代替其他任意标识符 , typedef只能对有效的数据类型取别名; 内联函数是用关键字inline函数,本身是函数,编译器会检查该函数的语法是否正确;
        #define P 1 (对的)
        #define while 1 (错的)

    6、volatile关键字的作用
        volatile关键字用于告诉编译器不作变量的优化:实质是指定cpu每次读取的值是从内存中读取实际的值,而不是读取cpu寄存器中的值。
        
    7、unsigned int a = -1; int b = 1; if(a>b)(printf("%d",a)):(printf("%d",b));输出结果?
            当执行运算时,如果其中一个运算数是有符号的,另一个是没有符号的,C语言会隐式的将有符号的运算数强制转为无符号,并且假设两个数都是非负的来执行运算。在32位和64位的计算机里面-1就是二进制的1111 1111 1111 1111 1111 1111 1111 1111转为十进制就是 4 294 967 295 就是32位无符号的最大值,所以输出结果就是-1;

    8、for(;;); 与 while(1);的不同;
            for()的执行效率要高于while(),通过汇编代码可以查看到,for()对于一条汇编指令,但是while()对于4条汇编指令;

     

  • 相关阅读:
    Leetcode刷题方法总结---字符串全解
    vue3在子组件中触发的父组件函数方式
    类的内部工作机制就是原型操作
    安卓开发-基础知识补习10
    提高开发生产力 - 生产力指南篇(之一)
    【VTK+有限元后处理】实时剖切视图
    【JavaScript】一文了解事件对象
    数字城市:科技革命下的未来之城
    codeforces每日5题(均1600)-第二十九天
    制作一个简单HTML公司官网网页设计(HTML+CSS)
  • 原文地址:https://blog.csdn.net/weixin_48102054/article/details/127756239