字节-编译与性能优化-实习-面试凉经

字节-编译与性能优化-实习-面试凉经

郑州某高校研究生,科研主要是编译优化和数学库相关,一篇中文论文刚投稿,意气风发,投了华为、阿里、字节的岗位,前两者一个在池子里杳无音讯,一个果断被拒,就剩下一个字节给了面试机会,结果凉透了。。。。。

下面是面试的过程:

  1. 一上来,先让自己做自我介绍,然后问一下简历相关的东西,主要是简历上和编译相关的东西,或者说和他们相关的技术问题,别的奖学金啥的,都不问,我的简历上很多都是和技术无关的,至于原因是自己菜还贪玩……

  2. 就是让说一下编译的过程,可以随便用一种语言,c或者java举例,因为我主要接触的是C,就说一了C语言的编译流程,包括预处理、编译、汇编、链接,几个步骤,然后每个步骤大概都有什么。

  3. 然后面试官,就针对这几个步骤,结合我说的一个一个问。就是编译过程中的词法分析、语法分析、语义分析、中间优化、代码生成几个部分,一个一个介绍一下……..emmm,编译的前端一般比较成熟了,就大三学编译的时候学了一点,记住了点名词,剩下的全还回去了,自然回答的是一塌糊涂。还有就是给了一个错误的代码,让说会在那个段报错,类似int a=”string”;其实明显该是语法分析报错呀,emmm,我全给说成语义分析了,emmmm.另外,我在词法分析那提了文法,就让我说一下文法是啥,都有那些类型,怎么区分,我只知道有三种文法,具体的都忘完了,就一直道歉……然后,就说了我自己做的中间优化部分,抽象语法树和我用的调度树,常见的循环优化手段等等,最后就是还问了自动向量化和多线程并行,emmmm,我答的是向量化是个啥,他让我说一下,怎么判断能不能向量化,具体怎么实施,就是说细节,这个只好继续道歉了…….

  4. 然后,让我说得到可执行文件后,执行的时候怎么执行,其实就是链接和装载的过程,还有区别。我当时因为前面答得不好,脑子一片混乱,说的也是错误百出。就是通过一页一页得装载,还说页是cpu和内存得交换的单位,emmmmmm,错的离谱,下来一查,也是虚拟内存和内存交换数据的单位,块是cpu和内存交换的单位,就离了大谱了……….

  5. 最后就是手撕代码,真的和自己写题不一样,别人看着,偶尔还说两下,再加上本来就紧张,真的脑子直接坏掉了,what了,啥都写不出来。题目是一个拓扑排序,当然了,我也是事后诸葛亮,做的时候一脸懵逼。 题目大意是: 有0~n-1个编译命令,[a, b]表示b依赖于a,请设计一个算法给出正确编译的顺序,假设无环。 输入:[2,3]、[3,1]、[0,2]、[0,3] 输出其正确的顺序。 解答方法自行百度吧,提示:是一个图的问题,从出入度判断,去边再判断,拓扑排序

面试后复习的一些知识:

  1. 内联函数与宏定义区别
    (1)内联函数在编译时展开,宏在预编译时展开;
    (2)内联函数直接嵌入到目标代码中,宏是简单的做文本替换;
    (3)内联函数有类型检测、语法判断等功能,而宏没有;
    (4)inline函数是函数,宏不是;
    (5)宏定义时要注意书写(参数要括起来)否则容易出现歧义,内联函数不会产生歧义

  2. 虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

    每个进程创建加载的时候,会被分配一个大小为4G的连续的虚拟地址空间,虚拟的意思就是,其实这个地址空间时不存在的,仅仅是每个进程“认为”自己拥有4G的内存,而实际上,它用了多少空间,操作系统就在磁盘上划出多少空间给它,等到进程真正运行的时候,需要某些数据并且数据不在物理内存中,才会触发缺页异常,进行数据拷贝,更准确一点的说,系统将虚拟内存分割为称为虚拟页(Virtual Page,VP)

    3.进程和线程的关系:
    (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。 (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 (3)处理机分给线程,即真正在处理机上运行的是线程。 (4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.
    进程与线程的区别:
    (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行 (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源. (4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销

    4.虚拟内存和cache区别
    那么我们来看下cache和虚拟内存的区别。
    (1)侧重点不同:cache主要解决主存与CPU的速度差异问题,而虚存主要是解决存储容量问题。
    (2)数据通路不同:CPU与cache和主存之间均有直接访问通路,cache不命中时可直接访问主存;而虚拟内存与CPU之间不存在直接的数据通路,当主存不命中时只能通过调页解决,CPU最终还是通过访问主内存。
    (3)透明性不同:cache的管理完全由硬件完成,对系统程序员和应用程序员均透明2;而虚存管理由软件(操作系统)和硬件共同完成,由于软件的介入,虚存对实现存储管理的系统程序员不透明,而只对应用程序员透明(段式和段页式管理对应用程序员“半透明”)。
    (4)未命中时的损失不同:由于主存的存取时间是cache的存取时间的5~10倍,而主存的存取速度通常比辅存的存取速度快上千倍,故主存未命中时系统的性能损失要远大于cache未命中时的损失

    5.硬盘与内存之间交换数据的单位是页,通过页面置换算法(FIFO、LRU、OPT)确定页,通过页表来判断对应的页在不在内存,不在的引发缺页中断,去硬盘将该页置换到内存中。虚拟内存和物理内存之间通过页表来映射;虚拟地址分为:页号和页内偏移。

    高速缓cache存和内存间交换数据的单位就是缓存行,当线程要访问的变量在CPU的缓存里没有找到时,就会去访问主内存,然后根据程序运行的局部性原理,此时就会把主内存中该变量所在的大小为缓存行的内存放入缓存中。准确的说,主存的一块数据放到cache的一行中,每个数据块和cache的行的大小完全一样, 而且每个块或行都是由若干个连续的字组成的。其中的地址映射,一般有直接映射方式(一些约定的主存块只能复制到cache中的一个特定行中)、全相连映射(主存中任意一个块可以映射到cache中的任意一行中。需要在cache中的一行增加标记部分,存放该行内容的主存块的块号)、组相联映射(组间直接映射,组内全相联映射)。一般来说,全相连映射更适合小容量的cache,直接映射方式适合大容量的cache。而容量不大不小的cache更适用用组相联映射方式。替换策略有:LFU(最不经常使用)、LRU(近期最少使用)、FIFO、随机替换算法。

    CPU与cache之间的数据交换是以字为单位,而cache与主存之间的数据交换是以块为单位。一个块由若干字组成,是定长的。

其他网站链接:https://www.nowcoder.com/discuss/931927?source_id=profile_create_nctrack&channel=-1 (牛客网)

打赏
  • 版权声明: 版权所有属于未央。商业转载,请联系作者(邮箱:sheensong@163.com)以获取授权。 非商业转载,请注明出处并附上原文链接,谢谢配合。

请我喝杯咖啡吧~

支付宝
微信