• 杭州天丽笔试题


    1.volatile关键字的作用,举三个应用实例。

    一般说来,volatile用在如下的几个地方:

    1、中断服务程序中修改的供其它程序检测的变量需要加volatile

    2、多任务环境下各任务间共享的标志应该加volatile

    3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义;

    2.定义一个返回值和参数都是函数指针的函数

    typedef void (*p)(void)

    p func(p p1);

    或是:void (*) (void)  func( void (*) (void))

    void (*func(void (*p) (void))(void);

    3.内存中的大小端模式?

    大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

    小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

    4.排序算法有哪几种?用C实现冒泡排序

    void sort(int arr[],int size){

    //1.外层循环控制比较的轮数

    //2.内层循环控制每轮比较的下标范围

    int i=0,j=0;

    for(i=0;i<size-1;i++){

    for(j=0;j<size-i-1;j++){

        if(arr[j]>arr[j+1]){

          int temp=arr[j];

          arr[j]=arr[j+1];

          arr[j+1]=temp;

    }

    }

    }

    }

    常用的排序算法

    2.1冒泡排序

    相邻位置之间元素的比较

    1)算法流程

    a.比较相邻位置的元素,如果左边的比右边的大,则交换两个元素的位置

    b.针对每一对相邻位置的元素都重复上一步,从第一对到最后一对比较完毕

    经过这一步,最后的元素就是这组数中的最大值

    c.针对所有的元素重复以上步骤,每次对越来越少的元素进行比较,直到没有

    可以交换的元素为止

    2)算法评价

    平均时间复杂度o(n^2),稳定,对样本的有序性比较敏感

    2.2插入排序

    1)算法的流程

    a.从第一个元素起,假定这个元素已经有序

    b.从第二个元素起,与已经有序的元素从后向前进行比较

    c.如果左边的元素大于取出的元素,则将左边的元素赋值到下一个位置上

    继续与有序的元素进行比较

    d.如果左边的元素小于取出的元素,则将取出的元素插入到左边元素之后

    e.重复以上步骤,直到处理完所有的元素

    2)算法评价

    平均时间复杂度o(n^2),稳定,对样本的有序性比较敏感,但是赋值的次数

    比冒泡排序少,所以略优于冒泡排序

    2.3选择排序算法

    1)算法的流程

    a.从第一数起依次取出所有元素,假定取出的元素是最小值,记录下标

    b.使用假定的最小元素和后续元素依次进行比较,如果后续元素中有比

    假定最小元素还小的元素,则重新记录下标,后续元素成为了假定的最小数

    c.直到假定的最小元素和后续所有元素比较完毕,交互最新的最小元素和

    开始假定的最小元素

    d.重复上述过程,直到所有元素排序完毕

    2)算法评价

    平均时间复杂度o(n^2),不稳定,对样本的有序性不敏感,比较的次数的比较多

    交换的次数比较少,一般情况下略优于冒泡排序

    2.4快速排序

    1)算法的流程

    a.选择一个中间元素作为基准值,单独存储起来

    b.依次分别使用左边元素和右边元素和基准值比较,将比基准值小的元素放在左边

    将比基准值大或者相等的元素放在右边,

    c.重复以上过程,直到两边元素的下标重合为止,将基准值放到重合的位置上,此时

    比基准值小的元素已经到了基准值左边,比基准值大的元素已经在基准值的右边

    d.用递归的方式对基准值左边和右边的元素分别进行分组排序

    2)算法评价

    平均时间复杂度o(NlogN)不稳定,如果每次分配都能做到均匀划分,这种情况的排序速度最快

    5.ISR中断服务子程序的错误:

        ISR不能有返回值;

        ISR不能传递参数;

        ISR应该是短而高效的,在ISR中做浮点运算是不明智的;

        ISR中不应该有重入和性能上的问题,因此不应该使用printf()函数。

    __interrupt double compute_area (double radius) 

    {

        double area = PI * radius * radius;

        printf(" Area = %f", area);

        return area;

    }

    1)  ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。

    2)  ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。

    3)  在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额外的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。

    此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。

    4) 与第三点一脉相承,printf经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。

    6.while(1) ,for(; ;),goto死循环用哪个?为什么

    一般for(;;)性能更优

    for(;;)  

    {}  

    这两个;; 空语句,编译器一般会优掉的,直接进入死循环

    while(1)  

    {}  

    每循环一次都要判断常量1是不是等于零,在这里whilefor多做了这点事

    不过从汇编的角度来说,都是一样的代码。

    goto语句通常不用,主要因为它将使程序层次不清,且不易读,但在多层嵌套退出时,用goto语句则比较合理。

    7.抢占式内核和非抢占式内核?

    内核抢占(可抢占式内核):

    即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程。

    非抢占式内核:

    高优先级的进程不能中止正在内核中运行的低优先级的进程而抢占CPU运行。进程一旦处于核心态(例如用户进程执行系统调用),则除非进程自愿放弃CPU,否则该进程将一直运行下去,直至完成或退出内核。

    抢占式内核的意义:

    首先,这是将Linux应用于实时系统所必需的。实时系统对响应时间有严格的限定,当一个实时进程被实时设备的硬件中断唤醒后,它应在限定的时间内被调度执行。而Linux不能满足这一要求,因为Linux的内核是不可抢占的,不能确定系统在内核中的停留时间。事实上当内核执行长的系统调用时,实时进程要等到内核中运行的进程退出内核才能被调度,由此产生的响应延迟,在如今的硬件条件下,会长达100ms级。这对于那些要求高实时响应的系统是不能接受的。而可抢占的内核不仅对Linux的实时应用至关重要,而且能解决Linux对多媒体(video, audio)等要求低延迟的应用支持不够好的缺陷。

  • 相关阅读:
    阿里笔试题—战报交流
    2 基于梯度的攻击——PGD
    1 基于梯度的攻击——FGSM
    0 对抗样本
    自然语言处理 复习笔记 3
    自然语言处理 复习笔记 2
    自然语言处理 复习笔记 1
    GRU
    1*1卷积核的作用
    BP原理
  • 原文地址:https://www.cnblogs.com/guozhijiang/p/4821757.html
Copyright © 2020-2023  润新知