zoukankan      html  css  js  c++  java
  • C C++ 常被人问的问题分析

    正文  -  开始了, 直接扯淡

      以下都是自己面试中遇到的常见的问题.如有不妥的地方就当见笑了. 哈哈

     宝剑索引

    1. 谈谈你们服务器的架构吧.

    分析:

      假如这是第一个问题, 你可以走了. 可能各方面原因他不想要你. 或者其它意外已经有人更适合了. 

    或者只是为了学一点东西.哈哈.一般面试游戏服务器开发的时候,这方面一定会问的. 关于游戏服务器架构,

    需要自己努力积累是硬功夫.没有个100页doc难搞下来.且不同公司架构还是很不一样.

    只是为了应对面试,可以参照

       MMORPG服务器架构  http://www.blogjava.net/landon/archive/2012/07/14/383092.html

       云风的 BLOG http://blog.codingnow.com/

    至少可以简单扯一点, 对吧.通常这个问题决定你最终资格,极其重要, 也是咱们干程序的一定要积累的.

    2. 有时候也会问,项目组正在开发中问题. 因公司而异.

    例如怎么设计跨服对战的业务, 怎么设计一个棋牌的随机排序算法.

    分析: 

      1)对于跨服对战, 当初是个卡牌战斗类, 简单些. 按照老套路

        a) 每个服前10名, 特定时间报名

        b) 按照服务器id,玩家id 构建一个新服

        c) 参照老套路了, 有了新服对战开始了...

      2) 对于棋牌的随机算法, 基本都是一个傻大哈方法

    //
    //    简单棋牌随机算法
    //  chess    : 存放棋牌的数组
    //    len        : 棋牌处理长度
    //
    void chess_rand(char chess[], int len) {
        if (!chess || len < 2)
            return;
        
        for (int i = 0; i < len; ++i) {
            int j = rand() % len;
            if (i != j) {
                char c = chess[i];
                chess[i] = chess[j];
                chess[j] = c;
            }
        }
    }

    具体就是你做过就按照你做过的思路说, 没做过就按照自己思路实诚一点说. 哈哈

    3. 用过什么数据, 什么数据库引擎,优化什么的扯个淡.

    分析:

      一般都是mysql, 问几个简单的sql查询.然后问innodb 和 myisam 区别.

      MyISAM和InnoDB的区别 

      Mysql几种索引类型的区别及适用情况

    其实现在开发我觉得从C++ 软件开发层面. mysql没有mariadb优势大, 高级层面的优化交给数据库开发者. 业务层开发也就是索引等等.

    到这里有时候会细问DB Server 设计. 缓存服务器设计等. 因公司业务不同, 说一说完全可以.

      高并发服务器的设计--缓存的设

      想在C++游戏服务器中实现热更,数据缓存要如何做呢?

    也能扯个半天.

    4. 那开始扯除了架构之外最重要的了, 多线程设计了.

    分析:

      首先一般面试官会这样开头, 啊, 那线程和进程的异同是啥呀?这东西常问, 不管是应届菜鸟还是老油条.

    因为面试官多数问自己以前被别人问的, 可以参照知乎上讨论, 基本都理解了, 可以来回扯了.

      线程和进程的区别是什么?

    当然这只是个开头,有时候会让你现场写代码. 那就需要自己回顾 pthread POSIX 那套了. 当然遇到必须手写的话, 说明那个人也是为难你.

    你也可以放心了. 后面愉快自然些. 他也许还没你懂得多. 详细的可以理解下面知识.

      [转]关于多线程并发:每个开发人员都应了解的内容

    其实关于线程真实工作中, 实战经验为零. 最扯淡的是, 会说的不一定会写, 会写的难说. 仍然推荐可以看看 云风 的 github,

    上面多线程代码不少. 还有就是POSIX 多线程那本书特别经典.很给力.

    分享个多个线程顺序循环执行的代码, 哈哈如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    // 测试线程数量
    #define _INT_THS    (3)
    
    struct threadarg {
        pthread_t tids[_INT_THS];
        sem_t sids[_INT_THS];
    };
    
    // 简单运行函数
    static void * _run(void * arg) {
        int i = -1, j = -1;
        struct threadarg * ths = arg;
        pthread_t tid = pthread_self();
        pthread_detach(tid);
    
        // 确定这是第几个线程
        while (++i < _INT_THS)
            if (pthread_equal(tid, ths->tids[i]))
                break;
        
        // 循环个特定遍数就结束吧
        while (++j < _INT_THS) {
            // 第 i 个线程, 等待 第 i - 1 个线程, 输出 'A' + i 
            sem_wait(ths->sids + (i - 1 + _INT_THS) % _INT_THS);
            putchar('A' + i);
            // 第 i 个线程, 激活 第 i 个信号量
            sem_post(ths->sids + i);
        }
    
        return NULL;
    }
    
    //
    // 写个测试线程信号量代码
    // 开启 _INT_THS 个线程, 顺序打印数据 A->B->C->...->A->B->....
    //
    void test_pthread_sem(void) {
        // 开始初始化了
        int i, j;
        struct threadarg targ;
        
        // 先初始化信号量,后初始化线程
        for (i = 0; i < _INT_THS; ++i) {
            // 0 : 表示局部信号量当前可用; 0 : 当前信号量值为0
            if (sem_init(targ.sids + i, 0, 0) < 0)
                goto __for_exit;
        }
    
        // 开启线程
        for (j = 0; j < _INT_THS; ++j) {
            // 开启三个线程
            if (pthread_create(targ.tids + j, NULL, _run, &targ) < 0)
                goto __for_exit;
        }
    
        // 激活第一个线程, 输出 'A' 开头
        sem_post(targ.sids + _INT_THS - 1);
    
        // 中间等待一些时间吧
        getchar();
    
    __for_exit:
        // 注意的是, 假如信号量释放了, 线程还在跑, 会异常
        for (j = 0; j < i; ++j)
            sem_destroy(targ.sids + j);
    #ifdef __GNUC__
        exit(EXIT_SUCCESS);
    #endif
    }

    编译指令是

    test_pthread_sem.exe:test_pthread_sem.c
        gcc -g -Wall --entry=$(basename $@) -nostartfiles -o $@ $^ -lpthread

    后面也可以参照下面链接学习一下.

       信号量与条件变量的区别

    5. 那再一次到语法基础部分了. C++各种语法妖魔来了. 哈哈

    存在这样一个情况. 一个函数玩家new了个对象. 但是忘记delete了.直接return了,怎么搞别内存泄漏.

    分析:

      其实这类C++问题, 在C++最经典的书籍中都有解释. 一般人会回答用智能指针. 这时候面试官和蔼的告诉你不行.

    你sb了. 那怎么搞哈哈. 如果做过很简单,没做过就xxx了. 其实这时候面试官希望你自己实现个简单的智能指针. 其实这个

    很好搞, 本质就是C++栈上变量在函数返回时候会退栈,执行变量析构函数.其实再扯一点,这种特性本质就是编译器在编译的时候

    ,帮我们插入了这些构建和清理的代码而以. 一个简单的代码如下:

    template<typename T> class AutoPtr {
        T * _ptr;
    public:
        explicit AutoPtr(T * ptr) {
            _ptr = ptr;
        }
    
        ~AutoPtr(void) {
            delete _ptr;
        }
    
        T & operator*() {
            return *_ptr;
        }
    
        T * operator->() {
            return _ptr;
        }
    };

    用法也特别简单

        class People { };
        AutoPtr<People> ptr(new People());

    到这里就各种妖魔鬼怪出来. 例如会继续问placement new 的用法. 呵呵, 各种奇葩问题来了.

      C++ 中为什么没有placement delete

    参照上面资料看的挺有意思.一般而言 placement new 用在指定对象分配上.

    #define _INT_XX (108)
    char
    xx[_INT_XX]; T * p = new(xx) T;

    当然还有更加奇葩的在构造函数和析构函数中抛出异常. 这种问题面试一问基本上基础部分就接近尾声了. 能扯个30min吧.

      构造函数、析构函数抛出异常的问题

      关于构造函数 和 析构函数 能否抛出异常的讨论

    说白了, C++ 的 new 和 delete 还是很有搞头的 O(∩_∩)O哈哈~  ┻┳|・ω・)问我?

    6. 又是最简单的虚函数了, 必问. 直接搞起吧.

      虚函数virtual可以说是C++面向对象的所有. 面试时必问的基础中的基础.(✪ω✪) 让我们来剖析其中的秘密吧.  

    virutal虚函数围绕本质在于编译器帮我们在类中插入了 __vfptr 变量. 例如下面例子.

    以上就是虚函数实现原理.通过汇编好实现.通过纯C++实现有点难搞, 需要记住类型.

    7. 那到了STL部分了,也是常有的. 搞一搞吧.

      STL是必问的,其实问的都很简单. 多数是看看下面STL代码是够有问题. 奥, 常见的有各种容易的区别.

    回答的时候需要抓住迭代器特点. 存储结构特点. 例如只有vector和deque是顺序存储并且支持随机迭代器的.

    有的会问怎么删除vector中是偶数的迭代器. 手写代码.

        int i = 0;
        std::vector<int> vs;
        std::vector<int>::iterator it = vs.begin();
        while (it != vs.end()) {
            if (++i % 2 == 0)
                it = vs.erase(it);
            else
                ++it;
        }

    主要是注意一下迭代器失效的情况.

      C++STL常见面试题

    后面扯扯C++11方面知识. 其实哈哈, 都C++17了, 还11. 说白了高级程序员,

    高级的地方不在于功底, 不在于能力, 最重要的是业务熟悉度, 和当前公司的业务匹配度.

    8. TCP 和 epoll 出现了. 其实也很简单.

      网络这块也是逃不掉的.什么四次分手, 3次握手是必须的.

       TCP相关面试题总结

      TCP滑动窗口控制流量的原理

    这里TCP搞完了, 那开始问select, epoll 什么的. 可以了开始考验你api 和 内核的理解了

      linux下epoll如何实现高效处理百万句柄的

       epoll 底层实现源码分析

      epoll实现机制分析

    套路都差不多. 多总结总结, 这里面试官一问能扯个5-10min吧. 毕竟除了老一辈的程序员功底好些.

    新的对于这些也只是 -->  "编程5min扯淡2h" ! O(∩_∩)O哈哈~  关于epoll 实际用法可以参照我的下面博文

      C高级 服务器内核分析和构建 (一)  

    后记 - 新的开始, 哈哈

       以上就是老鸟找工作必问的问题, 深入的扯能够扯好久.... 错误是难免的, 欢迎指正, 共同提高~~~

       虚虚实实  http://music.163.com/#/m/song?id=189433&userid=16529894

      

                       人生没有重来, 贪婪有何不可  -|-  对不起我的兄弟和我的妹子

  • 相关阅读:
    利用apktool反编译apk
    CF459E Pashmak and Graph (Dag dp)
    CF919D Substring (dag dp)
    BZOJ 1398: Vijos1382寻找主人 Necklace(最小表示法)
    LUOGU P3048 [USACO12FEB]牛的IDCow IDs(组合数)
    LUOGU P2290 [HNOI2004]树的计数(组合数,prufer序)
    小球放盒子 (组合数总结)
    LUOGU P2294 [HNOI2005]狡猾的商人(差分约束)
    LUOGU P4159 [SCOI2009]迷路(矩阵乘法)
    bzoj 1196: [HNOI2006]公路修建问题(二分+贪心)
  • 原文地址:https://www.cnblogs.com/life2refuel/p/6684145.html
Copyright © 2011-2022 走看看