技术面经验
自我介绍,项目介绍,
(1)喜欢加班的,吃苦耐劳不计较报酬
(2)中庸,不要表现自己的特性,有自己性格一定会被刷掉
(3)稳定的,稳定超过一切包括技术、包括是否能做事
(4)不能过激,比如那种会跳楼第一时间会被刷掉
(5)团队合作很重要,不要自己来往
嵌入式问题:
C语言问题
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
extern int a; 仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
const 意味着“只读”
1、const int a;
2、int const a;
3、const int *a;
4、int * const a;
5、int const * a const;
1、前两个的作用是一样,a是一个常整型数;
2、第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以);
3、第四个意思a是一个指向整型 数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的);
4、最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数 是不可修改的,同时指针也是不可修改的)。
1) 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
2) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
3) 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。
strcat使用过程中会出现什么问题
sizeof是运算符,在编译时即计算好了; 而strlen是函数,要在运行时才能计算。
栈:(队列优先,先进先出)操作系统自动分配释放,存放函数的参数值,局部变量的值等。操作方式类似于数据结构中的栈。
堆:(先进后出)一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
malloc函数 分配内存空间在堆上。
free函数 释放内存;
int a = 0; //全局初始化区
char *p1;//全局未初始化区
void main(void)
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上
static int c =0; //全局(静态)初始化区
p1 = (char *)malloc(10); //堆
p2 = (char *)malloc(20); //堆
}
什么数据放入堆?什么数据放入栈?
1、内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
2、内存溢出 out of memory :指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用,此时就会报错OOM,即所谓的内存溢出。
内存泄漏的原因:
1、内存分配未成功,却使用了它。
在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
2、内存分配虽然成功,但是尚未初始化就引用它。
赋初值,可以初值为零;
char *p = malloc (10);
memset(p,'\0',10);//初始化
3、内存分配成功并且已经初始化,但操作越过了内存的边界
尤其是for循环多1。
下面程序p仅被分配了10个字节,但是memcpy操作将11个字节写入p。
char *name = (char *) malloc(11);
memcpy (p,name,11);
4、忘记了释放内存,造成内存泄露
#include
using namespace std;
int main()
{
int a=11;
int c=22;
int *q, *r;
q=&a;
r=&c;
cout<<*q<<' '<
运行结果如下:
链表的节点结构:
struct LINK_NODE
{
int data;
Node *next;
};
typedef struct LINK_NODE LINK_NODE;
已知链表地头节点head,链表逆序(intel)
Node *ReverseLink(LINK_NODE *head) //链表逆序
{
LINK_NODE *next;
LINK_NODE *prev=NULL;
while(head!=NULL)
{
next=head->next;
head->next=prev;
prev=head;
head=next;
}
return prev;
}
LINK_NODE *ReverseLink2(LINK *head)
{
LINK_NODE *newHead;
if((head==NULL)||(head->next==NULL))
return head;
newHead=ReverseLink2(head->next)
head->next->next = head;
head->next = NULL;
return newHead;
}