一个关于fork()的面试题思路和扩展

京东Linux后台开发面经汇总:高频考点与题解思路 Linux后台开发岗位的核心能力在于对操作系统原理、网络编程与高并发场景的深刻理解。从进程线程调度、内存管理到IO模型,每一个基础概念都直接决定线上问题排查的效率和系统设计的可靠性。掌握这些原理不仅能应对技术面试中的深度追问,也是构建高性能服务的关键。在实际工程中,如何利用文本处理工具分析海量日志、如何通过epoll模型支撑高并发连接、如何通过MySQL索引优化查询性能,都是后台工程师的必备技能。本文汇总京东Linux后台开发面试中的高频考点,覆盖命令实战、系统原理、数据库与中间件、算法与系统设计等,帮助读 阅读详情

题目:请问下面的程序一共输出多少个“-”?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
   int i;
   for(i=0; i<2; i++){
      fork();
      printf("-");
   }

   return 0;
}

如果你对fork()的机制比较熟悉的话,这个题并不难,输出应该是6个“-”,但是,实际上这个程序会很tricky地输出8个“-”。

要讲清这个题,我们首先需要知道fork()系统调用的特性,

  • fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid),这是众为周知的。
  • 还有一个很重要的东西是,在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。

所以,上面的那个程序为什么会输入8个“-”,这是因为printf(“-”);语句有buffer,所以,对于上述程序,printf(“-”);把“-”放到了缓存中,并没有真正的输出(参看《<a title="C语言的谜题" target="_blank" href="http://www.kuqin.com/language/20090531/54105.html" "="" style="color: rgb(128, 0, 128); text-decoration: none; outline-style: none;">C语言的迷题》中的第一题),在fork的时候,缓存被复制到了子进程空间,所以,就多了两个,就成了8个,而不是6个。

另外,多说一下,我们知道,Unix下的设备有“块设备”和“字符设备”的概念,所谓块设备,就是以一块一块的数据存取的设备,字符设备是一次存取一个字符的设备。磁盘、内存都是块设备,字符设备如键盘和串口。块设备一般都有缓存,而字符设备一般都没有缓存。

对于上面的问题,我们如果修改一下上面的printf的那条语句为:

printf("-n");

或是

 printf("-");
fflush(stdout);

就没有问题了(就是6个“-”了),因为程序遇到“n”,或是EOF,或是缓中区满,或是文件描述符关闭,或是主动flush,或是程序退出,就会把数据刷出缓冲区。需要注意的是,标准输出是行缓冲,所以遇到“n”的时候会刷出缓冲区,但对于磁盘这个块设备来说,“n”并不会引起缓冲区刷出的动作,那是全缓冲,你可以使用setvbuf来设置缓冲区大小,或是用fflush刷缓存。

我估计有些朋友可能对于fork()还不是很了解,那么我们把上面的程序改成下面这样:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
   int i;
   for(i=0; i<2; i++){
      fork();
      //注意:下面的printf有“n”
      printf("ppid=%d, pid=%d, i=%d n", getppid(), getpid(), i);
   }
   sleep(10); //让进程停留十秒,这样我们可以用pstree查看一下进程树
   return 0;
}

于是,上面这段程序会输出下面的结果,(注:编译出的可执行的程序名为fork)

ppid=8858, pid=8518, i=0
ppid=8858, pid=8518, i=1
ppid=8518, pid=8519, i=0
ppid=8518, pid=8519, i=1
ppid=8518, pid=8520, i=1
ppid=8519, pid=8521, i=1

$ pstree -p | grep fork
|-bash(8858)-+-fork(8518)-+-fork(8519)---fork(8521)
|            |            `-fork(8520)

面对这样的图你可能还是看不懂,没事,我好事做到底,画个图给你看看:

注意:上图中的我用了几个色彩,相同颜色的是同一个进程。于是,我们的pstree的图示就可以成为下面这个样子:(下图中的颜色与上图对应)

这样,对于printf(“-”);这个语句,我们就可以很清楚的知道,哪个子进程复制了父进程标准输出缓中区里的的内容,而导致了多次输出了。(如下图所示,就是我阴影并双边框了那两个子进程)

Java Arrays.sort()排序全解析:从升序降序到多级排序与性能优化 在Java编程中,排序是数据处理的基础操作,其核心在于比较逻辑与算法效率。Java通过Arrays.sort()方法为数组排序提供了统一入口,但其底层实现根据数据类型分为两大分支:对基本类型数组采用优化的双轴快速排序(Dual-Pivot Quicksort)以追求极致速度;对对象数组则使用稳定的TimSort算法,并依赖Comparable与Comparator接口实现灵活的比较规则。这种设计在工程实践中至关重要,它允许开发者通过Comparator轻松定义降序、多字段排序等复杂逻辑,并利用其链式调用(t 阅读详情

相关推荐

C++ exit()函数详解:进程终止机制与退出码设计

exit()是C++中用于进程级终止的关键标准库函数,其核心原理在于触发标准化清理流程(缓冲区刷新、atexit函数调用、静态对象析构),并返回整型状态码供父进程解析。它区别于return(函数级控制流)和abort(无清理强制中止),在Docker容器管理、Gradle构建、LLaMA-Server服务启停等现代工具链中承担着‘心跳信令’角色。技术价值体现在可控性、可预测性与跨平台兼容性,广泛应用于命令行工具错误处理、嵌入式服务优雅退出及CI/CD流水线状态反馈场景。本文深入剖析exit()的语义约定、s

weixin_30729609的博客 358

操作系统习题 进程树 运行结果

main() { int p1,p2,p3,p4,p5,pp1,pp2; printf(“程序开始执行”); if ((p1=fork( )== 0){ printf(“进程proc1执行”); exit(1); } else if ((p2=fork() )== 0){ printf(“进程proc2执行”); ...

u014438295的博客 2032

拼多多Android面试题及参考答案

Android 系统采用分层架构设计,从底层到上层依次为Linux 内核层硬件抽象层(HAL)系统运行时库层应用框架层应用层,共五层。位置:Linux 内核层与系统运行时库层之间,是“硬件与系统的隔离层”。核心作用:屏蔽硬件差异,为上层提供统一的硬件访问接口,解决 Android 开源与硬件厂商闭源的矛盾,具体功能如下:硬件能力抽象:将硬件的具体实现(如不同厂商的摄像头芯片、音频芯片)封装为标准化接口(如Camera HALAudio HAL。

大模型大数据攻城狮的专栏 1284

Fork函数

在学习fork 函数的时候觉得特别有意思,就写下来和大家分享。 1、创建新进程:pid_t fork(void) 获得ID号: pid ——–pid_t getpid();   ppid——–pid_t getppid(); fork 函数调用一次,返回2次(返回2个值) (就像女人结一次婚就可能会得到丈夫

Lyt15829797751的博客 2229

2026年诺瓦星云嵌入式面试题82道带详细答案

摘要 本文系统整理了嵌入式开发工程师面试中的技术要点,涵盖硬件外设、通信协议、电路设计、单片机架构、编程基础、数据结构、操作系统、Linux开发、网络协议及项目协作等九大模块。重点解析了SPI、I2C、UART三种通信协议的核心差异与应用场景(如SPI适用于高速外设,I2C适合低速传感器,UART用于调试透传),详细说明了ADC类型、DMA配置、RTC中断等硬件关键技术,并探讨了PID控制、蓝牙通信等实用方案。同时包含C语言static关键字、链表/数组区别、死锁处理等软件基础,以及交叉编译、TCP/UDP

Open 52

告别交越失真:手把手教你设计高性能互补输出级电路(LTspice实测)

本文深入剖析音频放大器中常见的交越失真问题,并提供基于LTspice仿真的实战解决方案。通过对比二极管偏置、Vbe倍增器和集成运放驱动三种经典方案,手把手指导设计高性能互补输出级电路,涵盖原理分析、仿真验证及实物调试要点,助力消除音频失真,提升音质。

weixin_29190573的博客 552

Linux中的fork()函数的面试题目

(1)fork 以后,父进程打开的文件指针位置在子进程里面是否一样?(先open再fork) (2)能否用代码简单的验证一下? (3)先fork再打开文件父子进程是否共享偏移量?父进程打开的文件指针位置在子进程里面是否一样?能否用代码简单验证一下.(先fork再open会怎么样?) 5).malloc和free的三个问题: 思考下面三个问题: (1)申请了一块空间没有free,进程就结束了,那么空间被回收了吗? (2)malloc()申请3G的内存能否成功?判断依据是什么? (3)父进程堆区申请的空间

m0_62689947的博客 462

CANoe UDS $27服务DLL生成实战:从工程配置到算法修改全流程

本文详细介绍了在Vector CANoe中为UDS(统一诊断服务)的$27安全访问服务生成定制化DLL(动态链接库)的全流程。从定位官方参考工程、配置Visual Studio开发环境,到深入解析核心的GenerateKeyEx函数接口,并重点演示了如何修改和实现自定义的种子-密钥安全算法,最终完成DLL的编译、部署与CANoe集成测试,为汽车电子诊断开发提供实战指导。

star5的专栏 534

fork()函数及例题

一、fork入门知识 一个进程,包括代码、数据和分配给进程的资源。 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #incl

壮少Bryant的博客 3274

Windows下用VS2022编译libcurl全流程(含openssl配置避坑指南)

本文详细介绍了在Windows平台使用Visual Studio 2022编译libcurl库的完整流程,重点解决了集成OpenSSL支持HTTPS功能时的常见配置难题。从环境准备、源码获取、依赖编译到工程配置,提供了清晰的步骤和针对非默认安装路径的避坑指南,帮助开发者高效完成网络库的集成工作。

weixin_29291185的博客 245

使用Qt Creator调用eBUS SDK

在新界面,勾选左下角“ Show unreachable Network Devices",可以看到没有成功连接的网络相机,原因是IP地址配置错误。每个版本的OpenCV的依赖项的名字都不同,我这里是opencv_world490.lib与opencv_world490d.lib。函数,可以看到在这里是图像缓存区,能够对捕获的图像进行一些操作。在Visual Studio打开项目属性,在VC++目录这里,把Opencv的路径添加进去。这时,会自动跳转到mainwindow.cpp,生成该按钮对应的槽函数。

qq_35685051的博客 1288

Linux(十一)fork实例练习、文件操作示例及相关面试题目分享

Linux(十一)fork实例练习、文件操作示例及相关面试题目分享

SSaltedFish_tian的博客 1514

银行统一监管报送系统

依据《银行业金融机构数据治理指引》,银行业金融机构应当建立适应监管数据报送工作需要的信息系统,实现流程控制的程序化,提高监管数据加工的自动化程度。银行业金融机构应当将监管数据纳入数据治理,建立工作机制和流程,确保监管数据报送工作有效组织开展,监管数据质量持续提升。银行通常要对接报送EAST5.0、1104、CRSS等近40个监管应用,涉及近1000张报表。表13-01是主要的监管报送应用、报送依据、报送规范、监管机构名称。

银行信息系统应用架构详解 4348

如何快速上手AmazonCrackedResource:3步Fork仓库,加入4万+开发者的刷题挑战

如果你正在准备 Amazon 面试或校招笔试,**AmazonCrackedResource** 是一个可以免费入手的刷题清单仓库:它把亚马逊在线评估(OA)与面试中反复出现的高频题整理成 50 道精选题目,并配套 5 周打卡挑战,帮你以最小成本进入备考状态。本文用 3 个步骤带你完成 Fork 仓库、克隆到本地并提交第一次进度,轻松加入 4 万+ 开发者的刷题挑战。🚀 ## AmazonCr

gitblog_01137的博客 393

3dmax文件格式转换——.max 转换为 .flt(解决转换后.flt没有纹理贴图的问题)

本文主要介绍如何在3dmax中将.max格式文件转换为.flt格式文件,并解决转换后的文件没有纹理贴图的问题。 在3dmax中,将.max文件转换为.flt格式,只需导出选择.flt格式即可,但是导出的文件在osgEarth中加载后,缺少纹理和贴图。 下面是解决方案: 1、选中加载的模型,然后点击 渲染-> 渲染到纹理 2、将 渲染到纹理 子窗口往下拉,点击 添加 按钮,添加 ...

cchangcs 6167

网络无线AP信号走场测试软件(Ekahau 使用说明)

每次开启 Ekahau 软件需要重复此过程,才可以正常使用。 双击“Ekahau Pro activation.reg”,如下图所示; 点击“Yes”按钮 ,进行注册表合并; 点击“OK”按钮,确认; 运行“Ekahau Pro” 点击“Close”关闭提示; 点击“OK”,关闭提示; ...

Reyn_观极 6416

Java基础面试题总结《八》

确认进程 -> 抓取现场 (Processlist) -> 分析计划 (Explain) -> 优化/限流。大多数情况下,通过优化索引和 SQL 语句即可解决问题;若是业务量激增,则需从架构层面考虑读写分离或扩容。这个问题考察的是对 Redis 基础定位的宏观认知。回答时不仅要说出它是什么,还要解释它为什么强,以及能干什么。对于绝大多数互联网业务,“先更新数据库,再删除缓存” + “基于消息队列/Binlog 的重试机制”是保证最终一致性的最佳实践。它既保证了高性能,又能容忍极小概率的短暂不一致。

qq_55862497的博客 334

PCL 中实现平面模型分割【2026最新版】

RANSAC分割平面。博客长期更新,最近一次更新时间为:2026年5月4日。

点云侠的博客 38万+

终极200+公司LeetCode面试题库:面向技术求职者的系统化刷题指南

LeetCode-Questions-CompanyWise项目是一个精心整理的LeetCode题目分类仓库,按照公司、时间范围和频率进行系统化组织。该项目包含了超过500个数据文件,覆盖200多家科技公司的面试题目,为技术求职者提供了精准的面试准备资源。通过数据驱动的分析工具和可视化图表,你可以高效地针对目标公司进行算法面试准备。 ## 1. 项目全景速览 LeetCode-Question

gitblog_00764的博客 457

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

c++ 多个线程操作socket要同步吗_面试汇总(五):操作系统常见面试总结(一):进程与线程的相关知识点...

前言前面的两篇文章介绍了计算机网络在面试中的一些常见的问题。今天我们给大家介绍在面试中,操作系统常见的面试题。操作系统在计算机行业中是一门最基础的技术,无论是在开发项目还是在算法岗,我们都是基于计算机上进行的,我们对操作系统的了解体现我们从事计算机相关岗位的资深素质,因此,接下来,这篇文章给大家介绍在面试中常见的操作系统的知识点。当然,开发和算法岗对计算机网络的要求程度不同,相对而言,开发对操作系...

weixin_32645173的博客 398

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

面试题kkk

这篇文章摘要主要涵盖了Android开发中的核心知识点和技术难点,包括数据结构、Java与Kotlin语言特性、多线程与并发、内存管理、安卓组件与UI、IPC通信、数据库、多媒体处理、设计模式、性能优化、跨端开发等多个方面。文章详细解析了常见数据结构的使用与实现、JVM机制、内存泄漏分析与解决方案、Activity生命周期、事件分发机制、Handler原理、音视频处理、设计模式应用等核心内容,并提供了实际项目中的技术卡点与解决方案。此外,还涉及了性能优化策略、跨端开发差异、技术方案设计思路以及Git常用命令

mix39的博客 930

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

android 面试题

ContextImpl.startActivity → Instrumentation.execStartActivity → AMS.startActivity → 校验权限、创建 ActivityRecord、Pause 当前 Activity → ApplicationThread.scheduleTransaction → ActivityThread.H → LaunchActivityItem → performLaunchActivity(创建 Activity、调用 onCreate)。

qq_25657125的博客 396

2026年渗透测试面试题总结-21(题目+回答)

安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。

soc的博客 1008

并发的线程入门到并发安全原理解析,技术总监都拍手叫好

Java并发编程技术官笔记 由于篇幅原因,我只能在文章中展示部分的章节内容和核心截图,如果你需要完整的pdf版本,可以在文末免费领取 首先给大家分享学习的思维导图,学习是需要逻辑完整的,这样才可以更高效的学习: 下面是笔记的总目录: 1,线程基础、线程之间的共享和协作 基础概念 认识Java里的线程 对Java里的线程再多-点点认识 线程间的共享和协作 面试题 CPU核心数和线程数的关系 澄清并行和并发 2,线程的并发工具类 Fork-Join CountDownLatch CyclicB

m0_56146626的博客 142

吃透这篇 Redis 面试题,搞定 90% 后端面试(2026 超全整理)

本文是一份全面的Redis面试指南,重点覆盖后端面试中的高频考点。文章分为四个核心篇章: 基础原理篇:解析Redis高性能的四大支柱(内存存储、单线程模型、I/O多路复用、高效数据结构),深入讲解过期键删除策略(惰性+定期)和8种内存淘汰策略,强调生产环境推荐配置。 数据类型篇:详细对比9种Redis数据类型的底层实现(如SDS、跳表、QuickList)及典型应用场景,特别指出ZSet选用跳表而非平衡树的原因,并提供安全遍历Key的最佳实践。 持久化篇:深度对比RDB和AOF机制,介绍Redis 4.0+

JAVA社区的博客 994

2.4 java面试题:Netty

Netty 是一个,用于快速开发高性能、高可靠性的网络 IO 程序。它在 Java 领域中的地位,就像“网络编程的 Spring”,几乎统治了所有需要自定义协议的中间件和分布式组件。老练的 Java 工程师说 Netty,不仅要讲“是什么”,还要讲清它,以及。

你是人间四月天 219
上一篇: 网络编程学习笔记一:Socket编程
下一篇: C++ 虚函数表解析小结
Solid7
博客等级 码龄11年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值