V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AFOX
V2EX  ›  程序员

这些 C 语言的题,各位不用电脑纯手写的话,能做到什么程度呢?

  •  
  •   AFOX · 146 天前 · 5715 次点击
    这是一个创建于 146 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这些 C 语言的题,各位不用电脑纯手写的话,能做到什么程度呢?

    今天下午笔试被挂了,题目如下:

    1. 下面的输出是什么,请说明原因(钓鱼执法.....很容易就做错了)
    
    int main() {
         int a[5] = {1, 2, 3, 4, 5};
         int *p = &a + 1;
         printf("%d, %d", *(a+1), *(p - 1));
    
         return 0;
    }
    
    
    2. 请用一个 C 语言表达式判断某个数是否为 2 的 N 次幂 (没搞懂如何用一个表达式计算,这道题不谷歌真的做不出吧.....)
    
    3. 计算某个数的质因数(例如:12 = 2 * 2 * 3 ) (这里想太多了,空在那做后面的去了)
    
    4. 写出单链表反转的过程(写太多遍了,直接秒)
    
    5. 写一个函数判断回文数(没写出最优解,我转换成字符串用双指针判断了)
    
    6. 删除字符串中的数字并压缩字符串的空间,例如: 输入为 "abc123de45fg" ,输出 "abcdefg" (这里也是双指针做的,不需要开辟新的空间,判断字符串结尾是'\0')
    
     下面的 7 和 8 选一道做
    7. 微积分题,计算 y=x 和 y=x^2 围成的面积(想了一下怎么求积分)
    8. 在[0, 2Π]的区间内,计算 y=sinx 与 x 轴围成的面积
    
    9. 矩阵计算,这里具体数字记不清了,随便填一下不影响
    A = [[1,2,3], [4,5,6], [7,8,9]]
    B = [[3,2,1], [6,5,4], [9,8,7]]
    
    a. 计算 AB 的值 (还记得怎么算)
    b. 计算 A 的逆矩阵(不记得相关概念了,没做对)
    
    10. 写出 TCP/IP 的系统调用函数及用法(之前的工作基本不用 tcp/ip ,这里写不出)
    11. libudev 的设备通信过程(这个也不了解)
    12. 讲一下 linux 的进程间通信(这个就是八股文那几个了)
    13. 讲一下 linux 系统从开机到出现登陆界面的详细过程(讲了下 cpu 会从某个地址加载 bootloader ,然后 bootloader 会初始化哪些环境,然后把控制权交给内核了,最后内核从 init 函数开始启动,这里我了解的其实也不是很详细)
    14. 还有一道题和前面几道类似的题,记不起来了
    
    15.一道英语翻译题,应该是 I2C 总线手册上的(正常阅读没啥问题)
    

    我看了下我大概写出来了一半的题,被 hr 狠狠的羞辱说题目很基础,认为我大学没认真上 qwq...

    然后面的岗位是嵌入式工程师,没有要求必须要相关经验,之前做过三年机器人相关的开发。

    我这水平是不是菜到家了?

    52 条回复    2024-07-01 11:37:45 +08:00
    opticalproperti
        1
    opticalproperti  
       146 天前
    让哥们帮你做课堂作业是吧
    AFOX
        2
    AFOX  
    OP
       146 天前
    @opticalproperti 做完了,挂了,呜呜呜,我很想去的公司
    feather12315
        3
    feather12315  
       146 天前   ❤️ 1
    1 考察指针运算
    2 考察 bit 运算
    3 没想出来,暴力找?
    3 ,4 ,5 ,6 刷题,哎
    7 ,8 高等数学,微积分公式,高中的难度
    9 这个,确实但疼,能记住就会
    10 ,11 ,12 ,13 是 Linux OS 领域的,会不会看有没有接触过

    你面的公司考察得挺不错的。

    菜不至于,估计他们想找对计算机系统有兴趣、智商好(也就是大学好)的人吧。
    对计算机系统没兴趣,10 ,11 ,12 ,13 分布这么广泛工作时间短真不好搞;智商不好,多年不刷题 7 ,8 ,9 不好搞
    feather12315
        4
    feather12315  
       146 天前
    我有点好奇是哪家
    @AFOX #2
    AFOX
        5
    AFOX  
    OP
       146 天前
    @feather12315 第一题不是指针运算 qwq
    AFOX
        6
    AFOX  
    OP
       146 天前
    @feather12315 一家小公司,你想跳槽的话我可以告诉你
    ipwx
        7
    ipwx  
       146 天前   ❤️ 3
    hr 的评价不用太在意。根据我的经验,hr 要么是自己找的题库,要么是让开发给的题库,但是开发事儿多所以大概率是找的题库。

    因为 hr 都不会,所以看不出来每道题是不是 “基础”。
    AFOX
        8
    AFOX  
    OP
       146 天前
    @ipwx 开发找的,开发说我基本都是错的....我就回来自己算了下
    nagisaushio
        9
    nagisaushio  
       146 天前 via Android
    第一题只能说谁没事这么写。。
    2-6 说基础感觉没问题
    LHN
        10
    LHN  
       146 天前
    @AFOX #5 第一题输出应该是 2,1 吧
    AFOX
        11
    AFOX  
    OP
       146 天前
    @LHN 第一题是语法错误,很操蛋的题
    nagisaushio
        12
    nagisaushio  
       146 天前 via Android   ❤️ 1
    @LHN 其实是 2,5 。&a+1 会跳过 5 个元素,a+1 才是 1 个
    feather12315
        13
    feather12315  
       146 天前
    @AFOX #5

    `*(p-1)`太操蛋了。同事提醒恍悟:
    `&a == &a[0] == a`,`a`与`&a[0]`含义一样,但是`&a`与`a`含义不同,`&a`代表的是数组`a[5]`的地址,+1 就是`&a[6]`了。

    就是坑人的
    AFOX
        14
    AFOX  
    OP
       146 天前
    @AFOX 不对,我好像少了个括号,不过我写的是 2 ,1 ,反正是错了 qwq
    AFOX
        15
    AFOX  
    OP
       146 天前
    iOCZS
        16
    iOCZS  
       146 天前   ❤️ 1
    第二题好像可以用快速幂来做
    AFOX
        17
    AFOX  
    OP
       146 天前
    ``` C
    // 关于这道题,有两种情况,比如如果是下面这样,那输出就是 2 ,5
    int main() {
    int a[5] = {1, 2, 3, 4, 5};
    int *p = &a + 1;
    printf("%d, %d", *(a+1), *(p - 1));

    return 0;
    }

    // 如果是下面这样,那么编译报错
    int main() {
    int a[5] = {1, 2, 3, 4, 5};
    int *p = &(a + 1);
    printf("%d, %d", *(a+1), *(p - 1));

    return 0;
    }

    有点记不清当时题目有没有这个括号了,不过我都错了 qwq
    ```
    tool2dx
        18
    tool2dx  
       146 天前   ❤️ 1
    &a+1 会跳过 5 个元素, 我还第一次遇到,涨见识了。
    AFOX
        19
    AFOX  
    OP
       146 天前
    @iOCZS 因为要一个表达式,所以应该是 (number & number - 1) == 0
    iOCZS
        20
    iOCZS  
       146 天前
    @AFOX 的确如此
    AFOX
        21
    AFOX  
    OP
       146 天前
    来自 ChatGPT 对第一题的解释:

    1. **数组声明和初始化**:
    ```c
    int a[5] = {1, 2, 3, 4, 5};
    ```
    这行代码声明了一个包含 5 个整数的数组 `a`,并将其初始化为 1, 2, 3, 4, 5 。

    2. **指针初始化**:
    ```c
    int *p = &a + 1;
    ```
    这一行代码比较复杂。我们逐步解析:

    - `&a` 是数组 `a` 的地址。`&a` 的类型是 `int (*)[5]`,即指向一个包含 5 个整数的数组的指针。
    - `&a + 1` 表示将指针 `&a` 向前移动一个单位,这里的单位是整个数组 `a` 的大小(即 5 个整数的大小)。因此,它指向的是数组 `a` 之后的内存位置。
    - `&a + 1` 的类型仍然是 `int (*)[5]`。
    - 将 `&a + 1` 赋值给 `int *p` 时发生了隐式转换。最终 `p` 指向的是紧跟在数组 `a` 之后的内存位置。

    总结来说,`p` 指向的是数组 `a` 结束之后的那块内存位置。

    为了更好地理解这一点,我们来看一下内存布局:

    ```
    地址 值
    0x1000 1 (a[0])
    0x1004 2 (a[1])
    0x1008 3 (a[2])
    0x100C 4 (a[3])
    0x1010 5 (a[4])
    0x1014 ? (p 指向这里)
    ```

    在这里,`p` 指向地址 `0x1014`,也就是在 `a[4]` 之后的内存位置。

    ### 访问 `p`
    在这种情况下访问 `*p` 是未定义行为,因为它指向的是数组 `a` 结束之后的那块内存位置。

    你是否需要更多关于指针运算的信息,或者对这个代码有其他具体的问题?
    basncy
        22
    basncy  
       146 天前   ❤️ 2
    关于第一题, 联想后面的 I2C 和 TCP, 表面上是指针, 实际是通过 offset 快速定位. 通信协议里经常用 offset 取特定信息 .https://zh.wikipedia.org/zh-cn/IPv4

    但是 &a + 1 这种写法, vc++ 能过? 这么多年, linux 下从来没见过这种写法, 请 Linux 开发的面试官们手留情, 别误导青少年了.
    https://ibb.co/K7Lr73v
    AFOX
        23
    AFOX  
    OP
       146 天前
    @basncy
    我很同意你的第一点,面试官应该是想考察通过 offset 快速定位的知识点,但是感觉题没出好 hh

    第二点的话,我刚刚试了在 gcc 7.5 下还是可以编译通过,但是会报 warning 了。
    yxd19
        24
    yxd19  
       146 天前
    @basncy
    加个类型转换就行。
    https://godbolt.org/z/f6jb1P661

    也不用联想那么多。。联想到 C 里对多维数组的支持就理解了。
    yxd19
        25
    yxd19  
       146 天前
    第一题关键在于想到 sizeof(a)是啥(是 5*sizeof(int))
    basncy
        26
    basncy  
       146 天前
    @yxd19 #24 (&a + 1);已经越界了, code review 过不了. 加个(int*)哄编译器吗?
    ncisoft
        27
    ncisoft  
       146 天前
    题目出得不错,公司的研发团队素质挺好的 ^-^
    shijingshijing
        28
    shijingshijing  
       146 天前   ❤️ 1
    13 应该不会这么简单,要考虑是否启用 secure boot ,还有就是 x86 和 ARM 的启动还是有区别的。
    w568w
        29
    w568w  
       146 天前   ❤️ 1
    只说第一题哈,严格来说是不应该通过编译(或者说不鼓励写)的。

    关键在于 (&a + 1)。指针的加法运算仅对「指向数组元素的指针」有定义,而 a 显然不是一个数组元素。所以 &a+1 的定义是依赖编译器实现的。

    在连续的虚拟地址空间下,才能理想地认为 &a+1 代表 a 向后 5 个 sizeof(int) 字节的位置,然后再减 1 得到指向 a[4] 的指针。刻板地说,这题如果不加上这样那样的假设,那就是回答不了的。
    majula
        30
    majula  
       146 天前   ❤️ 1
    你这题让我想起来以前面过的一家公司(甚至有可能是同一家)

    题目类型也是先考察一下语法,然后几道算法题,几道 高数/线代/数理统计 题,几道 操作系统/计网/图形学 题,最后考察基英语读写能力。考察的方面很广,但都是基础题,并不难(尤其是对于应届生)

    不过最后是我把这家公司挂了(有三面邀约但我没去),因为面试官的态度令人不爽,让我对团队的技术氛围很担忧
    gpt5
        31
    gpt5  
       146 天前   ❤️ 1
    小时候打竞赛,老师都是要求手写,再上电脑验证。
    sillydaddy
        32
    sillydaddy  
       146 天前   ❤️ 1
    前 2 道题有些奇技淫巧的意思:
    第 1 题没啥意义,实际写代码基本不会用到。
    第 2 题题目太离奇了,最好是改成选择题,给出 7,8 个选项让选,就能知道是否熟悉 bit 运算了,谁没事去记这些奇技淫巧啊。
    cwxiaos
        33
    cwxiaos  
       146 天前 via iPhone   ❤️ 1
    第二题直接利用二进制数和 2 的幂的关系来做,这题我印象很深,配合 mask 还能做 4 的幂等等
    cwxiaos
        34
    cwxiaos  
       146 天前 via iPhone
    9 题不能乱填数字,$A \prime = \frac{A^*}{|A|}$,这题一样看过去没思路,用定义好像有点难算
    newtype0092
        35
    newtype0092  
       146 天前
    看到地址加整数就不想看了,出题的估计是 C 语言之父谭大师的门下弟子。。。
    smdbh
        36
    smdbh  
       146 天前
    要写完整的话,1 小时我做不完。谁手撸高斯消元啊。
    现在觉得面试做卷子太浪费大家的时间了,写的人累,看的人也累。其实面对面聊个 15 分钟,基本就能看出水平了
    AFOX
        37
    AFOX  
    OP
       146 天前
    @smdbh 他们不给我面聊的机会 qwq ,我线下面试都没见到面试官….
    shijingshijing
        38
    shijingshijing  
       146 天前
    @AFOX 比较好奇这个职位的 JD 是什么,这些题目分布的范围很广,有的还有一定深度,senior 级别的?
    geelaw
        39
    geelaw  
       146 天前   ❤️ 1
    第一个问题,我的理解是编译失败,因为 &a 是指向 int[5] 的指针,于是 &a + 1 也是指向 int[5] 的指针,它指向整个数组之后的 past-the-end 位置,然而 p 是指向 int 的指针,这是两个不兼容类型,当然初始化不能成功。至于具体的编译器接受此代码,只能说是不合标准。

    编译失败的原因同

    typedef int my_array_t[5]; /* 方便看清楚 */
    my_array_t a;
    my_array_t *q = &a;
    my_array_t *r = q + 1;
    int *p = r; /* 当然是无稽之谈 */

    第二个问题,如果你说的是 unsigned 类型,那么 x != 0 && (x & (x - 1)) == 0 ,如果是 int 类型还需要判断符号。

    后面略,这些问题是惟手熟尔。

    @basncy #26 C 和 C++ 里面恰好超过最后一个元素位置的指针是有效的,只是不允许解除引用。考虑 int a[5]={}; int *begin = a, *end = a + 5; while (begin != end) printf("%d\n", *begin++); 当然是 OK 的代码。

    @w568w #29 a 确实不是数组元素,但是对于指针运算来说,单个对象等同于具有一个元素的数组对象的惟一元素。也就是说 int b; int *begin = &b, end = &b + 1; 是正确的代码。
    hefish
        40
    hefish  
       145 天前
    我最讨厌用指针骚操作,又不用括号的代码。 可维护性极差, 写的人容易沾沾自喜,不利于团队和谐。 再牛逼也要当害群之马开掉。
    agagega
        41
    agagega  
       145 天前   ❤️ 1
    第一题有问题。
    第二题,2 的 N 次幂意味着二进制表示里只有一个 1 ,这种数减 1 就是后面的位全为 1 ,所以是 n!=0 且 n&(n-1)==0 (假设 n 是 unsigned )
    longlonglanguage
        42
    longlonglanguage  
       145 天前
    人形编译器
    mooyo
        43
    mooyo  
       145 天前
    哈哈哈哈想起大学的考试就是这样手写代码,太特么抽象了
    Greendays
        44
    Greendays  
       145 天前
    别说手写了,让我用记事本写我也写不出什么东西。
    kneo
        45
    kneo  
       145 天前
    面试是需要刷题的。把不会的都刷明白了。面试一次就是成长一次,别沮丧。
    nenseso
        46
    nenseso  
       145 天前
    第 2 题考虑 N 是负数的情况吗,如果考虑的话还挺复杂的
    AFOX
        47
    AFOX  
    OP
       145 天前
    @nenseso 没说考虑不考虑
    panda1001
        48
    panda1001  
       144 天前 via Android   ❤️ 1
    第一题主要意识到 c 语言变量的 type 是啥,对应 type 指针的+1-1 的步长是多少 byte 。gdb 打印可以看得到,确实是 c 工程的基本功
    题目看起来越界算是 hack 写法,觉得不规范不影响考察的重点,可以换成多维数组或者嵌套结构体,多级指针一样可以考察

    第二题搜搜 github 的 awesome bit
    dode
        49
    dode  
       144 天前
    第二题一直循环除 2 ,%2 呢
    yanqiyu
        50
    yanqiyu  
       144 天前   ❤️ 1
    1. UB ,&a 加减直接就 UB 到家了
    2. x ^ (1 << N) == 0 (如果是给定的 N ,否则 x ^(x-1) == 0 ),但是我不会写这种代码,读代码自己也坐牢
    3. 2, 3~sqrt(N)的奇数逐个除法?不过遇到质因数 q 就马上迭代 p/q, 从已经找到的质因数开始往下走,不知道有没有高效的算法
    4~5: 同
    7~8: 微积分我能不能直接写原函数进去,还是必须写数值方法,数值方法要老命了
    9. 基础代数,这我熟()
    10,11:我写这种东西离不开文档,记不住
    12,13:八股文
    yanqiyu
        51
    yanqiyu  
       144 天前
    草,才写完就发现第二个写错了是
    x ^ (1 << N) == 0 (如果是给定的 N ,否则 x & (x-1) == 0 )
    ccpp132
        52
    ccpp132  
       143 天前
    第二题其实搞嵌入式感觉挺常用的,位运算在别的领域看起来是 trick ,但底层一点还蛮常用的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2922 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 14:39 · PVG 22:39 · LAX 06:39 · JFK 09:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.