网易的笔试题

1. 给定一个点分IP地址表示,写个程序把它转换成相应的32位的无符号整数并输出,如果输入不是合法数据,就返回0.


这个题目如何利用好标准输入输出,其实可以很容易判断出不合法的输入用例,不过当时没有想好,导致这个题目没有AC。


后来回去写的代码如下:




[cpp] view plaincopyprint?
#include <stdio.h>  
#include <string.h>  
bool checkpoint(char *str){  
  
    int npoint = 0;  
    while(*str){  
        (*str) == '.' ? npoint++ : npoint;  
        if(*(str) != '.' && !((*str) <= '9' && (*str) >= '0')) return false;  
        str++;  
    }  
    return npoint == 3;  
}  
  
bool checkinrange(int addr[4]){  
    for(int i = 0; i < 4; i++){  
        if(addr[i] > 255){  
            return false;  
        }  
    }  
    return true;  
}  
bool convertIP(char s[], int addr[4]){  
    char tmp[128];  
    if(checkpoint(s)){  
        sscanf(s, "%d.%d.%d.%d",addr, addr + 1, addr + 2, addr + 3);  
        sprintf_s(tmp, sizeof(tmp), "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);  
        if(strcmp(s, tmp) == 0 && checkinrange(addr)){  
            return true;  
        }  
  
        //sprintf_s()  
    }  
    return false;  
}  
int main()  
{  
    char s[128] = {0};  
    int addr[4];  
      
    while(scanf("%s", s) != EOF){  
        memset(addr, -1, sizeof(addr));  
        if(convertIP(s, addr))  
        {  
            unsigned int result = 0;  
            result = addr[0] * (0x1 << 24);  
            result += addr[1] * (0x1 << 16);  
            result += addr[2] * (0x1 << 8);  
            result += addr[3];  
            printf("%u\n", result);  
        }  
        else{  
            printf("-1\n");  
        }  
  
    }  
  
    return 0;  
}  
#include <stdio.h>
#include <string.h>
bool checkpoint(char *str){


int npoint = 0;
while(*str){
(*str) == '.' ? npoint++ : npoint;
if(*(str) != '.' && !((*str) <= '9' && (*str) >= '0')) return false;
str++;
}
return npoint == 3;
}


bool checkinrange(int addr[4]){
for(int i = 0; i < 4; i++){
if(addr[i] > 255){
return false;
}
}
return true;
}
bool convertIP(char s[], int addr[4]){
char tmp[128];
if(checkpoint(s)){
sscanf(s, "%d.%d.%d.%d",addr, addr + 1, addr + 2, addr + 3);
sprintf_s(tmp, sizeof(tmp), "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
if(strcmp(s, tmp) == 0 && checkinrange(addr)){
return true;
}


//sprintf_s()
}
return false;
}
int main()
{
char s[128] = {0};
int addr[4];

while(scanf("%s", s) != EOF){
memset(addr, -1, sizeof(addr));
if(convertIP(s, addr))
{
unsigned int result = 0;
result = addr[0] * (0x1 << 24);
result += addr[1] * (0x1 << 16);
result += addr[2] * (0x1 << 8);
result += addr[3];
printf("%u\n", result);
}
else{
printf("-1\n");
}


}


return 0;
}
2. 给出大小为N的数组,用最快的办法找出前M个大的数字


这个题目可以用一个大小是M的最小堆来实现,初始建堆用数组前M个建好后,如果后面的元素a[i] 大于堆顶元素,那么就删除堆顶,插入新的元素。








[cpp] view plaincopyprint?
#include <queue>  
#include <vector>  
using namespace std;  
  
int main(){  
  
    priority_queue<int,std::vector<int>, std::greater<int>> q;  
  
    int n,m;  
    int num;  
    scanf("%d%d", &n, &m);  
  
    int i;  
    for(i = 0; i < m; i++){  
        scanf("%d", &num);  
        q.push(num);  
    }  
  
    for( ; i < n; i++){  
        scanf("%d", &num);  
  
        if(num > q.top()){  
            q.pop();  
            q.push(num);  
        }  
    }  
}  
#include <queue>
#include <vector>
using namespace std;


int main(){


priority_queue<int,std::vector<int>, std::greater<int>> q;


int n,m;
int num;
scanf("%d%d", &n, &m);


int i;
for(i = 0; i < m; i++){
scanf("%d", &num);
q.push(num);
}


for( ; i < n; i++){
scanf("%d", &num);


if(num > q.top()){
q.pop();
q.push(num);
}
}
}






一面:


面试官是一个看起来比较技术的MM,MM上来什么也没有问,直接来算法。


题目1. 一个人在网上做项目,加入每天都有很多项目可以选,每个项目都有一个开始时间和截止时间,假设每个项目的钱是一样的,那么在n天内,如何安排自己的接活才能保证赚钱最多。


问题简化后就是贪心的活动安排问题, 传送门:http://blog.csdn.net/a9529lty/article/details/4042019


然后证明(想半天,没有想出来)








问题2. 假如这个时候,每个活的钱数是不同的,可以获得最大的钱数是多少?


(我给的答案是枚举任务,然后做dp)


写代码....








[cpp] view plaincopyprint?
#define MAX_TAST 100  
struct Task{  
    int s, e;  
    int val;  
};  
  
bool TaskInRange(const Task &t, int s, int e){  
    return t.s >= s && t.e <= e;  
}  
  
int dp[MAX_TAST][MAX_TAST];  
int nTask;  
Task aTask[MAX_TAST];  
int GetMaxValue(int s, int e){  
  
    if(dp[s][e] != -1){  
        return dp[s][e];  
    }  
    if( s == e){  
        return dp[s][e] = 0;  
    }  
    int maxvalue = 0;  
    for(int i = 0; i < nTask; i++){  
        if(TaskInRange(aTask[i], s, e))  
        {  
            int value = GetMaxValue(s, aTask[i].s) +   
                        GetMaxValue(aTask[i].e, e) +  
                        aTask[i].val;  
            if(value > maxvalue){  
                maxvalue = value;  
            }  
        }  
    }  
    return dp[s][e] = maxvalue;  
}  
#define MAX_TAST 100
struct Task{
int s, e;
int val;
};


bool TaskInRange(const Task &t, int s, int e){
return t.s >= s && t.e <= e;
}


int dp[MAX_TAST][MAX_TAST];
int nTask;
Task aTask[MAX_TAST];
int GetMaxValue(int s, int e){


if(dp[s][e] != -1){
return dp[s][e];
}
if( s == e){
return dp[s][e] = 0;
}
int maxvalue = 0;
for(int i = 0; i < nTask; i++){
if(TaskInRange(aTask[i], s, e))
{
int value = GetMaxValue(s, aTask[i].s) + 
       GetMaxValue(aTask[i].e, e) +
aTask[i].val;
if(value > maxvalue){
maxvalue = value;
}
}
}
return dp[s][e] = maxvalue;
}


然后她问我如何优化,我说可以先把任务排序,然后搜索到合适的任务岂止点,将枚举从O(n)降低到O(logn).








二面:


二面先聊自我介绍,简要介绍之前做的项目


问题1. 写代码:判断一个数字序列是BST后序遍历的结果,下面是我现场写的代码,没有测试过








[cpp] view plaincopyprint?
bool IsPostOrderOfBST(int array[], int low, int high)  
{  
    if(low >= high){  
        return true;  
    }  
    int split = -1, i;  
  
    for( i = low; i < high; i++){  
        if(split != -1 && array[i] < array[high]){  
            return false;  
        }  
        if(split == -1 && array[i] > array[high]){  
            split = i;  
        }  
    }  
    if(split == -1){  
        return IsPostOrderOfBST(array, low, high-1);  
    }  
    return IsPostOrderOfBST(array, low, split-1) && IsPostOrderOfBST(array, split, high-1);  
}  
bool IsPostOrderOfBST(int array[], int low, int high)
{
if(low >= high){
return true;
}
int split = -1, i;


for( i = low; i < high; i++){
if(split != -1 && array[i] < array[high]){
return false;
}
if(split == -1 && array[i] > array[high]){
split = i;
}
}
if(split == -1){
return IsPostOrderOfBST(array, low, high-1);
}
return IsPostOrderOfBST(array, low, split-1) && IsPostOrderOfBST(array, split, high-1);
}




问题2. 写一个单件模式,然后顺便被我引导到扯扯 线程安全 异常安全等话题,我不断完善最初代码使得满足线程安全和异常安全。


下面的代码大概是最初版本: 








[cpp] view plaincopyprint?
#include <stdio.h>  
  
  
class Singleton{  
  
  
private:  
  
    Singleton(){}  
    Singleton(const Singleton &);  
    Singleton& operator=(const Singleton&);  
  
public:  
  
    static Singleton *Instantialize();  
    static Singleton *pInstance;  
};  
  
Singleton* Singleton::pInstance = 0;  
Singleton* Singleton::Instantialize(){  
  
    if(pInstance == NULL){  
        pInstance = new Singleton();  
    }  
    return pInstance;  
}  
#include <stdio.h>




class Singleton{




private:


Singleton(){}
Singleton(const Singleton &);
Singleton& operator=(const Singleton&);


public:


static Singleton *Instantialize();
static Singleton *pInstance;
};


Singleton* Singleton::pInstance = 0;
Singleton* Singleton::Instantialize(){


if(pInstance == NULL){
pInstance = new Singleton();
}
return pInstance;
}












然后大概扩展到如下形式:








[cpp] view plaincopyprint?
class Lock{  
private:         
    CRITICAL_SECTION &m_cs;  
public:  
    Lock(CRITICAL_SECTION cs):m_cs(cs)  
    {  
        m_cs.lock();  
    }  
    ~Lock()  
    {  
        m_cs.unlock();  
    }  
};  
  
class Singleton{  
private:  
    Singleton();  
    Singleton(const Singleton );  
    Singleton operator = (const Singleton &);  
  
public:  
    static Singleton *Instantialize();  
    static Singleton *pInstance;  
    static CRITICAL_SECTION cs;  
};  
Singleton* Singleton::pInstance = 0;  
Singleton* Singleton::Instantialize()  
{       if(pInstance == NULL){//double check  
    Lock lock(cs);//用lock实现线程安全,用资源管理类,实现异常安全  
    if(pInstance == NULL)  
    {  
        pInstance = new Singleton();  
    }}  
    return pInstance;  
}  
class Lock{
private:       
CRITICAL_SECTION &m_cs;
public:
Lock(CRITICAL_SECTION cs):m_cs(cs)
{
m_cs.lock();
}
~Lock()
{
m_cs.unlock();
}
};


class Singleton{
private:
Singleton();
Singleton(const Singleton );
Singleton operator = (const Singleton &);


public:
static Singleton *Instantialize();
static Singleton *pInstance;
static CRITICAL_SECTION cs;
};
Singleton* Singleton::pInstance = 0;
Singleton* Singleton::Instantialize()
{       if(pInstance == NULL){//double check
Lock lock(cs);//用lock实现线程安全,用资源管理类,实现异常安全
if(pInstance == NULL)
{
pInstance = new Singleton();
}}
return pInstance;
}












问题3 对C++ virtual的理解 . 我从实现角度给他说了  虚函数和虚继承


问题4 如果有一个websever,例如12306,用户量特别大,网站面临效能问题,如何解决。


          我先胡扯了线程池,然后又扯到多个机器搞这个问题等等




最后问一下我对什么感兴趣,他给我介绍了有道云笔记。








总结: 


和很多人分享了一些面试题目,感觉我面试的题目难度是比较水的,感觉其他同学面的都很难。有道说十一以后还会安排三面,是技术总监面试,估计也是终面了吧~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值