【校招面经】“学完C语言” · 这些高频面试考点你都掌握了吧~

简介: 学完C语言 · 这些高频面试考点你都掌握了吧~

目录

一、大小端字节序

1.大小端引入

2.何为大端小端

3.百度真题

思路

代码执行

4.作业补充

二、深入理解static关键字

1.static修饰局部变量

2. static修饰全局变量

3.static修饰函数

三、深剖const关键字

1.const修饰变量

2.常变量可成为数组一部分吗?

3.const修饰指针

四、手写求字符串长度函数(strlen)

1.方法一:普通解法

2.方法二:递归法

3.方法三:指针 - 指针

五、手写字符串拷贝函数(strcpy)

六、遇见安然遇见你,不负代码不负卿!


【前言】

为了考察自己对于C语言掌握情况,我特意在论坛里面整理了近百份C/C++研发方向的面经,我发现有很多知识点频繁被考察,下面我将这些高频考点分享给大家,铁汁们看看自己能答对多少个。(顺便说一下哈,C语言内容其实是非常多的,这里所说的“学完C语言”,指的仅仅是学完C语法而已)

【声明】

下面所总结的内容可能并不是面面俱到的,后续还会有所补充。

【注意】:博主刚建立了一个社区和QQ学习群,链接和二维码在最下面哦,非常欢迎铁汁们的加入!

 

一、大小端字节序

1.大小端引入

看看下面这段代码:

#include<stdio.h>
int main()
{
  int a = 0x11223344;//以十六进制的形式赋值给a
  return 0;
}

很明显,在内存中存储的顺序不对呀,这是为什么?这里就要介绍大小端了。

2.何为大端小端

大端字节序存储:

当一个数据的低位放到高地址处,数据的高位放到低地址处;

小端字节序存储:

当一个数据的低位放到低地址处,数据的高位放到高地址处

比如上面的栗子:

3.百度真题

下面看看15年百度的一道价值10分的笔试题!

百度2015年系统工程师笔试题(10分):

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。

概念的话都在上面啦,请看看如何设计小程序来判断...

思路

可以定义一个整型变量,并且初始化为1,所以它转换成十六进制表示形式就是0x00 00 00 01如果当前机器是小端字节序存储,那么从低地址到高地址就是01  00 00 00;如果当前机器是大端字节序存储,那么从低地址到高地址就是00 00 00  01;所以不同点就在于低地址处一个是01,一个是00,那怎么去判断呢?这里就可以使用前面指针所学的解引用操作,不过对于整型指针来说一次访问4个字节,而我们想要的仅仅读取到1个字节即可。所以这里就需要进行强制类型转换,将int* 转换成char* 类型的,这样的话进行指针解引用操作的时候,一次就只能访问一个字节的内容了。

分析起来很简单,下面看看代码该如何编写:

代码执行

#include<stdio.h>
int main()
{
  int a = 1;//00 00 00 01
  char* p = (char*)&a;
  if (1 == *p)
  {
    printf("小端\n");
  }
  else
  {
    printf("大端\n");
  }
  return 0;
}

上面这段代码只是方便大家理解,实际上我们交给面试官看的话,这么写代码就显得很low啦,所以下面才是满分答案:

#include<stdio.h>
int check_sys()
{
  int a = 1;//0x00 00 00 01
  return (*(char*)&a);//返回0-大端;返回1-小端
}
int main()
{
  int ret = check_sys();
  if (1 == ret)
  {
    printf("小端\n");
  }
  else
  {
    printf("大端\n");
  }
  return 0;
}

4.作业补充

unsigned int a = 0x1234;
unsigned char b = &a;
在32位大端式处理器变量b 等于()
A:0x00
B:0x12
C:0x34
D:0x1234
//很明显,答案是A,因为实际上a中放的是0x00001234

问:字符类型有大小端字节序问题吗?

答:没有,因为字符类型只有一个字节,何来字节序一说呢。


二、深入理解static关键字

在我整理百份面经后,我发现,static、extern、const、struct等关键字是大多数公司考察的重点,考的相当频繁,其中不乏知名大厂!

下面详细介绍static关键字:

static —— “静态”之意

C语言中static是用来修饰变量和函数的。

  • 修饰局部变量——静态局部变量
  • 修饰全局变量——静态全局变量
  • 修饰函数——静态函数

1.static修饰局部变量

//代码1
#include<stdio.h>
void test()
{
  int a = 1;//局部变量a的作用域在test()中,当a出了作用域就被销毁了,下次调用test()时,又需要重新创建a
  a++;
  printf("%d ", a);
}
int main()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    test();
  }
  return 0;
}

//代码2
#include<stdio.h>
void test()
{
  //static修饰局部变量a
  static int a = 1;
  a++;
  printf("%d ",a);
}
int main()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    test();
  }
  return 0;
}

看:上面的两块代码几乎一样,只不过第二个代码中自定义函数test()里面用static修饰局部变量,所以出现了这样的差异。


根据代码2的结果推测出每一次调用test(),使用的a都是上一次函数调用时留下的a;第二次调用test()时,由于上次函数调用产生的a没有被销毁,所以不会再次创建a,直接跳到了下一步,a++


【敲黑板】:

static修饰局部变量的时候,其实是改变了变量的存储类型,由栈区存储变成了静态区存储,从而使得静态的局部变量出了自己的作用域也不会被销毁,其实也就是相当于改变了这个变量的生命周期。

这里补充一条小知识点:

内存是一块比较大的空间,在使用内存的时候,会划分出不同的功能区域:栈区、堆区、静态区(这里为了好理解就直接这样说了,后面会详细介绍到这块内容)

2. static修饰全局变量

//代码1
//add.c文件
int g_val = 2018;//g_val是在add.c文件中定义的全局变量
//test.c文件
//如果想使用来自其他文件(外部文件)的全局变量,要先声明一下
extern int g_val;
//extern是一个关键字,专门用来声明外部符号的
int main()
{
  printf("%d\n", g_val);
  return 0;
}

上面这个程序是正常编译的,不过下面的这个程序就不行了哦

/代码2
//add.c文件
static int g_val = 2018;
//test.c文件
extern int g_val;
int main()
{
  printf("%d\n", g_val);
  return 0;
}

第二个程序编译的时候会报错,因为出现连接性错误。

【解释】

一个全局变量在整个工程中的其他子文件内部能被使用,是因为全局变量具有外部链接属性什么叫外部链接属性,一个变量在一个文件中定义,但是在另一个文件中可以使用(访问)叫外部链接属性当一个全局变量被static修饰的时候。其外部链接属性就变成了内部连接属性;使得这个全局变量只能在自己的源文件内部使用,其他文件不能再使用,因为它不再具有外部链接属性,给我们的感觉是作用域变小了。另外,局部变量只有内部链接属性

3.static修饰函数

//代码1
//add.c文件
int Add(int x, int y)
{
  return x + y;
}
//test.c文件
extern int Add(int x, int y);
int main()
{
  printf("%d\n", Add(2, 3));
  return 0;
}

上面的程序编译正常,但是下面的程序编译时会出现错误哦。

//代码2
//add.c文件
static int Add(int x, int y)
{
  return x + y;
}
//test.c文件
extern int Add(int x, int y);
int main()
{
  printf("%d\n", Add(2, 3));
  return 0;
}

这个程序编译时出现连接性错误。

因为函数本身就具有外部链接属性,static修饰函数的时候,函数本来是具有外部链接属性的,但是被static修饰后,就变成了内部连接属性,导致这个函数只能在自己的源文件内部使用,给我们的感觉是改变了作用域。


三、深剖const关键字

1.const修饰变量

【注意】:const修饰的只读变量不可直接被修改

//const修饰的只读变量不可以直接被修改
const int a = 10;
a = 20;//错误

问:const修饰的变量真的不能被修改吗?

其实const修饰的变量可以被间接修改掉

//const修饰的变量可以间接被修改
const int i = 10;
int* p = &i;
*p = 20;
printf("%d\n", i);//打印20

这样的话就有一个问题:const修饰变量意义何在?

  1. 让编译器进行直接修改式检查;
  2. 告诉其他程序猿(正在修改你代码的或者阅读你代码的)这个变量后面不要改哦,也属于一种”自描述”含义

2.常变量可成为数组一部分吗?

const int n = 10;
int arr[n] = {0};


注意,上面的代码在VS编译器(标准C)下直接报错了,但在gcc(GNU扩展)下可以正常编译,所以我们一切都要向标准看齐,这样的话,也就是不可以!上面的定义是错误的。

3.const修饰指针

面试题:const* 和 *const 什么区别?

const修饰指针的时候(有两种):


const放在*的左边(const int* p) ,修饰的是*p,使得*p不能改变(保证指针指向的内容不能通过指针修改),但是指针变量p本身可以改变;


const放在*的右边(int* const p),修饰的是p,使得p 不能改变。但是*p可以被修改

题目描述:

下列选项中哪一种形式声明了一个指向char类型变量的指针P,P的值是不可修改的,但P指向的变量的值是可以修改的?C

A:const char* p;//const修饰*p
B:char const* p;//const修饰*p
C:char* const p;//const修饰p
D:const char* const p;//const既修饰*p,又修饰p

思路:其实一看到题目中说p的值是不可修改的我们就应该想到const放在*的右边。


四、手写求字符串长度函数(strlen)

库函数strlen()原型:

1.方法一:普通解法

//方法一:普通方法
int my_strlen(const char* str)
{
    assert(str);//最好加上断言
  int count = 0;
  while (*str++)
  {
    count;
  }
  return count;
}

2.方法二:递归法

int my_strlen(const char* str)
{
  //找重复:my_strlen(str+1)是原问题的重复
  //找边界
  if (*str == '\0')
  {
    return 0;
  }
  return my_strlen(str + 1) + 1;
}

3.方法三:指针 - 指针

//方法三:指针 - 指针
int my_strlen(const char* str)
{
    assert(str);//最好加上断言
  char* end = str;
  while (end++)
  {
    ;
  }
  return end - str;
}

五、手写字符串拷贝函数(strcpy)

//本题需要注意的有两点:
//一是str1要足够大
//二是要保存str1的首地址
char* my_strcpy(char* str1, const char* str2)
{
  assert(str1 && str2);//最好加上断言
  char* ret = str1;//注意哦,记得保存str1的首地址
  while (*str1++ = *str2++)
  {
    ;
  }
  return ret;
}

【敲黑板】:本题需要注意的有两点:

  1. str1要足够大
  2. 保存str1的首地址

六、遇见安然遇见你,不负代码不负卿!

今天暂且到这里咯,后续会持续更新的哈,目标大厂,从最基本的知识点做起!

    如果有所收获,求求来个三连吧~

博主昨天刚建立了一个社区,非常欢迎铁汁们的加入并同步自己的博文到社区里引流,后面我也会在社区里开展一些奖励活动的哟,快来join us!

【招贤纳士】:建立初期,希望大家各显神通,表现积极优秀的童鞋可以搭伙一同管理社区!

image.png

最近由于我忙着复习备战期末考试,所以有很多铁汁给我的私信都没有及时回复,实在是对不起,所以我建立了一个QQ群,里面有很多资料,包括C/C++研发方向、Java研发方向的书籍,还有许多算法书,欢迎大家加入,如果有问题可以发到群里面,我们一同探讨,总之一句话,拒绝躺平,冲刺大厂!

QQ群号:926297014


相关文章
|
6月前
|
缓存 NoSQL Java
校招 Java 面试常见知识点及实战案例全解析
本文全面解析了Java校招面试中的常见知识点,涵盖Java新特性(如Lambda表达式、、Optional类)、集合框架高级应用(线程安全集合、Map性能优化)、多线程与并发编程(线程池配置)、JVM性能调优(内存溢出排查、垃圾回收器选择)、Spring与微服务实战(Spring Boot自动配置)、数据库与ORM框架(MyBatis高级用法、索引优化)、分布式系统(分布式事务、缓存应用)、性能优化(接口优化、高并发限流)、单元测试与代码质量(JUnit 5、Mockito、JaCoCo)以及项目实战案例(电商秒杀系统、社交消息推送)。资源地址: [https://pan.quark.cn/s
202 4
|
6月前
|
算法 Java 关系型数据库
校招 Java 面试基础题目解析及学习指南含新技术实操要点
本指南聚焦校招Java面试,涵盖Java 8+新特性、多线程与并发、集合与泛型改进及实操项目。内容包括Lambda表达式、Stream API、Optional类、CompletableFuture异步编程、ReentrantLock与Condition、局部变量类型推断(var)、文本块、模块化系统等。通过在线书店系统项目,实践Java核心技术,如书籍管理、用户管理和订单管理,结合Lambda、Stream、CompletableFuture等特性。附带资源链接,助你掌握最新技术,应对面试挑战。
162 2
|
6月前
|
存储 安全 算法
Java 集合面试题 PDF 下载及高频考点解析
本文围绕Java集合面试题展开,详细解析了集合框架的基本概念、常见集合类的特点与应用场景。内容涵盖`ArrayList`与`LinkedList`的区别、`HashSet`与`TreeSet`的对比、`HashMap`与`ConcurrentHashMap`的线程安全性分析等。通过技术方案与应用实例,帮助读者深入理解集合类的特性和使用场景,提升解决实际开发问题的能力。文末附带资源链接,供进一步学习参考。
163 4
|
6月前
|
Java 关系型数据库 MySQL
2025 年互联网公司校招 Java 面试题总结及答案实操示例解析
本项目基于Spring Boot 3与Java 17技术栈,围绕校园招聘常见面试题,提供核心知识点的实操示例。涵盖多线程、RESTful API设计、数据库操作(Spring Data JPA)、事务管理及异常处理等。通过完整代码实现与运行步骤,帮助理解用户管理、线程池配置等实际应用场景。资源包含项目结构、关键代码示例(如User实体类、UserService服务层、ThreadService多线程实现)及数据库迁移脚本,适合深入学习与实践。环境要求:JDK 17+、Maven 3.8+、MySQL 8.0+。
252 3
|
6月前
|
SQL Java 数据库连接
阿里腾讯互联网公司校招 Java 面试题总结及答案解析
本文总结了阿里巴巴和腾讯等互联网大厂的Java校招面试题及答案,涵盖Java基础、多线程、集合框架、数据库、Spring与MyBatis框架等内容。从数据类型、面向对象特性到异常处理,从线程安全到SQL优化,再到IOC原理与MyBatis结果封装,全面梳理常见考点。通过详细解析,帮助求职者系统掌握Java核心知识,为校招做好充分准备。资源链接:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
205 2
|
6月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
337 3
|
6月前
|
安全 Java 编译器
Java 校招面试题目合集及答案 120 道详解
这份资料汇总了120道Java校招面试题目及其详细答案,涵盖Java基础、JVM原理、多线程、数据类型、方法重载与覆盖等多个核心知识点。通过实例代码解析,帮助求职者深入理解Java编程精髓,为校招面试做好充分准备。无论是初学者还是进阶开发者,都能从中受益,提升技术实力和面试成功率。附带的资源链接提供了更多学习材料,助力高效备考。
308 3
|
6月前
|
存储 算法 Java
校招 java 面试基础题目及解析
本文围绕Java校招面试基础题目展开,涵盖平台无关性、面向对象特性(封装、继承、多态)、数据类型、关键字(static、final)、方法相关(重载与覆盖)、流程控制语句、数组与集合、异常处理等核心知识点。通过概念阐述和代码示例,帮助求职者深入理解并掌握Java基础知识,为校招面试做好充分准备。文末还提供了专项练习建议及资源链接,助力提升实战能力。
158 0
|
6月前
|
存储 设计模式 算法
校招 Java 面试常见知识点汇总及备考指南
本文全面解析校招Java面试常见知识点,涵盖Java基础、集合框架、多线程并发、JVM等内容。从面向对象特性(封装、继承、多态)到数据类型与包装类,再到字符串处理和关键字用法,逐一剖析。集合框架部分深入讲解List、Set、Map接口及其常用实现类的特性和应用场景。多线程章节探讨线程创建、同步机制及线程池的使用。JVM部分聚焦内存区域、垃圾回收机制和类加载过程。结合实际案例,助你轻松应对校招面试!资源地址:[点此获取](https://pan.quark.cn/s/14fcf913bae6)。
163 0
|
11月前
|
Java 程序员
Java社招面试中的高频考点:Callable、Future与FutureTask详解
大家好,我是小米。本文主要讲解Java多线程编程中的三个重要概念:Callable、Future和FutureTask。它们在实际开发中帮助我们更灵活、高效地处理多线程任务,尤其适合社招面试场景。通过 Callable 可以定义有返回值且可能抛出异常的任务;Future 用于获取任务结果并提供取消和检查状态的功能;FutureTask 则结合了两者的优势,既可执行任务又可获取结果。掌握这些知识不仅能提升你的编程能力,还能让你在面试中脱颖而出。文中结合实例详细介绍了这三个概念的使用方法及其区别与联系。希望对大家有所帮助!
569 60