面试题——蓝

本文详细解释了可重入代码的概念及其重要性,介绍了如何确保代码的可重入性,并列举了进程间及线程间的通信方式。此外,还探讨了volatile关键字的用途、static关键字的作用及与extern的区别,以及一些实用的技术操作。
摘要由CSDN通过智能技术生成

1. 可重入是什么概念?

可重入代码(Reentry code)也叫纯代码(Pure code)是一种允许多个进程同时访问的代码。为了使各进程所执行的代码完全相同,故不允许任何进程对其进行修改。程序在运行过程中可以被打断,并由开始处再次执行,并且在合理的范围内(多次重入,而不造成堆栈溢出等其他问题),程序可以在被打断处继续执行,且执行结果不受影响。

(不应该有全局变量或静态变量,因为这些变量会保存某一个进程的修改。可重入代码中的变量应该都是局部变量,每次重新调用时变量重新被赋值,从而保证,每个进程对它的访问都产生同样的结果。)

void test()
{
  int i;
  i=2;
  printf("%d\n",i );
  i++;
  printf("%d\n",i);
}
结果:每次都是:2 \n 3
void test()
{
  static int i=2;
  printf("%d\n",i );
  i++;
  prinft("%d\n",i);
}
结果:第一次:2 \n 3;第二次:3 \n 4
 

2. 如何确保代码可重入?

若一个程序或子程序可以安全的被并行执行,则称其为 可重入(reentrant或re-entrant)的;即,当该子程序正在运行时,可以再次进入并执行它。
若一个函数是可重入的,则该函数:
不能含有静态(全局)非常量数据。 不能返回静态(全局)非常量数据的地址。 只能处理由调用者提供的数据。 不能依赖于单实例模式资源的锁。 不能调用不可重入的函数。 多 '用户/对象/进程优先级' 以及多进程一般会使得对可重入代码的控制变得复杂。同时,IO代码通常不是可重入的,因为他们依赖于像磁盘这样共享的、单独的资源。
 
3. 进程间通讯方式?线程间通讯方式?
进程间:管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    有名管道 (namedpipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    信号量(semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
    消息队列( messagequeue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    信号 (sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
    共享内存(shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
    套接字(socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
线程间通信可以通过下列三种方法:  1)使用全局变量实现线程间通信  2)使用消息实现线程间通信  3)使用CEvent类实现线程间通信
MFC下常用方法:
1.全局变量  注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化。
2.Message消息机制,常用的Message通信的接口主要有两个:PostMessage为线程向主窗口发送消息。而PostThreadMessage是任意两个线程之间的通信接口。
3.CEvent对象,是MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步。
线程间同步机制:锁机制:包括互斥锁、条件变量、读写锁(或者说 互斥mutex、信号量Semaphore、临界区Critical section)
    互斥锁提供了以排他方式防止数据结构被并发修改的方法。
    读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
    条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
    信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
    信号机制(Signal):类似进程间的信号处理
  线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
 
4. volatile关键词含义?————直接存取原始内存地址
volatile是一个类型 修饰符 (type specifier)。它是被设计用来修饰被不同线程访问和修改的 变量 。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么 编译器 失去大量优化的机会,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
volatile 的作用: 作为指令 关键字 ,确保本条指令不会因 编译器 的优化而省略,且要求每次直接读值.就是防止编译器对代码进行优化
常用于:1)并行设备的硬件寄存器(如:状态寄存器)
    2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 
    3)多线程应用中被几个任务共享的变量
  1).一个参数既可以是const还可以是volatile吗?是的。只读的状态寄存器。是volatile因为它可能被意想不到地改变,是const因为程序不应该试图去修改它。
  2). 一个指针可以是volatile 吗?是的。如:当一个中断服务子程序修改一个指向一个buffer的指针时。
  3). 下面的函数被用来计算某个整数的平方,它能实现预期设计目标吗?   intsquare(volatileint*ptr)   {   return *ptr**ptr;   }
  *ptr的值可能在两次取值语句之间发生改变,因此a和b可能是不同的。结果,这段代码可能返回的不是你所期望的平方值!
 
5. 关键字static作用?与关键字extern的区别?

  1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
  2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
  3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

  (本地化数据和代码范围的好处和重要性)

  extern和static完全不同,static会定义一个变量,extern不能定义一个变量,extern表示的是“已经存在一个变量,但是不在当前的编译单元内,需要在其他编译单元中寻找。
  文件a.c
  static int i;   //只在a文件中用
  int j;            //在工程里用
  static void init(){}  //只在a文件中用
  void callme()          //在工程中用
  {static int sum;}

  上面的全局 i 变量和 init() 函数只能用在a.c文件中,全局变量sum的作用域只在callme里。

  变量j和函数callme()的全局限扩充到整个工程文件。

  所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。

  文件b.c
  extern int j;                //调用a文件里的
  extern void callme();   //调用a文件里的
  int main(){}

    extern的另外用法是当C和C++混合编程时如果c++调用的是c源文件定义的函数或者变量,那么要加extern来告诉编译器用c方式命名函数:

    文件A.cpp调用a.c里面的变量i和函数callme()
    extern "C"  //在c++文件里调用c文件中的变量
    {  int j;  void callme();  }
    int main()
    {  callme();  }
 
6. 查看当前目录下是否存在一个叫abc的文件
  VB——if dir("c:\a.txt")<>"" then  存在 endif
  php——<?php   $filename = '/path/to/foo.txt'; if (file_exists($filename))
      { echo "The file $filename exists"; }
      else { echo "The file $filename does not exist"; } ?> 
  Linux下  ( if access(const char* pathname, F_OK)==0)  存在 ( F_OK文件是否存在   R_OK读权限   W_OK写权限   X_OK执行权限
       ( if opendir(const char* pathname)==0)  存在(不存在 NULL)
      find -name "$(date +%F)*" -exec mv {} ./history \;发现当前目录下有用当天日期为文件名的文件,即做MV
  C++  #include <iostream>  #include <fstream>  using namespace std;  #define FILENAME "stat.dat"
        int main(){     fstream _file;     _file.open(FILENAME,ios::in);     
          if(!_file)     {  cout<<FILENAME<<"没有被创建";  }
             else  {  cout<<FILENAME<<"已经存在";}  return 0;  } 
  C语言  #include  <io.h>  #include  <stdio.h>  #include  <stdlib.h>
        void main( void ) { if( (_access( "ACCESS.C", 0 )) != -1 ) { printf( "File ACCESS.C exists " );    
                   if(   (_access( "ACCESS.C", 2 )) != -1 )      printf( "File ACCESS.C has write permission " );   }  }
 
7. 嵌入式系统常对寄存器或变量进行位操作,给定一个整形变量value,设置value的bit 3,清除value的bit 3,以上操作保持其它位不变
  value |=0x01<<3  ;  value &=-(0x01<<3)
 
8. 嵌入式系统访问某特定内存位置,32位机要求设置一绝对地址为0x000067a9的整形变量值为0xaa66,代码完成
  若这个地址是代码段(方法)位置,且已知函数为void型,无参,如何调用?
  1) int* p;  p=0x000067a9;  *p=0xaa66  2)  void (*p)();声明  p=0x000067a9;定义  *p();调用
 
 

转载于:https://www.cnblogs.com/qq1129496211/p/4072218.html

### 回答1: 好的,下面是对大数据面试题——spark面试题(一)的回答: 1. 什么是Spark?它与Hadoop有什么区别? Spark是一个快速、通用、可扩展的大数据处理引擎,它可以在内存中进行数据处理,因此比Hadoop更快。与Hadoop相比,Spark的优点在于它可以在内存中进行数据处理,因此速度更快,而且它支持更多的数据处理方式,例如流处理、图形处理等。 2. Spark的核心组件有哪些? Spark的核心组件包括Spark Core、Spark SQL、Spark Streaming、MLlib和GraphX。 3. 什么是RDD?它有哪些特点? RDD是Spark中的一个基本概念,它代表一个不可变的分布式数据集合。RDD具有以下特点: - 可以在内存中进行计算,因此速度快; - 支持多种操作,例如map、reduce、filter等; - 可以进行持久化,以便在后续计算中重复使用。 4. Spark中的map和flatMap有什么区别? map和flatMap都是RDD中的转换操作,它们的区别在于: - map操作对每个元素进行转换,返回一个新的元素; - flatMap操作对每个元素进行转换,返回一个包含多个元素的序列。 5. 什么是Spark的shuffle操作? Spark的shuffle操作是指将数据重新分区的操作,它通常发生在reduce操作之前。Shuffle操作会将数据从多个节点上收集到一个节点上,然后重新分区,以便进行后续的计算。 6. Spark中的cache和persist有什么区别? cache和persist都是将RDD持久化到内存中,以便在后续计算中重复使用。它们的区别在于: - cache操作默认将数据持久化到内存中,而persist操作可以指定将数据持久化到内存、磁盘或者其他存储介质中; - cache操作是persist操作的一种简化形式,它默认将数据持久化到内存中,并且只能持久化到内存中。 7. Spark中的reduceByKey和groupByKey有什么区别? reduceByKey和groupByKey都是对键值对RDD进行操作的函数,它们的区别在于: - reduceByKey操作会在每个分区内先进行本地聚合,然后再进行全局聚合,因此效率更高; - groupByKey操作会将所有的键值对都进行网络传输,然后在一个节点上进行聚合,因此效率较低。 8. Spark中的broadcast变量有什么作用? broadcast变量是一种只读的变量,它可以在所有节点上共享,以便在计算过程中使用。使用broadcast变量可以避免在网络上传输大量的数据,从而提高计算效率。 9. 什么是Spark的checkpoint操作? Spark的checkpoint操作是将RDD持久化到磁盘上,以便在后续计算中重复使用。与cache和persist不同的是,checkpoint操作会将数据持久化到磁盘上,以便在内存不足时可以从磁盘上恢复数据。 10. Spark中的Task是什么? Task是Spark中的一个基本概念,它代表一个可以在一个节点上行的计算任务。Spark将一个RDD分成多个分区,每个分区对应一个Task,这些Task可以并行行,以提高计算效率。 ### 回答2: 今天我们来讨论一下关于Spark大数据面试的一些常见问题。Spark是一种基于Hadoop的开源计算系统,它能够快速处理大规模数据,并且支持多种编程语言,包括Java、Scala和Python等。以下是一些Spark面试题及其答案: 1. Spark有哪几种部署模式? Spark有三种部署模式,分别是本地模式、集群模式和分布式模式。本地模式指的是在本地运行Spark应用程序,不需要连接到外部计算机。集群模式指的是单个Spark集群环境,它由一组Spark节点组成,可以在数据中心或云中运行。分布式模式指的是使用多个Spark集群并行处理大规模数据。 2. Spark和Hadoop的区别是什么? Spark和Hadoop都是处理大规模数据的工具,但它们有一些区别。首先,Spark处理数据速度快,因为它将数据存储在内存中,而Hadoop则将数据存储在磁盘中。其次,Spark支持更多的编程语言,包括Java、Scala和Python等,而Hadoop只支持Java。此外,Spark具有更好的机器学习和图形处理功能,可以更好地支持大规模数据分析。 3. Spark的RDD是什么? RDD是Spark中重要的概念,全称为Resilient Distributed Dataset。它是一个不可变的分布式数据集合,可以分区存储在不同节点上,并且每个分区都可以在并行处理中进行处理。RDD支持两种操作,即转化操作和行动操作。转化操作将一个RDD转换为另一个RDD,而行动操作返回一个结果或将结果输出至外部系统。 4. Spark的优化技术有哪些? Spark优化技术包括数据本地化、共享变量、宽依赖和窄依赖、缓存和持久化,以及数据分区等技术。数据本地化将数据存储在尽可能接近计算节点的位置,以减少网络传输的开销。共享变量将常用的变量通过广播或累加器的方式在节点中共享,从而减少网络传输量。宽依赖和窄依赖指的是在转化操作中RDD之间的依赖关系,窄依赖表示每个父分区最多与一个子分区有关联,而宽依赖则表示多个子分区可能与多个父分区关联。缓存和持久化技术可将RDD保存在内存中,从而加速访问速度。数据分区可以将数据划分为较小的块进行并行处理。 5. Spark Streaming是什么? Spark Streaming是Spark的一个扩展模块,它支持实时数据流处理。Spark Streaming可以将实时数据流以微批次方式处理,每个批次的数据处理平均耗时只有几秒钟。Spark Streaming可以将数据存储在内存或磁盘中,同时支持多种数据源和数据输出方式。 以上是关于Spark大数据面试题的一些回答,希望能够对大家有所帮助。如果你想深入学习Spark和大数据处理技术,可以考虑参加相关的培训课程或在线课程。 ### 回答3: Spark是一个分布式计算框架,它可以使大规模数据处理更加高效和便捷。因此,在企业招聘大数据领域的人才时,对Spark的技术能力要求越来越高。以下是Spark面试题的回答: 1. Spark有哪些组件? Spark框架由三个核心组件组成:Spark Core、Spark SQL和Spark Streaming。此外,还有Spark MLlib、Spark GraphX、Spark R等个别不同的子组件。 2. 什么是RDD?与Dataframe有什么区别? RDD(弹性分布式数据集)是Spark的核心数据抽象,是不可变的分布式对象集合。RDD可以从文件中读取数据、从内存中读取数据、并行修改数据等。而Dataframe和RDD类似,但是Dataframe更加强大,因为它是带有结构化的RDD。Dataframe在处理大规模结构化数据时非常有效和便捷。 3. Spark如何处理缺失数据? Spark提供了两种处理缺失数据的方法:第一种是使用DataFrame API中的na函数,可以删除或替换缺失值;第二种是使用MLlib中的Imputer类,可以将缺失值替换为均值或中位数。 4. 什么是Spark的任务(task)? 一个任务是Spark作业中的最小行单位。Spark集群上的作业被划分为多个任务,这些任务可以并行行。 5. Spark的shuffle操作是什么?它为什么是昂贵的? Spark的shuffle操作是将一组数据重新分配到不同计算节点上的操作。Shuffle操作可能会导致大量数据的磁盘写入、网络传输和数据重组,这些都是非常昂贵的操作。因此,它在Spark集群中是一个相当昂贵的操作。 6. Spark中的Partition有什么作用? Partition是Spark中的数据划分单位。它可以将数据分成多个块并对每个块进行处理。Partition 可以提高 Spark 的并行度和运行效率,因为它可以将大规模数据分成多个小块,并在集群的多个计算节点上并行处理数据。 总而言之,Spark是大数据领域中使用最广泛的计算引擎之一,其技术理念和应用场景非常广泛。对于求职者而言,掌握 Spark 的基本概念和技术特点,提高对 Spark 的理解和应用能力,将有助于更好地处理和分析大规模数据集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值