剑指XX游戏读后感(2):网易2011笔试题详解/sizeof和strlen/交换双向链表节/dll和lib和exe/8叉树减色/11盆花组合/宠物技能遗传/看virtual继承代码写输出

请区分sizeof和strlen?

<pre name="code" class="cpp">char array[] = "0123456789";
char* pointArray = "0123456789";
char arrayBig[100] = "0123456789";
cout << sizeof(array) << endl;             //11    sizeof统计了占用字节数,10个字节+\0
cout << sizeof(pointArray) << endl;              //8      指针大小。PS:我用的是64bit的PC
cout << sizeof(arrayBig) << endl;      //100   数组统计内存中预分配的大小
cout << sizeof(*array) << endl;        //1          以下三个都表示首字符,sizeof当然为1
cout << sizeof(*pointArray) << endl;         //1
cout << sizeof(*arrayBig) << endl;     //1
cout <<strlen(array) << endl;          //10         strlen表示了真实的字符串长度长度
cout << strlen(pointArray) << endl;          //10
cout <<strlen(arrayBig) << endl;   //10

 

什么是用户级线程和内核级线程?区别

  1. 内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。
  2. 用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。
  3. 用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。
  4. 在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。
  5. 用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。
用户级线程优点:
  • 线程的调度不需要内核直接参与,控制简单。
  • 可以在不支持线程的操作系统中实现。
  • 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。
  • 允许每个进程定制自己的调度算法,线程管理比较灵活。
  • 线程能够利用的表空间和堆栈空间比内核级线程多。
用户级线程缺点:
  • 资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用。
  • 同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。另外,页面失效也会产生同样的问题。
内核级线程优点:当有多个处理机时,一个进程的多个线程可以同时执行。
内核级线程缺点:由内核进行调度,切换开销大

从C++文件到生成exe 文件经过哪三个步骤?(第二次出现)

有个二维数组 A(6*8),每个元素占 6 字节,起始地址为 1000,请问最后一个元素 A[5][7]的起始地址为??? 数组A占内存大小为??? 假设以行优先,则A[1][4]起始地址为?

  • 1000 + (6*8-1)*6 = 1282.起始地址为1282
  • 6*8*6 = 288
  • 明确题义:二维数组为6行8列,行主序[1][4]的话,1000 + ( 1*8+4 )*6 = 1072.(行主序:先填满1行,再换行)

用C语言把双向链表中的两个结点交换位置,考虑各种边界问题?

bool exchange(Linklist* list, Node* L, Node* R){
    if( L == NULL || R == NULL){    //预防空指针
        return false;
    }else if( L == R ){     //两个被交换节点指向同一个节点
        return true;
    }else{
        bool orderWrong = false;        //左右顺序错误标志位
        for(Node* cur = L; cur != list->head; cur = cur->pre){  //检测顺序错误
            if(L == R){
                orderWrong = true;
                break;
            }
        }
        if(orderWrong == true || list->head == R){      //检测顺序错误
            Node* tmp = L;
            L = R;
            R = tmp;
        }
        Node*  LL = L->pre;
        Node*  LR = L->next;
        Node*  RL = R->pre;
        Node*  RR = R->next;
        if( RL == L || LR == R){        //两个被交换节点相邻
            R->next = L;
            L->pre = R;
        }else{          //不相邻
            L->pre = RL;
            RL->next = L;
            R->next = LR;
            LR->pre = R;
        }
        if(LL != NULL){         //是否包含头节点
            LL->next = R;
            R->pre = LL;
        }else{
            list->head = R;
        }
        if(RR != NULL){     //是否包含尾节点
            RR->pre = L;
            L->next = RR;
        }else{
            list->tail = L;
        }
        return true;
    }
}

注意,双向链表的指针较多,很容易搞混,所以推荐使用如下方法:先用多个指针固定住所有涉及的节点,本题中涉及6个:L和R为被交换节点,LL,LR,RL,RR为相邻接的4个节点,然后就好做很多了。如果面试官要求使用更少的指针,可以在照这么写完以后,再用指针替换。可以大大提高正确率以及减少错误!


*.dll,*.lib,*.exe 文件分别是什么,有什么区别? 


lib是静态的库文件,dll是动态的库文件。

  • 所谓静态就是link的时候把里面需要的东西抽取出来安排到你的exe文件中,以后运行exe的时候不再需要lib。 
  • 所谓动态就是exe运行的时候依赖于dll里面提供的功能,没有这个dll,exe无法运行。 
lib, dll, exe都算是最终的目标文件,是最终产物。而c/c++属于源代码。源代码和最终 目标文件中过渡的就是中间代码obj,实际上之所以需要中间代码,是你不可能一次得到目 标文件。比如说一个exe需要很多的cpp文件生成。而编译器一次只能编译一个cpp文件。这 样编译器编译好一个cpp以后会将其编译成obj,当所有必须要的cpp都编译成obj以后,再统 一link成所需要的exe,应该说缺少任意一个obj都会导致exe的链接失败.

使用八叉树算法把24位真彩色转化成 256色。24位真彩色包括 R,G,B颜色,每种颜色8 位?


稍后补充,算法略长...


有 11 盆花,围成一圈,要求每次组合时,每盆花相邻的两盆花与上次不同,请问有多少排列方法?


学长不会,我也不会,暂时没有思路,看看有没有高手会...


2 只宠物合成,1只有 5技能,1 只有4 技能,每个技能有 a%概率遗传,请问刚好有7 个技能遗传成功的概率是?


分情况讨论,该题有三种组合方式可以达到目标:

  1. 3+4:(a%)^7 * C(5,3)
  2. 4+3:(a%)^7 * C(5,4) * C(4,3)
  3. 5+2:(a%)^7 * C(4,2)
总概率就是三个情况的和。

请说出下列算法的输出:


class A{
public:
	A(){cout<<"1";}
	A(A &a){cout <<"2";}
	virtual ~A() {cout<<"3";}
};
class B:public A{
public:
	B(){cout<<"4";}
	B(B &b){cout<<"5";}
	~B(){cout<<"6";}
};
int main(){
    A* pa = new B();
	delete pa;
	return 0;
}

答案为:1463。父类先出生后死,子类后出生先死。有关virtual的,参见我的另一篇日志: 虚函数相关的知识

---------------------------------------------------------------------
本系列第二篇也结束了,深感网易游戏笔试的算法考得还是蛮深的,看来,各个细节以后都要考虑到,以免到时候折戟沉沙,共勉!加油!
希望我凭借着自己的努力,能够让自己变得更强!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值