c和c++精炼总结(重点是几个重要的关键字的用法)

1、cin输入多个数据用空格或者回车来区分,不可以用“,”来区分。

2、多个判断语句下,if...if...else;这样写程序会导致最后两个形成独立判断,也就是说,如果第一个if成立,那么除了执行第一个if下的内容,还会执行else下的内容;为了避免这样的问题,就需要用if...else if...else这样的嵌套

3、随机数函数的应用

(1)srand(time(0))和rand();前者是为产生随机数提供种子函数,后者就是随机值产生的函数;而套用的time(0),目的是为了    产生随着时间改变的随机数。

(2)这两个函数分别属于两个头文件 #include <stdlib.h>、#include<time.h>

4、在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”):

(1) 一个对象作为函数参数,以值传递的方式传入函数体;
(2)一个对象作为函数返回值,以值传递的方式从函数返回;
(3)一个对象用于给另外一个对象进行初始化(常称为赋值初始化);

5、关于extern、static、const和virtual的用法总结:

extern:

(1) extern修饰变量的声明。

如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v。

这里需要注意的是,被引用的变量v的链接属性必须是外链接(external)的,也就是说a.c要引用到v,不只是取决于在a.c中声明extern int v,还取决于变量v本身是能够被引用到的。

这涉及到c语言的另外一个话题--变量的作用域。能够被其他模块以extern修饰符引用到的变量通常是全局变量

还有很重要的一点是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函数fun定义的开头处声明extern int v,然后就可以引用到变量v了,只不过这样只能在函数fun作用域中引用v罢了,这还是变量作用域的问题。对于这一点来说,很多人使用的时候都心存顾虑。好像extern声明只能用于文件作用域似的。

(2) extern修饰函数声明。

从本质上来讲,变量和函数没有区别。函数名是指向函数二进制块开头处的指针。

如果文件a.c需要引用b.c中的函数,比如在b.c中原型是int fun(int mu),那么就可以在a.c中声明extern int fun(int mu),然后就能使用fun来做任何事情。

就像变量的声明一样,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的范围中。

对其他模块中函数的引用,最常用的方法是包含这些函数声明的头文件。使用extern和包含头文件来引用函数有什么区别呢?extern的引用方式比包含头文件要简洁得多!extern的使用方法是直接了当的,想引用哪个函数就用extern声明哪个函数。

这样做的一个明显的好处是,会加速程序的编译(确切的说是预处理)的过程,节省时间。在大型C程序编译过程中,这种差异是非常明显的。

(3)此外,extern修饰符可用于指示C或者C++函数的调用规范。

比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。

这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。

static:

(1)、 局部静态变量

局部变量按照存储形式可以分为三种,分别是auto、static、register。

与auto类型(普通)局部变量相比,static有三点不同:

1. 存储空间分配不同

auto类型分配在栈上,属于动态存储类别,占动态存储空间,函数调用结束后自动释放;static类型分配在静态存储区,在程序整个运行期间都不释放;

两者作用域相同,但是生存期不同。

2. static局部变量在初次运行时进行初始化工作,且只初始化一次。

3. 对于局部静态变量,如果不赋初值,编译期会自动赋初值0或者空;

auto类型的初值是不确定的。

对于C++的类对象例外,class的对象实例如果不初始化,则会自动调用默认构造函数,不管是不是static类型。

特点:static局部变量的“记忆性”与生存期的“全局性”

所谓“记忆性”是指在两次函数调用时,在第二次调用进入时,能保持第一次调用退出时的值。

#include <iostream>
using namespace std;

void staticLocalVar()
{
	static int a = 0;
	cout<<"a="<<++a<<endl;
}

int main()
{
	staticLocalVar();	// a=1
	staticLocalVar();	// a=2
	system("pause");
	return 0;
}

  利用生存期的”全局性“改善return a pointer / reference to a local object的问题,local object的问题在于退出函数时,生存期就结束,局部变量就会被销毁;利用static就可以延长局部变量的生存期。

// IP address to string format
// Used in Ethernet Frame and IP Header analysis
const char * IpToStr(UINT32 IpAddr)
{
	static char strBuff[16]; // static局部变量, 用于返回地址有效
	const unsigned char *pChIP = (const unsigned char *)&IpAddr;
	sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);
	return strBuff;
}

  注意事项:

1. “记忆性”是程序运行很重要的一点就是可重复性,而static变量的“记忆性”破坏了可重复性,造成不同时刻同一函数的运行结果不同。

2. “生存期”全局性和唯一性。 普通的局部变量在栈上分配空间,因此每次调用函数时,分配的空间都可能不一样,而static具有全局唯一性的特点,每次调用时都指向同一块内存,这就造成一个很重要的问题---不可重入性!!!

在多线程或者递归程序中要特别注意。

(2) 外部静态变量/函数

在C中static的第二种含义:用来表示不能被其它文件访问的全局变量和函数。

此处static的含义是指对函数的作用域仅仅局限于本文件(所以又称为内部函数)。

注意:对于外部(全局)变量,不论是否有static限制,它的存储区域都是在静态存储区,生存期都是全局的,此时的static只是起作用域限制作用,限制作用域在本文件内部。

使用内部函数的好处是:不同的人编写不同的函数时,不用担心函数同名问题。

 //file1.cpp
static int varA;
int varB;
extern void funA()
{
} 

static void funB()
{
} 

//file2.cpp
extern int varB; // 使用file1.cpp中定义的全局变量
extern int varA; // 错误! varA是static类型, 无法在其他文件中使用
extern void funA(); // 使用file1.cpp中定义的函数
extern void funB(); // 错误! 无法使用file1.cpp文件中static函数

  (3)静态数据成员/成员函数(C++特有)

C++重用了这个关键字,它表示属于一个类而不是属于此类的任何特定的对象的变量和函数。

静态类成员包括静态数据成员和静态函数成员。

1. 静态数据成员

类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时静态数据成员还具有以下特点。

1) 静态数据成员的定义

静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。其定义方式与全局变量相同。举例如下:

 xxx.h文件
 class base
{
private:
	static const int _i;	//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。
};   

xxx.cpp文件
const int base::_i = 10;	//定义(初始化)时不受private和protected访问限制.

  注:不要试图在头文件中定义(初始化)静态数据成员。在大多数情况下,这会引起重复定义。即使加上#ifndef  #define  #endif或者#pragma once也不行。

2) 静态数据成员被类的所有对象所共享,包括该类的派生类的对象。

#include <iostream>
using namespace std;

class base
{
public:
	static int _num;	//声明
};  

int base::_num = 0;	//静态数据成员的真正定义     

class derived : public base
{
};    

int main()
{
	base a;
	derived b;
	a._num++;
	cout<<"base class static data number _num is "<<a._num<<endl;	// 1
	b._num++;
	cout<<"derived class static data number _num is "<<b._num<<endl;// 2
	system("pause");
	return 0;
}

  3) 静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。

class base
{
public:
	static int _staticVar;
	int _var;
	void foo1(int i = _staticVar);//正确,_staticVar为静态数据成员
	void foo2(int i = _var);//错误,_var为普通数据成员
};

4 )  ★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的指针或引用。举例如下:

class base
{
public:
	static base _object1;//正确,静态数据成员
	base  object2;//错误
	base *pObject;//正确,指针
	base &mObject;//正确,引用
};

   5 ).★这个特性,我不知道是属于标准c++中的特性,还是vc6自己的特性。

静态数据成员的值在const成员函数中可以被合法的改变。举例如下:

class base
{
public:
	base()
	{
		_i = 0;
		_val = 0;
	}
	mutable int _i;
	static int _staticVal;
	int _val;
	void test() const
	{
		_i++;//正确,mutable数据成员
		_staticVal++;//正确,static数据成员
		_val++;//错误
	}
};
int   base::_staticVal = 0;

   2 静态成员函数

1).静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用类成员函数指针来储存。举例如下:

class base
{
	static int func1();
	int func2();
};  

int (*pf1)() = &base::func1;		//普通的函数指针
int (base::*pf2)() = &base::func2;	//成员函数指针

  2).静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。  
       3).静态成员函数不可以同时声明为   virtual、const、volatile函数。举例如下:

class base
{
	virtual static void func1();//错误
	static void func2() const;//错误
	static void func3() volatile;//错误
};

  最后要说的一点是,静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。

const

(1) const的基本功能与用法

1).将限定符声明为只读

使用方法如下,在类型前/后加上关键字const,该变量必须被初始化,否则编译错误;该变量不能被重新赋值,否则也编译错误。

const int i = 50;   // 编译正确
const int j;        // 编译错误
int k = 0;
i = k;              // 编译错误
k = i;              // 编译正确

2).用于修饰函数形参,保护参数使其不被修改

用法1:若形参为const A* a,则不能改变函数所传递的指针内容,这样对指针所指向的内容起到保护作用,这里需要注意的是,该修饰不能改变指针所指向地址所存储的内容,但是指针a所指向的地址可以被改变,具体例子如下:

void Test(const int *a)
{
    *a = 1;          //错误,*a不能被赋值
    a = new int(10086);  //正确,为指针a开辟新的空间,并令*a=10086
}

int main()
{
    int *a = new int(10000);
    Test(a);
    return 0;
}

用法2:若形参为const A& a,则不能改变函数传递进来的引用对象,从而保护了原对象的属性。

对于自定义的数据类型,用引用传递速度较快,如果不想改变原值,就可以用const来保护参数,如以下例子:

void Test(const int &a) //保护L7中的a不会被改变
{
    a = 2;//错误,a不能给常量赋值
}

int main()
{
    int a = 3;
    Test(a);
    return 0;
}

  

事实上对于内置型数据类型(如以上例子中的int类型),用引用传递不会使速度更快。如果是用引用传参,一般是为了改变参数值;如果不想改变参数的值,直接值传递即可,不必使用const修饰。而对于自定义数据类型的输入参数,为了提高速度和效率,应使用“const + 引用传递”代替值传递。例如:

将函数 void Test(A a) 改为-> void Test(const A &a)

3).用于修饰函数返回值

用法1:用const修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数并产生新对象的时候 。
举例:

const Rational operator*(const Rational& lhs, const Rational& rhs)
{
    return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
Rational a,b;
Radional c;
(a*b) = c;//错误

用法2:不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(const A test = A 实例)或某个对象的引用为const(const A& test = A实例) ,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到,具体例子如下:

class A
{
public:
    int y;
    A(int y):x(x),y(y){};
    void Sety(int y){this->y = y;}
};

const A Test1(A a)
{
    return a;
}

const A& Test2(A &a)
{
    return a;
}

int main()
{
    A a(2);
    Test1(a).Sety(3);//错误,因为Test1(a)的返回值是个const,不能被Sety(3)修改
    Test2(a).Sety(3);//错误,因为Test1(a)的返回值是个const,不能被Sety(3)修改
    return 0;
}

用法3:如果给采用“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。例子如下:

const char * GetString(void){}
int main()
{
    char *str1=GetString();//错误
    const char *str2=GetString();//正确
    return 0;
}

  用法4:函数返回值采用“引用传递”的场合不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。例子如下:

class A
{
    // 以下赋值函数的返回值加const修饰,该返回值的内容不允许修改
    A &operate = (const A &other);
}
A a, b, c;  // a,b,c为A的对象
a = b = c;      // 正确
(a = b) = c;    // 错误,a = b的返回值不允许被再赋值

4).在类成员函数的函数体后加关键字const

在类成员函数的函数体后加关键字const,形如:void fun() const; 在函数过程中不会修改数据成员。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其他非const成员函数,编译器将报错,这大大提高了程序的健壮性。

如果不是在类的成员函数,没有任何效果,void fun() const;和void func();是一样的。

5). 在另一连接文件文件中引用常量

方法:在类型前添加关键字extern const,表示引用的是常量,因此该常量不允许被再次赋值,举例如下:

extern const int i;       // 正确
extern const int j = 10;  // 错误,常量不可以被再次赋值

(2).const常量与#define的区别

1).const常量有数据类型,而宏常量没有数据类型

宏常量只进行简单的字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误,如:

#define I = 10
const long &i = 10;
// 由于编译器的优化,使得在const long i=10时i不被分配内存
// 而是已10直接代入以后的引用中,以致在以后的代码中没有错误
//一旦你关闭所有优化措施,即使const long i = 10也会引起后面的编译错误。
char h = I; // 正确
char h = i; // 编译警告,可能由于数的截短带来错误赋值

2).使用const可以避免不必要的内存分配

从汇编的角度来看,const定义常量只是给出了对应的内存地址, 而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。例子如下:

#define k "Hello world!"
const char pk[]="Hello world!";
printf(k);      // 为k分配了第一次内存
printf(pk);     // 为pk一次分配了内存,以后不再分配
printf(k);      // 为k分配了第二次内存
printf(pk);

(3). 使用const的一些注意事项

1).修改const 所修饰的常量值

以下例子中,iconst修饰的变量,可以通过对i进行类型强制转换,将地址赋给一个新的变量,对该新的变量再作修改即可以改变原来const 修饰的常值。

const int i = 0;
int *p=(int*)&i;
*p = 100;

2).构造函数不能被声明为const

3).const数据成员的初始化只能在类的构造函数的初始化表中进行

class A
{
public:
    const int a;
    A(int x):a(x)//正确
    {
        a = x;//错误
    }
};

4).在参数中使用const应该使用引用或指针,而不是一般的对象实例

合理利用const在成员函数中的三种用法(参数、返回值、函数),一般来说,不要轻易的将函数的返回值类型定为const;另外,除了重载操作符外一般不要将返回值类型定为对某个对象的const引用。

5).对于使用const修饰来指针的情况

对于以下情况,const放在变量声明符的前后位置效果是一样的,这种情况下不允许对指针a 的内容进行更改操作:

int i;
const int *a = &i;
int const*a = &i;

  但是,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即该指针指向一个地址,该地址的内容不可变;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量:

int i;
// 以下一行表示a是一个指针,可以任意指向int常量或者int变量
// 它总是把它所指向的目标当作一个int常量
// 也可以写成int const* a
const int *a = &i;
// 以下一行表示a是一个指针常量,
// 初始化的时候必须固定指向一个int变量
// 之后就不能再指向别的地方了
// 但是指针指向的内容可以改变
int *const a = &i;

6).指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如以下例子中a++是错误的: 

int *const a = &i;
a++;  // 错误,a指针本身是常量,不能再指向别的地方

7).当指针本身和指针所指向的内容均为常量时

这种情况下可写为:

const int * const a = &i;

  8).const成员函数返回的引用,也是const

#include<iostream>
using namespace std;
class A
{
public:
    int x;
    void set(int x){this->x = x;}
    // const成员函数返回的引用也是const,a
    // 如果把A&前面的const去掉会出错
    // 因为返回的是一个const的对象,返回类型却不是const
    // 返回的内容和返回的类型不符
    const A& Test1()const
    {
    // 错误。这是const成员函数的特点
    x = 2;
    // 不限于*this。不管返回的是什么,哪怕是一个定义为非const的对象,结果也是一样的
    return *this;
    }
};

int main()
{
    A a, b;
    // 正确,虽然返回的是一个const,却用另一个非const来接收
    b = a.Test1();
    // 错误,既然是别名,那么别名的类型要与原来的类型相同
    A &c = a.Test1();
    // 正确虽然在a.Test1()中a不能改变,但是这里已经出了这个成员函数的作用域
    a.set(2);
    // 正确,b接收了a.Test1()返回的数据的内容,但是它不是const
    b.set(2);
    // 错误。a.Test1()是一个对象,这个对象是它的返回值
    // 虽然没有名字,但是它就是a.Test1()的返回值
    // 值是a.Test1()返回的值,类型是a.Test1()返回的类型
    a.Test1().set(2);
    return 0;
}

9).mutable将数据声明为可变数据成员

在C++语言中,mutable是使用较少的关键字,它的作用是:如果一个函数被const 修饰,那么它将无法修改其成员变量的,但是如果一个成员变量是被mutable修饰的话,则可以修改。

mutable 可以用来指出,即使成员函数或者类变量为const,其某个成员也可以被修改。反过来说,可变数据成员永远不能成为const,即使它是const对象的成员。

class A
{
public:
    int x;
    mutable int y;
    A(int a, int b):x(a),y(b){}
};

int main()
{
    const A a(0, 0); // const对象必须初始化
    a.x = 1;         // 错误
    a.y = 2;         // 正确,mutable修饰使得成员可被修改,即使对象a为const
    return 0;
}

virtual 

先来一段代码:

#include "stdio.h"
#include "conio.h"

class Parent

{

public:

	char data[20];
	void Function1();
	virtual void Function2();   // 这里声明Function2是虚函数

}parent;

void Parent::Function1()
{
	printf("This is parent,function1\n");
}

void Parent::Function2()

{
	printf("This is parent,function2\n");
}

class Child:public Parent

{
	void Function1();
	void Function2();

} child;

void Child::Function1()

{
	printf("This is child,function1\n");
}

void Child::Function2()

{
	printf("This is child,function2\n");
}

int main(int argc, char* argv[])

{
	Parent *p;  // 定义一个基类指针
	if(_getch()==‘c‘)     // 如果输入一个小写字母c
		p=&child;         // 指向继承类对象
	else
		p=&parent;       // 否则指向基类对象
	p->Function1();   // 这里在编译时会直接给出Parent::Function1()的入口地址。
	p->Function2();    // 注意这里,执行的是哪一个Function2?
	return 0;

}

用任意版本的Visual C++或Borland C++编译并运行,输入一个小写字母c,得到下面的结果:

This is parent,function1

This is child,function2

为什么会有第一行的结果呢?因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。 那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就是说,它是一个虚函数。虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。
如果我们在运行上面的程序时任意输入一个非c的字符,结果如下:

This is parent,function1

This is parent,function2

请注意看第二行,它的结果出现了变化。程序中仅仅调用了一个Function2()函数,却可以根据用户的输入自动决定到底调用基类中的Function2还是继承类中的Function2,这就是虚函数的作用。我们知道,在MFC中,很多类都是需要你继承的,它们的成员函数很多都要重载,比如编写MFC应用程序最常用的CView::OnDraw(CDC*)函数,就必须重载使用。把它定义为虚函数(实际上,在MFC中OnDraw不仅是虚函数,还是纯虚函数),可以保证时刻调用的是用户自己编写的OnDraw。虚函数的重要用途在这里可见一斑。

PS:一定要注意“静态联翩 ”和“ 动态联编 ”的区别,对于我来说,若没有在VC6.0中亲自去测试,凭自己的感觉,当在键盘中输入“c”时,我会觉得由于有:p=&child;这句代码,我认为结果会是:

This is child,function1
This is child,function2

  但是实际结果却是:

This is parent,function1
This is child,function2

因为虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实,它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。

第二行中调用了子类的function2,完全是因为virtual 的功能,virtual实现了动态联编,它可以在运行时判断指针指向的对象,并自动调用相应的函数。当然,如果执行的是:p=&parent; 这一句,该指针很明显的是指向父类,那么肯定调用的是父类的方法。

原文地址:https://www.cnblogs.com/lzy820260594/p/11315400.html

时间: 2024-10-05 01:38:36

c和c++精炼总结(重点是几个重要的关键字的用法)的相关文章

C C++ OC iOS面试重点问题(一)

C C++ OC iOS面试重点问题(一) 1.字符串常量需要加\0 2.逻辑运算 位操作(经典:实现两个数的交换) 3.关键字 4.引用和指针的区别和联系 5.如何引用一个已经定义过的全局变量?  答:可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错. 5.extern关键字的用法? 答:ext

网店转化率太低,你该怎么办?

转化率指在一个统计周期内,完成转化行为的次数占推广信息总点击次数的比率.转化率越高,说明店铺元素的吸引力越高. 一.转化率定义 转化率指在一个统计周期内,完成转化行为的次数占推广信息总点击次数的比率.转化率越高,说明店铺元素的吸引力越高.所以对于淘宝卖家,转化率是最核心的数据,提升转化率也是永恒的话题. 二.影响线上转化率的四大因素 1.产品 淘宝上产品千千万,为何有的产品卖的红红火火,有的却半路夭折?针对淘宝网这个平台,有关产品本身的几个可视化数据有:类目.品牌.产品信息.售价. 类目:类目不

技术宅学习Linux系统还是很有前途的

老实说,我之所以入了Linux的坑,纯粹只是为了追我现在的男朋友,也就是技术宅.如果不是为了追我男朋友的话,我估计我这辈子都不会去接触linux.好吧,今天写一写过往事情,也是为了怀念当初追男友的一些故事吧. 我大学专业是金融管理,现在的男友专业是计算机.男友是那种性格极其沉闷的人,也不愿意参与任何社交的活动.按理说,男友这样的性格,又和自己不是一个专业,我们应该难以认识的.但是有时候上天就会这么悄悄眷顾你的爱情.在一次大课的时候,我们专业和计算机专业安排一起上课.那天上课的时候,我刚好迟到,于

幸亏参加了51CTO的高项培训班

信息项目管理师属于高级,挺难的有两点,第一就是专业跨度比较大,涉及开发.网络.数据.法律.信息系统.数学等等很多学科,而且考得也很深入,第二科论文,一般来说很难把握论文能否达到合格线. 听说软考中的高级项目经理很难通过,网上传一次通过率不到10%.现实工作中,看到某银行科技部员工年年报考软考高项,到现在只有一人通过. 对于高级的考试,包括基础知识.案例分析,还有论文,这三个方面,大家要很努力的准备才有可能通过!我一个上学时学习的机械专业,与计算机和管理完全不搭边,半路赶鸭子上架做的项目经理,参加

北上广逃离指南

逃离北上广,在技术上其实十分简单.复杂的,是逃离时的姿势和态度. 就好像情侣吵架,谁先开口说分手,谁就占得了上风. 这是原则性问题,绝对不接受妥协. 很幸运.在这场旷日持久的争吵里头,北上广都不会开口说话.因此我们轻而易举地便抢到了主动权. 任何一名打算逃离北上广的都市中产阶级,都要谨记:姿势必须优雅,态度必须凛冽.否则,逃离北上广,便失去了意义. 逃离北上广的首要条件,是月薪必须达到一万. 月薪一万是逃离北上广的前提.月薪不到一万,没有资格说逃离.月薪不到一万,不是你逃离了北上广,是北上广抛弃

浅析Java中的final关键字

原文出处: 海子 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下面是本文的目录大纲: 一.final关键字的基本用法 二.深入理解final关键字 若有不正之处,请多多谅解并欢迎指正. 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量).下面就从这三个方面来了解一下final关键字

转载:浅析Java中的final关键字

文章转自:http://www.cnblogs.com/dolphin0520/p/3736238.html 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下面是本文的目录大纲: 一.final关键字的基本用法 二.深入理解final关键字 若有不正之处,请多多谅解并欢迎指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cn

想要新网站提高关键字的排名?这里有妙招

一个新建设的网站想要获得比较好的排名,站长在网站建设和优化的过程中肯定要花很多的时间和精力.而在这一个过程中我们要注意哪些问题呢?除了坚持,就是要学会分析关键字.优化网站内部结构.更新高质量的内容等等方面.今天我们就来说一下新网站究竟怎样可以提升关键字的排名,希望对各位站长有所帮助. 第一.一个新建设的网站在一开始的时候,是没有权重的.因此第一步要做的就是让搜索引擎知道并且认可我们的网站,然后再在网站上更新一些原创的内容,做好关键字的布局,在重点栏目中也要做好关键字的布局.在内容中最好是加入长尾

java 基础(二)

java 基础(二)java 基础(二) 2016-2-1 by Damon 61. 编写多线程程序有几种实现方式 Java 5以前实现多线程有两种实现方法:一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活. 补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的