展讯/北京移动--笔试题
展讯笔试题目:
1.给出字符串pszBuff, 将其全部转化为大写,a转化为A
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *convert(const char* dest)
{
int ilen=0;
char *tmp=(char *)dest;
char *str;
//strcpy(str,dest);
while(*dest++) ilen++;
str = (char *)malloc(ilen);
while(*tmp)
{
if ( (*tmp>'a') && (*tmp<'z')) {
*str = *tmp + 'A' - 'a' ;
}else{
*str = *tmp;
}
str++;
tmp++;
}
*str='\0';
return str-ilen;
}
int main(int argc, char* argv[])
{
const char pszBuff[] = "AbCd";
char *cc;
cc = convert(pszBuff);
printf("%s",cc);
getchar();
return 0;
}
2. 给出输出结果,假设是CPU32位
int main(int argc, char* argv[])
{
char *str="1234567890";
long *pLong= (long *)str;
char *pChar = str;
pLong++;
pChar++;
printf("%d %d %s\n",sizeof(long),sizeof(pLong),pLong);
printf("%d %d %s\n",sizeof(char),sizeof(pChar),pChar);
printf("%d",sizeof(int));
getchar();
return 0;
}
答案: 4 4 567890
1 4 234567890
4
想把 0x12345678 从一台 x86 机器发送到另外一台 x86 机器
1. x86 机器是小端的,所以 0x12345678 在内存中的布局为 78 56 34 12;
2. 网络字节序是大端的,所以 0x12345678 在网络中的传输顺序为 12 34 56 78;可以这样理解,传输的顺序是从内存低地址到内存高地址依次传输,在传输之前先将小端的 78 56 34 12 转换为大端的 12 34 56 78,然后再按照内存低地址到内存高地址的顺序依次传输。
3. 在接收方,依次接收到的是 12 34 56 78,但是它本身是小端的,所以需要先将 78 存储在内存低地址,然后依次存储 56 34 12。
Part1 通信
GSM/GPRS/WCDMA区别
GSM的上下行频率
Part2 c语言
c语言中volatile的用处
链表与数组的区别
写出strcpy的c实现代码
求两个字符串的最大公共字符子串
Part3 智力题
一根非均匀绳子可以烧1小时,怎么用它定出15分钟?
两头点燃+中间点燃。一段烧光了,马上到另一段中间点燃。直到最后烧光。
你让工人为你工作7天,给工人的回报是一根金条。
金条平分成相连的7段,你必须在每天结束时给他们一段金条,
如果只许你两次把金条弄断,你如何给你的工人付费?
分成1,2,4三段。每天给一段,有时候要求找零。
Part4 英语
翻译:一段跟移动基站有关的英文技术文章
北京移动:
1,网络192.168.18.0采用255.255.255.240子网掩码划分子网时,那些是有效的主机地址? 192.168.18.33/.112/.119/.126/.175/.208(选择题)
字串3
2,GSM900和DCS1800的上下行频率分别是? 字串1
3,智能网的网络元素组成?
字串4
4,ping指令运行在OSI的哪层? 字串1
5,请写出英文全称:IMSI,HLR,VLR,MSC,TUP,SCCP
字串5
6,基站控制器BSC和基站BTS间的传输方式有哪些? 字串2
1. GSM全名为:Global System for Mobile Communications,中文为全球移动通讯系统,中国移动、中国联通各拥有一个GSM网,为世界最大的移动通信网络。GSM系统包括 GSM 900:900MHz、GSM1800:1800MHz 及 GSM-1900:1900MHz等几个频段
GPRS的英文全称为General Packet Radio Service,中文含义为通用分组无线服务,是通信公司的服务,可以利用他上网或一些数据的传输等等。
WCDMA 是一种由3GPP具体制定的,基于GSM MAP核心网,UTRAN(UMTS陆地无线接入网)为无线接口的第三代移动通信系统.
2.gsm900和dcs1900的上下行频率及射频带宽等
http://www.rfhy.com/gb2312/UploadFile/200562794926966.doc
什么是双工间隔?GSM系统、DCS1800的双工间隔是多少?
双工间隔指上下行频率之间的间隔,GSM为45MHz,DCS1800为95MHz。
900MHz
基本工作频带: 上行:890~915MHz
下行:935~960MHz
扩展工作频带: 上行:880~890MHz
下行:925~935MHz
dB、dBm、dBc、dBi的区别:
dB是个比值,不是单位;dBm是功率的单位;dBc常用互调方面,不常用;dBi是增益单位。
通信的时候在逻辑上需要两条链路:一条是出去的,一条是进来的(上行和下行);
上行是指信号从移动台(一般指手机)到基站(2G叫BTS,3G叫NODEB)到BSC
下行是指信号从BSC到基站(2G叫BTS,3G叫NODEB)到移动台(一般指手机)
这两条链路必须要分开,否则通信无法正常进行,由此产生双工模式。双工模式有2种:时分双工(TDD)和频分双工(FDD)
在TDD中,上下行链路靠时隙来区分,频率是一样的, 比如TD-SCDMA
在FDD中,上下行链路靠不同的频率来区分,同时收发, 比如WCDMA(FDD)
为了有效地区分开上下行频率,上行频率与下行频率必须有一定的间隔(保护带)
一般下行频率高于上行频率。
在GSM系统中,上行(接收)的频率为:880-915MHZ;下行(发射)频率为:925-960MHZ;
在我国GSM900的使用频率是:905-915MHZ(上行),950-960MHZ(下行)
移动的:下行(前向)950MHz-954MHz, 上行(反向)905MHz-909MHz共4M带宽,20个频道;
联通CDMA:下行 954MHz~960MHz 上行909MHz~915MHz共6M带宽,29个频道.
频率间隔是200KHZ;
双工间隔是45MHZ
上行:(890~915)MHz,移动台发。
下行:(935~960)MHz,移动台收。
频带宽度:25 MHz。
上,下行频率间隔:45 MHz。
载频间隔:200KHz
频点:25 MHz/200K Hz=125,共124个频点。
通信方式:全双工
DCS1800,上行:1710-1785MHz,下行:1805-1880MHz.
3. volatile关键字有什么用?
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码:
1. int i1; int geti1() {return i1;}
2. volatile int i2; int geti2() {return i2;}
3. int i3;synchronized int geti3() {return i3;}
geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。
而geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说,一个变量经 volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。
既然volatile关键字已经实现了线程间数据同步,又要synchronized干什么呢?呵呵,它们之间有两点不同。首先, synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事实。但是,synchronized也同步内存:事实上,synchronized在“主”内存区域同步整个线程的内存。因此,执行geti3()方法做了如下几步:
1. 线程请求获得监视this对象的对象锁(假设未被锁,否则线程等待直到锁释放)
2. 线程内存的数据被消除,从“主”内存区域中读入(Java虚拟机能优化此步。。。[后面的不知道怎么表达,汗])
3. 代码块被执行
4. 对于变量的任何改变现在可以安全地写到“主”内存区域中(不过geti3()方法不会改变变量值)
5. 线程释放监视this对象的对象锁
因此volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。
- 链表和数组的区别
链表的特性是在中间任意位置添加删除元素的都非常的快,不需要移动其它的元素。
链表顾名思义,要把各个元素链接起来才算撒。
通常链表每一个元素都要保存一个指向下一个元素的指针(单链表)。
双链表的化每个元素即要保存到下一个元素的指针,还要保存一个上一个元素的指针。
循环链表则把最后一个元素中保存下一个元素指针指向第一个元素。
数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,这个编号叫做下标,我们可以通过下标来区别这些元素。数组元素的个数有时也称之为数组的长度
5. 写出strcpy的c实现代码
不使用库函数实现strcpy。这是一个很简单的题目,但它却可以考察如下的几点:
(1)编程风格;
(2)出错处理;
(3)算法复杂度分析(用于提高性能)。
这是摘自林锐的《高质量C++/C编程指南》中的内容。
也有人总结成了下面的几点,说的也很有道理:
(1)注意编程风格。比如,使用dst、src这样增强可读性的名字。
(2)使用断言来检验输入参数的有效性。
(3)使用const来约束src,表明src对应的内容不能被修改。
(4)返回dst,以便实现链式表达式这样的机制。
char *strcpy(char *strDest, const char *strSrc);
{
//使用断言来检验输入参数的有效性。
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ )
NULL ;
return address ;
}
6。求两个字符串的最大公共字符子串,如"abccade","dgcadde"的最大子串为"cad"
int GetCommon(char *s1, char *s2, char **r1, char **r2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
int maxlen = 0;
for(int i = 0; i < len1; i++)
{
for(int j = 0; j < len2; j++)
{
if(s1 == s2[j])
{
int as = i, bs = j, count = 1;
while((as + 1 < len1 )&& (bs + 1 < len2) && (s1[++as] ==s2[++bs]))
count++;
if(count > maxlen)
{
maxlen = count;
*r1 = s1 + i;
*r2 = s2 + j;
}
}
}
}
关于内存的4个经典题目GetMomery
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
请问运行Test函数会有什么样的结果?
答:程序崩溃。
因为GetMemory并不能传递动态内存,
Test函数中的 str一直都是 NULL。
strcpy(str, "hello world");将使程序崩溃。
说的简单一些,就是传入的就是一个空指针,p确实分配空间了,
但是生成的空间首地址没有返回给str
2:
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
请问运行Test函数会有什么样的结果?
答:可能是乱码。
因为GetMemory返回的是指向"栈内存"的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。
说的简单一些,就是函数的局部变量释放了。
3:
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行Test函数会有什么样的结果?
答:
(1)能够输出hello
(2)内存泄漏
说的简单一些,就是没有释放malloc的空间
4:
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
请问运行Test函数会有什么样的结果?
答:篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str);之后,str成为野指针,
if(str != NULL)语句不起作用。
说的简单一些,就是只收回内存,没有用str=NULL收回指针