linux c/c++面试知识点整理(四)

31、printf输出时在%和字母之间插入数字表示场宽的规则?

       当实际长度不够时, 右对齐;
       如果字符串或者整数的长度超过说明的场宽, 则按其实际长度输出;
       如果是浮点数, 若整数部分超过了说明的整数位场宽, 则按其实际长度输出, 若是小数部分超过了说明的小数位场宽, 则按说明的宽度以四舍五入输出。

32、逗号表达式?

       例如:printf(“%d %d %d\n”, (a,b,c),b,c);
       那么将输出才c,b,c这3个值,因为逗号表达式的值就是表达式中最后一个表达式的值;
       即:表达式1,表达式2,表达式3…表达式n 就是表达式n的值。

33、c语言中标识符第一次字符必须是什么?

       第一个字符必须是字母或者下划线,不能是数字。

34、数据流程图(DFD图)是什么

       DFD图是结构化方法的需求分析工具。

35、hash_set和set的区别?

       hast_set以hashtable为底层机制,而set以RB-tree(红黑树)为底层机制;
       set有元素自动排序功能,而hash_set没有;
       set可在logN下完成查找、插入和删除等操作,hash_set可在常数时间复杂度下完成这些操作,但是取决于哈希表的负载情况;
       hast_multiset则允许键值重复;

36、static的用途以及类中使用static的规则。

       用途:
       static限制变量的作用域;
       static不显示的初始化时,会被隐式的初始化为0;
       static设置变量的存储域,变量存储在静态区;
       类中使用static的规则:
       不能通过类名来调用类的非静态成员函数,可以调用静态成员函数;
       类的对象可以使用静态成员函数和非静态成员函数;
       类的静态成员函数中不能使用类的非静态成员,因为此时静态成员函数已经分配了存储空间,而非静态成员却还没有分配内存,相当于变量声明了但是未定义就直接使用;
       类的非静态成员函数(包括常函数)可以使用类的静态成员函数和静态成员变量,并且非静态成员常函数可以修改静态成员变量;
       类的静态成员变量必须初始化以后才能使用;

37、数据库三范式

       第一范式:数据库表中的所有字段值都是不可分解的原子值,比如地址字段,根据需求拆分成省份和城市更方便
       第二范式:在一个数据库表中,一个表中只能保持一种数据,不可以把多种数据保存在同一张数据库表中,比如订单信息和商品信息就要分为两个表
       第三范式:每一列数据都和主键直接相关,而不能间接相关,就是说字段值要和主键有直接关系
巴斯-科德范式:第三范式的一个子集,在第一范式基础上,任何非主属性不能对主键子集依赖。

38、网络编程中设计并发服务器,使用多进程和多线程,请问有什么区别?

       1)两者都可以提高程序的并发度,提高程序运行效率和响应时间
       2)线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。

39、可以用作switch的参数的类型

       int、short、byte、char、long
       基本上可以转换为整数的类型都可以用作switch的参数。

40、linux使用多线程的方法

       互斥锁、信号量、条件变量、全局变量、读写锁。
       1)互斥锁:当线程A锁定了互斥变量时,线程B再去锁定时就会被挂起,直到A解锁。
       注意:当线程要不断的去轮询检查某个条件以判断是否可以操作需同步的数据时,可使用条件变量提高效率。
demo如下:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex;

void *print_msg(void *arg)
{
    int i = 0;
    pthread_mutex_lock(&mutex); //互斥锁加锁
    for (i = 0; i < 20; i++)
    {
        printf(" i = %d\n", i);
        usleep(200);
    }
    pthread_mutex_unlock(&mutex);

}

int main()
{
    pthread_t id1, id2;
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&id1, NULL, print_msg, NULL);
    pthread_create(&id2, NULL, print_msg, NULL);
    pthread_join(id1, NULL);  //使主线程等待该线程结束后才结束,否则主线程很快结束,该线程没有机会执行
    pthread_join(id2, NULL);
    pthread_mutex_destroy(&mutex);

    return 0;
}

       2)信号量:实际是一个整数,只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减1。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加1,但是sem_wait返回之前还是会将此value值减1。
demo如下:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
#include <stdlib.h>

void *thread_func(void* msg);
sem_t sem;
sem_t sem_add;

#define MSG_SIZE 512

int main()
{
    int res = -1;
    pthread_t thread;
    void *thread_result = NULL;
    char msg[MSG_SIZE];

    res = sem_init(&sem, 0, 0);
    if (res == -1)
    {
        printf("sem init failed\n");
        exit(-1);
    }

    res = sem_init(&sem_add, 0, 1);
    if (res == -1)
    {
        printf("sem_add init failed\n");
        exit(-1);
    }

    res = pthread_create(&thread, NULL, thread_func, msg);
    if (res != 0)
    {
        printf("pthread_create failed\n");
        exit(-1);
    }
    printf("input some text. Enter 'end' to finish...\n");
    
    sem_wait(&sem_add);
    while(strcmp("end\n", msg) != 0)
    {
        if (strncmp(msg, "TEST", 4) == 0)
        {
            strcpy(msg, "copy_data\n");
            sem_post(&sem);
            sem_wait(&sem_add);
        }
        fgets(msg, MSG_SIZE, stdin);
        sem_post(&sem);  //sem信号量加1,让子线程开始执行
        sem_wait(&sem_add);  //sem_add信号量减1,等待子线程处理完成

    }

    printf("waiting for thread to finish...\n");
    res = pthread_join(thread, &thread_result);
    if (res != 0)
    {
        printf("pthread_join faild\n");
        exit(-1);
    }

    printf("thread joined\n");

    sem_destroy(&sem);
    sem_destroy(&sem_add);
    exit(0);

    return 0;
}

void* thread_func(void* msg)
{
    char *ptr = (char*)msg;
    sem_wait(&sem);
    while(strcmp("end\n", ptr) != 0)
    {
        int i = 0;
        for (; ptr[i] != '\0'; ++i )
        {
            if (ptr[i] >= 'a' && ptr[i] <= 'z')
            {
                ptr[i] -= 'a' - 'A';
            }
        }
        printf("you input %d characters\n", i - 1);
        printf("to uppercase: %s\n", ptr);

        sem_post(&sem_add);
        sem_wait(&sem);
    }
    sem_post(&sem_add);
    pthread_exit(NULL);
}

       3)条件变量:经常和互斥锁一起使用,使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程会解开相应的互斥锁并等待条件发生变化,一旦其他的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此变量阻塞的线程,这些线程将重新锁定互斥锁并重新测试条件是否满足。
       pthread_cont_init()
       pthread_cont_destroy()
       pthread_cont_wait() //线程解开mutex指向的锁并被条件变量阻塞
       pthread_cont_timedwait() //多了时间参数,当时间过了以后,即使条件变量不满足,阻塞也被解除
       pthread_cont_signal()/pthread_cont_broadcast //唤醒被条件变量阻塞的线程。
demo见我的另外一篇文章:
linux c/c++ 面试题目整理(四)中的第34题
       4)读写锁:可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁。
       当读写锁是写加锁状态时,在这个锁被解锁前,所有试图对这个锁加锁的线程都会被阻塞;
       当读写锁是读加锁状态时,其他线程可以读模式得到访问权,但是以写模式对它进行加锁的线程都将被阻塞;
       当读写锁是在读模式加锁状态时,如果有其他线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,避免读模式锁长期占用,而写模式所长期阻塞;
读写锁适用于对数据读的次数比写的次数多的情况。
       API接口:
       初始化和销毁:
       int pthread_rwlock_init();
       int pthread rwlock_destroy();
       读加锁、写加锁、解锁:
       pthread_rwlock_rdlock();
       pthread_rwlock_wrlock();
       pthread_rwlock_unlock();
       非阻塞获得读锁和写锁:
       pthread_rwlock_tryrdlock();
       pthread_rwlock_trywrlock();
demo如下

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define Read_Num 2

pthread_rwlock_t lock;

class Data
{
    public:
        Data(int i, float f): I(i), F(f){}
        int GetI()
        {
            return I;
        }

        float GetF()
        {
            return F;
        }

    private:
        int I;
        float F;
};

Data *pData = NULL;

void *read(void *arg)
{
    int *id = (int*)arg;
    while(true)
    {
        pthread_rwlock_rdlock(&lock);
        printf(" reader %d is reading data\n", *id);
        if (pData == NULL)
        {
            printf("data is NULL\n");
        }
        else
        {
            printf("data: I = %d, F = %f\n", pData->GetI(), pData->GetF());
        }
        pthread_rwlock_unlock(&lock);
    }
    pthread_exit(0);
}

void *write(void *arg)
{
    while(true)
    {
        pthread_rwlock_wrlock(&lock);  //写锁加锁后,解锁前,所有试图对该锁加锁的线程都会被堵塞
        printf("writer is wiriting data:\n");
        if (pData == NULL)
        {
            pData = new Data(2, 2.2);
            printf("writer is writing data: %d, %f\n", pData->GetI(), pData->GetF());
        }
        else
        {
            delete pData;
            pData = NULL;
            printf("wirter free the data\n");
        }
        pthread_rwlock_unlock(&lock);

    }
    pthread_exit(0);
}

int main()
{
    pthread_t reader[Read_Num];
    pthread_t writer;
    for (int i = 0; i < Read_Num; i++)
    {
        pthread_create(&reader[i], NULL, read, (void*)&i);
    }
    pthread_create(&writer, NULL, write, NULL);
    while(1)
    {
        sleep(1);
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容