Java面试问题集锦之操作系统02

13. Linux32位系统,应用程序最多能分配的内存大小?

32位linux不打开PAE,则最多只能识别出4GB内存,若打开PAE,则最多可以识别出64GB内存。但是 32位系统下的进程一次最多只能寻址4GB的空间。

PAE:物理地址扩展

14. sleep和wait的区别?

  • sleep方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁);
  • wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);

15. 什么是临界资源?什么是临界区?

  • 临界资源:把一次只允许一个进程使用的资源成为临界资源。(独占性,如打印机,卡片输出机等)
  • 临界区:把每个进程中访问临界资源的那段代码从概念上分离出来,将其称为临界区。即临界区是指对临界资源实时操作的程序的代码段。
  • 相关临界区:并发进程中涉及相同临界资源的临界区。相关临界区必须互斥执行。

16. 什么是进程互斥?

  • 进程互斥是解决进程间竞争关系(间接制约关系)的手段。指任何时刻不允许两个以上的共享该资源的并发进程同时进入临界区,这种现象称为互斥。
  • 相关临界区的管理原则:互斥、空闲让进、有限等待。

17. 进程同步的概念?

进程同步指两个或多个进程为了合作完成同一个任务,在执行速度或某些确定的时序点上必须相互协调,即一个进程的执行依赖于另一个进程的消息,当一个进程到达了某一个确定点而没有得到合作伙伴发来的已完成消息时必须等待,知道该消息到达被唤醒后,才能继续向前推进。

18. 进程同步和互斥的关系?

  • 进程的互斥实际上是进程同步的一种特殊情况,即主次使用互斥共享资源,也是对进程使用资源次序上的一种协调。进程的互斥和同步统称为进程同步。
  • 进程的互斥是进程间共享资源的使用权,这种竞争没有固定的必然联系,哪个进程竞争到资源的使用权,该资源就归哪个进程使用,直到它不再需要使用时才归还资源;而进程同步中,所涉及的共享资源的并发进程间有一种必然的联系,当进程必须同步时,即使无进程在使用共享资源,尚未得到同步消息的进程也不能去使用该资源。

19. 信号量机制(PV操作)

信号量机制的实现原理是两个或多个进程可以利用彼此间收发的简单信号来实现正确的并发执行,一个进程在收到一个指令信号前,会被迫在一个确定的或者需要的地方停下来,从而保持同步或互斥。

20. 同步的实现机制

  • 临界区:通过多线程的串行化来访问公共资源或者一段代码,速度快,适合控制数据访问。
  • 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以可以保证公共资源不会同时被多个线程访问。
  • 信号量:允许多个线程同时访问同一资源,但是需要限制同一时刻访问此资源的最大线程数目。信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统PV操作相似。
  • 事件(信号):通过通知操作的方式保持多线程同步,还可以方便的实现多线程的优先级比较的操作。

21. 经典的同步问题

  • 生产者消费者问题
  • 读者-写者问题(读者优先:信号量+读进程计数器rc;弱写者优先:信号量+读进程计数器rc+排队信号量read;强写者优先:信号量+读进程计数器rc+排队信号量read+写优先信号量write_first)
  • 哲学家就餐问题:是在多个线程之间共享多个资源时会不会导致死锁或饥饿的典型模型。解决方案:i. 每个哲学家取得手边的两个叉子才能吃面,即仅当一个哲学家左右两边的叉子都可用时,才允许他拿叉子,否则一个叉子也不取。ii. 偶数号哲学家先取手边的叉子,奇数号哲学家先取右手边的叉子。
  • 嗜睡理发师问题

22. 进程通信的方式

  • 共享存储:消息缓冲
  • 消息传递:信箱
  • 管道通信

23. 产生死锁的条件

  • 互斥条件:同时只能有一个进程持有资源
  • 请求和保持条件:一个进程请求资源得不到满足时,不释放占有的资源
  • 不剥夺条件:任何一个进程不能抢夺其他进程占有的资源
  • 循环等待条件:存在一个循环等待链,链中每个进程已获得资源,并分别等待前一个进程持有的资源。

24. 处理死锁的方法

  • 死锁预防:破坏产生死锁条件的任何一个或多个,如静态资源分配策略(2)和按序分配资源策略(4)。
  • 死锁避免:采用银行家算法,每次分配都查看能否找到一种资源分配方法,使得已有的进程可以顺利完成任务,如果有,则分配,否则不分配。
  • 死锁检测和解除:用软件来检查有进程和资源构成的有向图是否存在一个或多个回路。

25. 分页和分段的区别

  • 分页是信息的物理单位,与源程序的逻辑结构无关,用户不可见,分页的目的主要是为了减少碎片,提高主存的利用率。分段是信息的逻辑单位,由源程序的逻辑结构来决定,目的是更好地满足用户的需求。
  • 的大小固定且由系统确定,而的长度不固定,由用户程序决定。
  • 分页的作业地址空间是一维的(线性地址空间),分段的作业地址空间是二维的(段名和段内地址)

26. 缓存的局部性原理

根据研究,在较短的时间内,程序的执行会局限于某一个部分,则可以根据当前程序运行的位置,推测可能执行的程序,预先加载,来达到缓存的目的。(虚拟内存的实现)

27. 同步和异步有什么不同?

  • 同步,就是说你的程序在执行某一个操作时一直等待直到操作完成。最常见的例子就是 SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的 RESULT值返回给调用者。
  • 异步,就是说程序在执行某一个操作时,只是发出开始的指令;由另外的并行程序执行这段代码,当完成时再通知调用者。当一个客户端通过调用Connect函数发出一个连接请求后,调用者线程立刻可以朝下运行。当连接真正建立起来以后,socket底层会发送一个消息通知该对象。

28. 什么是线程?有哪些状态?

一个线程是进程的一个顺序执行流。同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈。线程在切换时负荷小,因此,线程也被称为轻负荷进程。一个进程中可以包含多个线程。

状态如下:

  • 新建状态:新建线程对象,并没有调用start()方法之前
  • 就绪状态:调用start()方法之后线程就进入就绪状态,但是并不是说只要调用start()方法线程就马上变为当前线程,在变为当前线程之前都是为就绪状态。值得一提的是,线程在睡眠和挂起中恢复的时候也会进入就绪状态哦。
  • 运行状态:线程被设置为当前线程,开始执行run()方法。就是线程进入运行状态
  • 阻塞状态:线程被暂停,比如说调用sleep()方法后线程就进入阻塞状态
  • 死亡状态:线程执行结束

29. synchronized和Lock的异同?

类别 synchronized Lock
存在层次 Java的关键字,在jvm层面上 是一个类
锁的释放 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 在finally中必须释放锁,不然容易造成线程死锁
锁的获取 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 分情况而定,Lock有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待
锁状态 无法判断 可以判断
锁类型 可重入 不可中断 非公平 可重入 可判断 可公平(两者皆可)
性能 少量同步 大量同步

30. 什么是序列化?什么是串行化?

把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

对象的序列化主要有两种用途:

  • 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  • 在网络上传送对象的字节序列。

串行化和并行化

  • 串行化也叫做序列化,就是把存在于内存的对象数据转化成可以保存成硬盘文件的形式去存储;
  • 并行化也叫反序列化,就是把序列化后的硬盘文件加载到内存,重新变成对象数据。 也就是把内存中对象数据变成硬盘文件.

31. 什么是守护线程与用户线程 ?举一个守护线程的例子

  • 用户线程:我们平常创建的普通线程。
  • 守护线程:用来服务于用户线程;不需要上层逻辑介入。

当主线程结束时,结束其余的子线程(守护线程)自动关闭,就免去了还要继续关闭子线程的麻烦。如:Java垃圾回收线程就是一个典型的守护线程;内存资源或者线程的管理,但是非守护线程也可以。

32. synchronized关键字的用法

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
分享到