后端开发面经系列--360一面面经

360嵌入式开发一面面经

公众号:阿Q技术站

来源:
https://www.nowcoder.com/feed/main/detail/22a2f509f0a94c3cbb8ba485de084d19

1、Wi-Fi关联是怎么做的了解过吗?

  1. 扫描可用网络: 设备会主动扫描附近的无线网络,以查找可用的Wi-Fi网络。这个扫描过程通常包括探测各个Wi-Fi网络的SSID(网络名称)和信号强度。
  2. 选择网络: 设备会根据一些标准来选择一个要连接的网络,通常是用户事先配置的首选网络,或者信号强度最强的网络。
  3. 认证: 如果Wi-Fi网络需要密码或其他认证方式(如WPA2密码或WPA3密码),设备将发送认证请求,通常需要提供正确的密码。
  4. 关联: 一旦认证通过,设备将与Wi-Fi网络关联,建立一个连接。在这个步骤中,设备获取了IP地址,这使得它可以通过网络进行通信。
  5. DHCP分配: 一旦设备与Wi-Fi网络关联,通常会使用DHCP(Dynamic Host Configuration Protocol)从路由器或DHCP服务器获取IP地址、子网掩码、网关地址和DNS服务器地址等网络配置信息。
  6. 完成关联: 一旦设备成功获取IP地址和相关网络配置信息,Wi-Fi关联就完成了,设备现在可以通过Wi-Fi网络访问互联网或局域网资源。

2、TCP保证可靠性有哪些措施?

  1. 序号和确认: TCP 使用序号字段来对数据进行编号,接收方使用确认字段来确认已经收到的数据。这确保了数据的顺序性和完整性。如果发生数据丢失或重传,接收方可以根据序号进行恢复。
  2. 超时和重传: TCP 使用超时机制来检测丢失的数据包。如果发送方没有收到来自接收方的确认,它会等待一段时间(超时时间),然后重传相应的数据包。这确保了即使数据包在传输过程中丢失,它们最终还是会被正确传输。
  3. 流量控制: TCP 使用滑动窗口机制来控制数据的发送速率,以防止数据的溢出和拥塞。发送方和接收方之间的窗口大小是动态调整的,以适应网络条件。这有助于避免网络拥塞和数据包丢失。
  4. 拥塞控制: TCP 使用拥塞窗口来调整数据的发送速率,以避免网络拥塞。拥塞窗口是动态调整的,根据网络拥塞的程度来进行调整。如果网络出现拥塞,发送方会减小发送速率,以减轻网络负担。
  5. 有限重传次数: TCP 限制了数据包的重传次数,以避免无限重传。如果数据包经过多次重传后仍未成功传输,TCP 将放弃并通知上层应用程序。
  6. 数据校验: TCP 使用校验和字段来验证数据的完整性。如果数据在传输过程中发生错误,校验和将失败,导致数据被丢弃或重传。
  7. 连接管理: TCP 使用三次握手和四次挥手的机制来建立和关闭连接。这有助于确保数据的可靠传输,并避免不必要的数据包传输。

3、如何用C语言实现大小端? 什么是大端和小端?

  1. 小端: 在小端系统中,最低有效字节(即数据的最低位)存储在内存的低地址处,而最高有效字节(最高位)存储在高地址处。这意味着数据的字节从低地址到高地址排列。
    1. 低地址 ------------------> 高地址
    2. 0x78 | 0x56 | 0x34 | 0x12
  2. 大端: 在大端系统中,最高有效字节存储在内存的低地址处,而最低有效字节存储在高地址处。数据的字节从高地址到低地址排列。
    1. 低地址 -----------------> 高地址
    2. 0x12 | 0x34 | 0x56 | 0x78

举个例子:

#include <stdio.h>

int main() {
    unsigned int num = 1;
    unsigned char *byte = (unsigned char *)&num;

    printf("Value: %u\n", num);

    if (*byte == 1) {
        printf("This system is Little Endian\n");
    } else {
        printf("This system is Big Endian\n");
    }

    printf("Bytes in memory (from lowest address to highest):\n");
    for (int i = 0; i < sizeof(num); i++) {
        printf("%p: %02X\n", (void *)(byte + i), byte[i]);
    }

    return 0;
}

检测 byte 的第一个字节的值。如果它是1,则表示小端系统;如果不是1,则表示大端系统。

4、802.11ax和802.11ac/n这些有什么区别? 802.11ax、802.11ac和802.11n是Wi-Fi标准的不同版本,它们在性能、速度、频段和其他方面有一些关键区别。

区别:

  1. Wi-Fi标准名称和发布年份:
    1. 802.11n:也称为Wi-Fi 4,于2009年发布。
    2. 802.11ac:也称为Wi-Fi 5,于2013年发布。
    3. 802.11ax:也称为Wi-Fi 6,于2019年发布。
  2. 频段支持:
    1. 802.11n:工作在2.4GHz和5GHz频段。
    2. 802.11ac:主要工作在5GHz频段,但也支持2.4GHz。
    3. 802.11ax:工作在2.4GHz和5GHz频段,提供更好的频谱效率。
  3. 理论最大速度:
    1. 802.11n:最高可达300 Mbps或600 Mbps,取决于通道宽度。
    2. 802.11ac:最高可达1.3 Gbps(1.3 Gigabits per second)。
    3. 802.11ax:最高可达9.6 Gbps,但实际速度通常更低。
  4. MIMO技术:
    1. 802.11n:使用MIMO(多输入多输出)技术,支持多个天线。
    2. 802.11ac:引入更高级的MIMO,如3x3或4x4 MIMO。
    3. 802.11ax:引入更高级的MIMO,如8x8 MIMO,并引入了OFDMA技术以提高网络效率。
  5. 通道宽度:
    1. 802.11n:支持20MHz和40MHz通道宽度。
    2. 802.11ac:支持80MHz和160MHz通道宽度。
    3. 802.11ax:支持更宽的通道宽度,如160MHz和甚至更大的通道宽度。
  6. 效率和密度:
    1. 802.11ax引入了更多的效率和密度,支持高密度网络环境,如拥挤的公共场所。
  7. QAM调制:
    1. 802.11n:支持16-QAM和64-QAM调制。
    2. 802.11ac:引入了256-QAM调制。
    3. 802.11ax:引入了1024-QAM调制。
  8. 性能和容量:
    1. 802.11ax旨在提供更高的性能和容量,以应对越来越多的连接设备和应用程序需求。

5、进程和线程的区别?

  1. 定义:
    • 进程:进程是一个独立的执行实体,每个进程都有自己的内存空间、代码、数据和系统资源。
    • 线程:线程是进程内的执行单元,多个线程可以共享同一个进程的内存空间和资源,它们在同一个进程中并行执行。
  2. 独立性:
    • 进程:进程是相互独立的,一个进程的崩溃通常不会影响其他进程。
    • 线程:线程是进程内的执行单元,它们共享相同的内存空间,因此一个线程的错误可能会影响整个进程,包括其他线程。
  3. 资源开销:
    • 进程:每个进程都有自己的独立内存空间和系统资源,因此创建和销毁进程通常需要较多的系统资源和时间。
    • 线程:线程共享同一个进程的资源,因此创建和销毁线程的开销通常较小。
  4. 通信和同步:
    • 进程:不同进程之间的通信通常需要使用进程间通信(IPC)机制,如管道、消息队列、套接字等。
    • 线程:线程之间可以通过共享内存等机制更容易地进行通信和同步。
  5. 切换开销:
    • 进程:由于进程切换需要保存和恢复整个进程的状态,进程切换开销较大。
    • 线程:线程切换开销较小,因为它们共享相同的地址空间和资源。
  6. 并发性:
    • 进程:进程之间的并发性较低,因为它们是相互独立的。
    • 线程:线程之间的并发性较高,因为它们可以在同一个进程中并行执行。
  7. 适用场景:
    • 进程:适用于需要隔离、独立性和安全性的任务,如独立的应用程序。
    • 线程:适用于需要高并发性、共享数据和轻量级任务的情况,如多线程编程和服务器应用。

6、多进程编程实现? 多进程编程是指使用多个独立的进程来执行并发任务,通常涉及创建、管理和协调多个进程。在Unix/Linux系统中,可以使用fork()系统调用来创建新的进程,每个进程都有自己的地址空间和代码执行流。

一般步骤:

  1. 包含必要的头文件: 在C程序中,需要包含 <stdio.h><unistd.h> 头文件以使用fork()函数。
  2. 使用fork()创建子进程: 使用fork()函数创建一个新的子进程。fork()会复制父进程的地址空间和执行状态,包括程序代码、数据和文件描述符等。
pid_t child_pid = fork();
  1. 检查fork()的返回值:

    • 如果fork()返回负值,表示创建子进程失败。

    • 如果fork()返回0,表示当前代码正在子进程中执行。

    • 如果fork()返回正值,表示当前代码正在父进程中执行,返回值是子进程的PID(进程标识符)。

  2. 在父子进程中执行不同的任务: 在父子进程中,可以编写不同的代码来执行不同的任务。通常,父进程会等待子进程完成,或者父子进程可以进行进一步的通信和协调。

  3. 子进程的任务完成后退出: 在子进程完成其任务后,可以使用exit()函数退出子进程。

if (child_pid == 0) {
    // 子进程执行的代码
    // ...
    exit(0);
}
  1. 父进程等待子进程完成: 父进程可以使用wait()或waitpid()等系统调用来等待子进程的完成,并获取子进程的退出状态。
if (child_pid > 0) {
    int status;
    wait(&status);
    // 在这里可以处理子进程的退出状态
}

7、MCS是什么(没料到嵌入式还问物理层)?

“MCS” 通常代表 “Modulation and Coding Scheme”(调制与编码方案),它是一种用于描述在无线通信中如何调制和编码数据的方法或方案。 MCS 通常与 Wi-Fi、无线局域网(Wireless LAN)、LTE、5G 和其他无线通信技术相关。

  1. 调制方式: 在传输数据时使用的调制方式,包括调制类型(例如,QPSK、16-QAM、64-QAM)和符号率。不同的调制方式具有不同的数据传输速率和容忍度。
  2. 编码方式: 数据在传输前如何编码以提高错误容忍度。通常,更高级别的编码可以提供更好的容错性,但以牺牲传输速率为代价。

MCS 的选择取决于通信环境、信道质量、带宽和应用需求。通常,较差的信道质量需要更低级别的 MCS 以提供更好的容错性,而较好的信道质量则可以使用更高级别的 MCS 以获得更高的数据传输速率。

8、C语言中如何防止同一个.h文件被重复 #include?

在C语言中,可以使用预处理指令和条件编译来防止同一个头文件被重复包含。这通常通过宏和条件编译指令来完成。

给个参考方法:

  1. 在头文件(.h文件)的开头添加条件编译宏,以确保头文件只会被包含一次:
#ifndef HEADER_NAME_H
#define HEADER_NAME_H

// 头文件的内容

#endif

HEADER_NAME_H 是一个自定义的宏名称,通常采用头文件名的大写形式。你可以用不同的名字替换它,只要确保它在头文件的不同地方是唯一的。

  1. 当预处理器首次遇到 #ifndef 指令时,会检查是否定义了 HEADER_NAME_H 这个宏。如果没有定义,它会执行 #define 部分,将 HEADER_NAME_H 定义为一个值,然后继续处理头文件。

  2. 当同一个头文件再次被包含时,预处理器会检测到 HEADER_NAME_H 已经被定义,因此不会再次包含头文件的内容。

这样,就确保同一个头文件不会被重复包含,防止出现重复定义的问题。

例子:

#ifndef MYHEADER_H
#define MYHEADER_H

#include <stdio.h>

void myFunction();

#endif

在使用这个头文件的源文件中,只需要包含一次该头文件,无需担心重复包含:

#include "myheader.h"

int main() {
    myFunction();
    return 0;
}

9、动态链接和静态链接分别是什么?

  1. 静态链接(Static Linking):
    • 工作方式:在静态链接中,所有所需的库和模块在编译时都会被合并到最终的可执行文件中。这意味着可执行文件包含了所有依赖的代码和数据,形成一个独立的、自包含的文件。
    • 优点:
      • 可执行文件独立,不依赖外部库或模块,因此更容易分发和部署。
      • 静态链接在编译时进行,可以在编译器检查到错误和优化代码。
      • 程序运行时没有外部依赖,因此通常更稳定。
    • 缺点:
      • 可执行文件较大,因为它包含了所有依赖的代码,可能占用更多的磁盘空间。
      • 每次更新代码或库时,必须重新编译整个程序。
  2. 动态链接(Dynamic Linking):
    • 工作方式:在动态链接中,程序的不同部分被分为可执行文件和动态链接库(DLL)两部分。可执行文件包含程序的核心代码,但依赖的库被保存在独立的DLL文件中。这些库在程序运行时动态加载和链接。
    • 优点:
      • 节省磁盘空间,因为多个程序可以共享相同的动态链接库,减少了重复存储。
      • 更容易更新库,因为只需替换DLL而不需要重新编译整个程序。
    • 缺点:
      • 需要运行时动态加载和链接,可能引入一些性能开销。
      • 可能出现版本不一致的问题,因为不同程序可能依赖于不同版本的库。

通常,动态链接在现代操作系统中更为普遍,因为它可以节省磁盘空间并使软件更新更容易。静态链接通常用于嵌入式系统或需要独立、自包含可执行文件的情况。在某些情况下,可以使用混合链接,将一些库静态链接到可执行文件中,而将其他库动态链接以在需要时加载。

10、对指针的理解?

  1. 指针是内存地址的容器: 指针是一个变量,它存储了内存中某个数据的地址,而不是数据本身。这使得程序可以引用和操作内存中的数据,而不需要知道数据的确切值或位置。
  2. 数据类型相关: 指针的数据类型与它所指向的数据的数据类型相关。这意味着指针的类型决定了指针可以指向哪种类型的数据。例如,一个整数指针可以指向整数变量,一个字符指针可以指向字符数组。
  3. 指针操作: 可以使用指针来访问、修改和操作内存中的数据。通过指针,可以读取或写入数据,还可以执行指针算术操作,如递增和递减指针,以遍历数组或数据结构。
  4. 空指针: 空指针是指不指向任何有效内存地址的指针。在C/C++中,空指针通常用NULL(C)或nullptr(C++)表示。
  5. 野指针: 野指针是指指向未知或无效内存地址的指针,访问野指针可能导致未定义行为或程序崩溃。
  6. 指针和数组: 数组名本质上是一个指向数组首元素的指针,因此可以通过指针操作来访问数组元素。例如,arr[0] 可以写为 *arr
  7. 指针和函数: 指针可以用于传递函数参数,允许函数修改调用者的变量或在函数间共享数据。
  8. 动态内存分配: 指针常用于动态内存分配,如在C/C++中使用 mallocfree 分配和释放内存。
  9. 引用和指针: 指针和引用(在C++中)都用于处理内存中的数据,但它们有不同的语法和语义。引用是指已有变量的别名,而指针是一个独立的变量,存储了另一个变量的地址。

11、函数指针怎么使用 有什么作用? 函数指针是指向函数的指针变量,它允许程序在运行时动态选择要调用的函数。

函数指针的声明和定义:

return_type (*function_pointer)(parameter_list);
  • return_type 是函数的返回类型。
  • function_pointer 是函数指针变量的名称。
  • parameter_list 是函数的参数列表。

函数指针的初始化:

函数指针可以初始化为指向具体函数的地址。

int (*add)(int, int) = &addition_function;

add 函数指针初始化为指向名为 addition_function 的函数的地址。

使用函数指针调用函数:

函数指针可以像调用普通函数一样使用,通过使用函数调用操作符 ()

int result = (*add)(3, 4); // 调用addition_function(3, 4)

或者可以简化为:

int result = add(3, 4);

回调函数:

函数指针常用于实现回调函数的机制。通过将函数指针传递给其他函数,可以使其他函数在适当的时候调用指定的函数,以执行特定的操作。这在事件处理、异步编程等方面非常有用。

动态算法选择:

函数指针允许在运行时选择要执行的算法。这对于根据不同条件选择不同的计算方法非常有用。例如,可以根据用户输入选择不同的排序算法。

函数表:

函数指针可以用于创建函数表,函数表是一个数组,每个元素都是一个函数指针,用于执行不同的操作。程序可以根据索引或条件来选择要执行的函数。

12、TCP/IP网络模型一共几层 哪几层?

  1. 应用层: 应用层是网络协议栈的最顶层,包括了应用层协议,如HTTP、FTP、SMTP、DNS等。这些协议负责应用程序之间的通信和数据交换。
  2. 传输层: 传输层提供端到端的数据传输和错误检测。最常见的传输层协议是TCP(传输控制协议)和UDP(用户数据报协议)。TCP提供可靠的、面向连接的数据传输,而UDP提供不可靠的、面向无连接的数据传输。
  3. 网络层: 网络层处理数据包的路由和转发。主要协议包括IP(Internet协议),它负责数据包的寻址和路由。IPv4和IPv6是两个常见的IP版本。
  4. 数据链路层: 数据链路层负责物理介质的访问和数据帧的传输。它通常包括以太网、Wi-Fi、PPP等协议,用于在相邻节点之间传输数据帧。

13、ARP协议具体干什么的?

ARP(Address Resolution Protocol,地址解析协议)是用于将网络层(如IPv4)的IP地址映射到数据链路层(如以太网)的物理硬件地址(MAC地址)的协议。

几个功能:

  1. IP地址到MAC地址的映射: ARP用于确定本地网络上的特定IP地址对应的MAC地址。这是因为在一个局域网中,通信设备(如计算机、路由器)通过MAC地址来识别和定位其他设备,而不是IP地址。
  2. ARP请求和应答: 当设备需要将某个IP地址映射到MAC地址时,它会发送一个ARP请求广播到局域网中的所有设备。带有请求IP地址的设备会响应ARP请求,提供与该IP地址相关联的MAC地址。这个过程通常包括ARP请求和ARP应答两个步骤。
  3. ARP缓存: 设备通常会维护一个ARP缓存表,其中存储了最近已解析的IP地址和相应的MAC地址。这样,在未来的通信中,设备可以直接查找ARP缓存,而不必每次都发送ARP请求。
  4. ARP攻击检测: ARP协议还涉及到检测和防范ARP欺骗攻击,其中攻击者尝试伪装成其他设备,欺骗网络中的设备以获得通信优势。
  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值