精华内容
下载资源
问答
  • https://www.easyx.cn/downloads/ 注:使用easyx需要注意它兼容的编译器(下载的帮助文件会写),不同的easyx兼容的编译器不同,但总是visual C++6兼容(字符编码有关),本文visual C++6编译器为例书写代码。...

    0.引言

    \qquad 看了CSDN上很多关于C程序图形化界面的介绍,有的代码繁琐难解,不方便调试修改;有的不够详细。本文提供的代码简单、易于移植、容易理解,望急需使用C语言制作图形化界面的朋友采纳。
    \qquad 对easyx尚不熟悉的朋友不需要担心,我敢打包票它只需10分钟就可以上手,而它为你节省的时间可能是3个小时甚至更多。关于easyx的简单应用请参考一篇我以前写的关于C程序可视化的博文。
    →【C语言实现动画控制】←
    \qquad 本文的讲解是循序渐进的,读者应该重点关注每个步骤的理解,两步之间代码的变化,即可完全理解本文。

    1.素材准备

    1. easyx的下载链接如下:(本文使用的版本是2014冬至版)
      https://www.easyx.cn/downloads/
      注:使用easyx需要注意它兼容的编译器(下载的帮助文件会写),不同的easyx兼容的编译器不同,但总是和visual C++6兼容(和字符编码有关),本文以visual C++6编译器为例书写代码。
    2. easyx的最新英文帮助文档链接(下载2014冬至版会自带中文帮助文档):
      https://docs.easyx.cn/en-us/intro
    3. 如果你成功下载了easyx2014冬至版,那么解压后把头文件(easyx.h和graphic.h)和lib文件(amd64)分别放在VC文件夹默认的include文件夹和lib文件夹中。右键你的VC程序,选择打开文件所在位置,然后找到MFC文件夹,友情提供两个文件夹的位置截图。
      include
      lib
    4. 建议编译的C文件以cpp后缀保存。

    2.编程

    2.1.创建你的界面

    \qquad 创建一个480×360的窗口,我们需要使用initgraph()函数,闲言少叙,让我们直接看一段代码:

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	closegraph();//关闭绘图界面
    }
    
    

    \qquad 这段代码很容易理解,运行这段程序,就会出现逐渐明亮的屏幕。因为不断刷新背景色为 R G B ( i , i , i ) RGB(i,i,i) RGB(i,i,i)。C语言中的颜色使用十六进制表示的,RGB函数可以将0~255范围内的三个整数三原色转换成这个十六进制。
    \qquad cleardevice()函数用于清屏,是界面内所有元素都被清空,一般只会在初始化出现。
    \qquad Sleep()是毫秒级延迟,当然界面变亮时间不一定是准确的15ms×255/5=0.765s,因为其他语句还需要执行时间。
    \qquad closegraph():关闭绘图界面。注意,如果初始化了绘图界面但没有在主函数结束前关闭它,可能会引发一些莫名其妙的错误!所以这个函数一定要有!

    2.2.创建按钮

    \qquad 我们尝试在界面创建几个按钮,按钮需要的操作是绘制矩形和打印文字。虽然看着简单,但是里面还是有点学问,为了方便大家理解,还是先放上代码和注释。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r1[]={30,20,130,60};//输入按钮的矩形参数
    int r2[]={170,20,220,60};//运行按钮的矩形参数
    int r3[]={260,20,310,60};//退出按钮的矩形参数
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r1[0],r1[1],r1[2],r1[3]};//矩形指针R1
    	RECT R2={r2[0],r2[1],r2[2],r2[3]};//矩形指针R2
    	RECT R3={r3[0],r3[1],r3[2],r3[3]};//矩形指针R3
    	LOGFONT f;//字体样式指针
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r1[0],r1[1],r1[2],r1[3]);
    	rectangle(r2[0],r2[1],r2[2],r2[3]);
    	rectangle(r3[0],r3[1],r3[2],r3[3]);
    	system("pause");//暂停,为了显示
    	closegraph();
    	return 0;
    }
    

    在这里插入图片描述
    \qquad 这里需要特别介绍的是矩形指针 p R e c t pRect pRect,它使用句柄RECT定义,并且不可以中途再次赋值。之所以要设置矩形指针了为了打印字体的时候以矩形为边界自动填充。它的格式是RECT r={X1,Y1,X2,Y2},X1和X2是矩形的左边和右边的横坐标,Y1和Y2是矩形的上边和下边的纵坐标,这一点和rectangle()绘制空心矩形函数参数排列一致。后面的DT_CENTER | DT_VCENTER | DT_SINGLELINE就是描述填充格式的常量。使用drawtext书写文字不需要再计算文字的坐标和设置大小,会方便很多。
    \qquad LOGFONT是字体样式指针,通过gettextstyle()函数来获取当前的字体类型,再通过settextstyle()函数加以设置。这里只修改了字体的名称和显示质量,还可以修改斜体、下划线等属性,更详细的部分请参考帮助文档。

    2.3.鼠标操作

    2.3.1.单击特效

    \qquad 作为一个图形化界面的C程序,鼠标操作总不能少吧。在讲解程序前先别着急,简单为大家科普一下鼠标事件:
    \qquad 鼠标是输入设备,只要发生以下的事件,就会暂存在鼠标消息列表中,我们的操作系统就会依次响应列表中的鼠标消息事件,常用的鼠标事件如下:

    • WM_MOUSEMOVE——鼠标移动
    • WM_MOUSEWHEEL——鼠标滚轮滚动
    • WM_LBUTTONDOWN——鼠标左键按下
    • WM_LBUTTONUP——鼠标左键弹起
    • WM_LBUTTONDBLCLK——鼠标左键双击
    • WM_RBUTTONDOWN——鼠标右键按下
    • WM_RBUTTONUP——鼠标右键弹起
    • WM_RBUTTONDBLCLK——鼠标左键双击
    • WM_MBUTTONDOWN——鼠标中键按下
    • WM_MBUTTONUP——鼠标中键弹起
    • WM_MBUTTONDBLCLK——鼠标中键双击
      \qquad 我们只需要根据不断获取鼠标消息队列的消息并根据消息依次进行响应即可。

    \qquad 相信大家已经迫不及待了,那么请看下面一个简单的程序。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r1[]={30,20,130,60};//输入按钮的矩形参数
    int r2[]={170,20,220,60};//运行按钮的矩形参数
    int r3[]={260,20,310,60};//退出按钮的矩形参数
    int main()
    {
    	int i;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r1[0],r1[1],r1[2],r1[3]};//按钮1的矩形区域
    	RECT R2={r2[0],r2[1],r2[2],r2[3]};//按钮2的矩形区域
    	RECT R3={r3[0],r3[1],r3[2],r3[3]};//按钮2的矩形区域
    	LOGFONT f;
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r1[0],r1[1],r1[2],r1[3]);
    	rectangle(r2[0],r2[1],r2[2],r2[3]);
    	rectangle(r3[0],r3[1],r3[2],r3[3]);
    	MOUSEMSG m;//鼠标指针
    	setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    		if(m.uMsg==WM_LBUTTONDOWN)
    		{
    			for(i=0;i<=10;i++)
    			{
    				setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    				circle(m.x,m.y,2*i);
    				Sleep(25);//停顿2ms
    				circle(m.x,m.y,2*i);//抹去刚刚画的圆
    			}
    			FlushMouseMsgBuff();//清空鼠标消息缓存区
    		}
    	}
    	system("pause");//暂停,为了显示
    	closegraph();
    	return 0;
    }
    
    
    

    在这里插入图片描述
    \qquad 每点击鼠标以下,应该可以看到鼠标点击处有一个逐渐扩大并淡出的圆(截图无法清晰,在画面的中右侧),当循环体内Sleep的视觉大于20ms后视觉效果很强。
    \qquad 每响应一次鼠标左键单击事件,都会调用一次清空鼠标消息缓存区的函数FlushMouseMsgBuff(),如果没有这个函数会怎么样呢?如果我们快速连续地单击鼠标左键N次,那么特效就会播放N次,如果特效播放速度比单击的速度慢,那么即使你停下来了,程序仍然会接着播放单击特效,因为你的左键单击仍然在鼠标的消息队列m.uMsg中的鼠标消息没有响应完。
    \qquad 这里需要解释的是一个二元光栅设置函数setrop2(),二元光栅是混合背景色和当前颜色的模式。我们这里采用的方式是同或(NOT XOR)的方式,若底色为白色(1),则当前颜色不变;若底色是黑色(0),则当前颜色反色。为什么需要采用这种方式呢?因为我们在第二次抹去原来的圆的时候不能采用白色,否则如果背景色原来就为黑(比如按钮和文字),就也会被抹成白色。而背景色与任意一个颜色同或两次都为其本身,即可起到还原背景色的效果。这里的背景色与cleardevice()前面那个背景色不同,这里的是指执行这一条绘画指令之前屏幕上的颜色。

    2.3.2.光标感应

    \qquad 我们希望鼠标移到按钮上时按钮会有所变化,移开按钮时又会回到原样。这里我们采用一种简单的填充颜色的方法,就是按钮变色。我们需要解决一个问题就是按钮变色了但是按钮的文字不能被覆盖,那么我们还是需要使用到二元光栅。只是我们这次的模式改成了同或。
    \qquad 为了方便起见,存放三个按钮的数组我们合并为了一个二维数组,在鼠标事件中更容易使用和分配任务。

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    int r[3][4]={{30,20,130,60},{170,20,220,60},{260,20,310,60}};//三个按钮的二维数组
    
    int button_judge(int x,int y)
    {
    	if(x>r[0][0] && x<r[0][2] && y>r[0][1] && y<r[0][3])return 1;
    	if(x>r[1][0] && x<r[1][2] && y>r[1][1] && y<r[1][3])return 2;
    	if(x>r[2][0] && x<r[2][2] && y>r[2][1] && y<r[2][3])return 3;
    	return 0;
    }
    int main()
    {
    	int i,event=0;
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(15);//延时15ms
    	}
    	RECT R1={r[0][0],r[0][1],r[0][2],r[0][3]};
    	RECT R2={r[1][0],r[1][1],r[1][2],r[1][3]};
    	RECT R3={r[2][0],r[2][1],r[2][2],r[2][3]};
    	LOGFONT f;
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r[0][0],r[0][1],r[0][2],r[0][3]);
    	rectangle(r[1][0],r[1][1],r[1][2],r[1][3]);
    	rectangle(r[2][0],r[2][1],r[2][2],r[2][3]);
    	MOUSEMSG m;//鼠标指针
    	
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    
    		switch(m.uMsg)
    		{
    			case WM_MOUSEMOVE:
    				setrop2(R2_XORPEN);
    				setlinecolor(LIGHTCYAN);//线条颜色为亮青色
    				setlinestyle(PS_SOLID, 3);//设置画线样式为实现,10磅
    				setfillcolor(WHITE);//填充颜色为白色
    				if(button_judge(m.x,m.y)!=0)
    				{
    					if(event != button_judge(m.x,m.y))
    					{
    						event = button_judge(m.x,m.y);//记录这一次触发的按钮
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//有框填充矩形(X1,Y1,X2,Y2)
    					}
    				}
    				else
    				{
    					if(event != 0)//上次触发的按钮未被修正为原来的颜色
    					{
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//两次同或为原来颜色
    						event = 0;
    					}
    				}
    				break;
    			case WM_LBUTTONDOWN:
    				setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    				for(i=0;i<=10;i++)
    				{
    					setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    					circle(m.x,m.y,2*i);
    					Sleep(30);//停顿30ms
    					circle(m.x,m.y,2*i);//抹去刚刚画的圆
    				}
    				break;
    				FlushMouseMsgBuff();//清空鼠标消息缓存区
    		}
    	}
    	system("pause");//暂停,为了显示
    	return 0;
    }
    
    

    在这里插入图片描述
    \qquad 这里我们运用了两次设置二元光栅的函数setrop2,在鼠标的移动条件内(case MOUSEMOVE),我们使用的是屏幕颜色和当前颜色异或,这是为什么呢?因为fillrectangle()函数是画一个有框填充矩形,我们让这个有框填充矩形和原按钮的一样大。由于线条的颜色为亮青色,填充颜色为白色(1),白色的填充颜色和屏幕颜色异或,取的是屏幕颜色的反色。按钮的边框是黑色(0),它与亮青色异或,则会保留原来的亮青色。
    \qquad 与同或一样,异或两次等于没有执行操作,所以可以还原到原屏幕画布的颜色。

    2.3.3.进度条

    \qquad 既然涉及到进度条了,那么就应该涉及到正式程序了,这里我不想涉及太多的专业知识影响大家理解,但又不能让程序运行得太快以至于看不出进度条的变化,所以我设计了一个简单的弹性球轨迹作图程序。
    \qquad 假设球半径为R,初始高度为 h 0 h_0 h0,初速度为0(自由落体),非弹性碰撞时能量损失率为 α \alpha α。计算部分子函数如下:

    int simulation()
    {
    	float dt = 0.01;//仿真间隔10ms
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    	}
    	free(h);
    	free(v);//释放内存
    	return 0;
    }
    

    \qquad 当然,我们还需要绘图网格,定义绘图网格的函数如下:

    void init_figure()
    {
    	int i;
    	setrop2(R2_COPYPEN);//当前颜色
    	setlinecolor(BLACK);
    	setlinestyle(PS_SOLID);//实线
    	rectangle(30,100,420,330);//外框线
    	setlinestyle(PS_DOT);//点线
    	for(i=30+39;i<420;i+=39)
    	{
    		line(i,100,i,330);//竖直辅助线
    	}
    	for(i=100+23;i<330;i+=23)
    	{
    		line(30,i,420,i);//水平辅助线
    	}
    }
    

    \qquad 注意,我们使用了rectangle()空心矩形函数绘制网格外框架,使用了line函数依次画出了辅助线。

    \qquad 我们现在的目标就是将h的坐标转换到网格上去,绘制出球心的轨迹,这样似乎并不复杂,只需要对simulation()函数稍加修改即可。

    int simulation()
    {
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);//画点putpixel(X,Y,color*)
    		Sleep(dt*1000);//延时
    	}
    	free(h);
    	free(v);
    	return 0;
    }
    

    \qquad 这里的新函数putpixel(X,Y,color*)是画像素点的函数,适合刻画不连续或不规则的移动轨迹。
    \qquad 现在我们只剩下了刻画进度条的函数了,进度条的刷新很明显是应该放在for循环里面的,那么我们采用什么进度条的格式呢?进度条可以有圆形、扇形、长条连续型、长条不连续型等多种,我们这里采用的是环形进度条,将进度数字显示在环中心。请看以下的对simulation()函数改进的代码:

    //仿真运行
    int simulation()
    {
    	char t[3];//百分值的字符
    	char *out_text;//带百分号的百分字符
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	RECT r={370,35,400,65};//百分值显示区域的矩形指针
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	setfillcolor(WHITE);
    	setlinecolor(WHITE);
    	fillrectangle(354,19,411,81);//覆盖原进度条区域
    	setlinestyle(PS_NULL);//无线条
    	setbkmode(TRANSPARENT);//设置文字填充背景为透明
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	BeginBatchDraw();//开始缓存区
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		setfillcolor(WHITE);
    		setlinecolor(WHITE);
    		fillrectangle(354,19,416,81);//覆盖原进度条区域
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		setlinestyle(PS_SOLID);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);
    		setfillcolor(BLUE);
    		setlinestyle(PS_NULL);
    		fillpie(355,20,415,80,0,process_duty*2*PI);
    		setfillcolor(WHITE);
    		fillcircle(385,50,20);
    		sprintf(t,"%d",(int)(process_duty*100.0));//整型转换为字符串
    		out_text = strcat(t,"%");//添加一个百分号
    		drawtext(out_text,&r,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    		Sleep(dt*1000);
    		FlushBatchDraw();//刷新缓存区
    	}
    	EndBatchDraw();//结束缓存区
    	free(h);
    	free(v);
    	return 0;
    }
    

    \qquad 这里我们需要多加载一个头文件<string.h>。
    \qquad 首先需要计算进度条的坐标,把环形进度条区域用白色矩形刷新掉,环形进度条需要一个扇形和圆形的组合,扇形的角度是0~360°。这里我们用到了fillpie(X1,Y1,X2,Y2,start_angle,end_angle),前四个参数为椭圆扇形的外接矩形坐标,后两个参数分别为起始角和终止角(弧度制)。每过一次迭代都重新计算终止角(起始角始终为0),即可起到扇形角度逐渐增长的效果,再用一个白色填充圆覆盖中心部分即可变成环形进度条。
    \qquad FlushBatchDraw()函数是刷新缓存区的函数,与BeginBatchDraw()EndBatchDraw()一起使用,如果我们绘图之后不想立即显示,而想批量绘图最后一起刷新画板,用缓存区的方法再合适不过了。

    3.完整代码及效果

    #include <graphics.h>              // 引用图形库头文件
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>				//用到了定时函数sleep()
    #include <math.h>
    #include <string.h>
    #define PI 3.1416
    int r[3][4]={{30,20,130,60},{170,20,220,60},{260,20,310,60}};//三个按钮的二维数组
    float alpha,R,h0,sim_t;//碰撞时的能量损失率,球的半径、初始高度、仿真时间
    //按钮判断函数
    int button_judge(int x,int y)
    {
    	if(x>r[0][0] && x<r[0][2] && y>r[0][1] && y<r[0][3])return 1;
    	if(x>r[1][0] && x<r[1][2] && y>r[1][1] && y<r[1][3])return 2;
    	if(x>r[2][0] && x<r[2][2] && y>r[2][1] && y<r[2][3])return 3;
    	return 0;
    }
    //初始化图像
    void init_figure()
    {
    	int i;
    	setrop2(R2_COPYPEN);//当前颜色
    	setlinecolor(BLACK);
    	setlinestyle(PS_SOLID);//实线
    	rectangle(30,100,420,330);//外框线
    	setlinestyle(PS_DOT);//点线
    	for(i=30+39;i<420;i+=39)
    	{
    		line(i,100,i,330);//竖直辅助线
    	}
    	for(i=100+23;i<330;i+=23)
    	{
    		line(30,i,420,i);//水平辅助线
    	}
    }
    //仿真运行
    int simulation()
    {
    	char t[3];//百分值的字符
    	char *out_text;
    	float dt = 0.01;//仿真间隔10ms
    	float dy = 230/h0;//单位纵坐标
    	long int N = (long int)(sim_t/dt);//迭代次数
    	float *h=(float*)calloc(N,sizeof(float));//高度
    	float *v=(float*)calloc(N,sizeof(float));//速度(竖直方向)
    	long int i;//迭代变量
    	float process_duty;//进度
    	RECT r={370,35,400,65};//百分值显示区域的矩形指针
    	init_figure();//初始化图像网格
    	setrop2(R2_COPYPEN);//当前颜色
    	setfillcolor(WHITE);
    	setlinecolor(WHITE);
    	fillrectangle(354,19,411,81);//覆盖原进度条区域
    	setlinestyle(PS_NULL);//无线条
    	setbkmode(TRANSPARENT);//设置文字填充背景为透明
    	//计算步骤
    	h[0]=h0;v[0]=0;
    	BeginBatchDraw();//开始缓存区
    	for(i=1;i<N;i++)
    	{
    		if(h[i-1]>R)//未发生碰撞
    		{
    			v[i]=v[i-1]-9.8*dt;//速度计算
    		}
    		else//发生碰撞,动能损失alpha,速度损失alpha的开方
    		{
    			v[i]=-sqrt(alpha)*v[i-1];	
    		}
    		setfillcolor(WHITE);
    		setlinecolor(WHITE);
    		fillrectangle(354,19,416,81);//覆盖原进度条区域
    		h[i]=h[i-1]+v[i]*dt;//高度计算
    		process_duty = (i+1)/(float)(N);
    		setlinestyle(PS_SOLID);
    		putpixel(30+(int)(process_duty*390),330-(int)(h[i]*dy),RED);
    		setfillcolor(BLUE);
    		setlinestyle(PS_NULL);
    		fillpie(355,20,415,80,0,process_duty*2*PI);
    		setfillcolor(WHITE);
    		fillcircle(385,50,20);
    		sprintf(t,"%d",(int)(process_duty*100.0));//整型转换为字符串
    		out_text = strcat(t,"%");//添加一个百分号
    		drawtext(out_text,&r,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    		Sleep(dt*1000);
    		FlushBatchDraw();//刷新缓存区
    	}
    	EndBatchDraw();//结束缓存区
    	free(h);
    	free(v);
    	return 0;
    }
    
    int main()
    {
    	int i,event=0;
    	char s[30];//输入字符串变量
    	short win_width,win_height;//定义窗口的宽度和高度
    	win_width = 480;win_height = 360;
    	initgraph(win_width,win_height);//初始化窗口(黑屏)
    	for(i=0;i<256;i+=5)
    	{
    		setbkcolor(RGB(i,i,i));//设置背景色,原来默认黑色
    		cleardevice();//清屏(取决于背景色)
    		Sleep(30);//延时30ms
    	}
    	RECT R1={r[0][0],r[0][1],r[0][2],r[0][3]};
    	RECT R2={r[1][0],r[1][1],r[1][2],r[1][3]};
    	RECT R3={r[2][0],r[2][1],r[2][2],r[2][3]};
    	LOGFONT f;//字体样式指针
    	gettextstyle(&f);					//获取字体样式
    	_tcscpy(f.lfFaceName,_T("宋体"));	//设置字体为宋体
    	f.lfQuality = ANTIALIASED_QUALITY;    // 设置输出效果为抗锯齿  
    	settextstyle(&f);                     // 设置字体样式
    	settextcolor(BLACK);				//BLACK在graphic.h头文件里面被定义为黑色的颜色常量
    	drawtext("输入参数",&R1,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R1内输入文字,水平居中,垂直居中,单行显示
    	drawtext("运行",&R2,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R2内输入文字,水平居中,垂直居中,单行显示
    	drawtext("退出",&R3,DT_CENTER | DT_VCENTER | DT_SINGLELINE);//在矩形区域R3内输入文字,水平居中,垂直居中,单行显示
    	setlinecolor(BLACK);
    	rectangle(r[0][0],r[0][1],r[0][2],r[0][3]);
    	rectangle(r[1][0],r[1][1],r[1][2],r[1][3]);
    	rectangle(r[2][0],r[2][1],r[2][2],r[2][3]);
    	MOUSEMSG m;//鼠标指针
    	
    	while(true)
    	{
    		m = GetMouseMsg();//获取一条鼠标消息
    
    		switch(m.uMsg)
    		{
    			case WM_MOUSEMOVE:
    				setrop2(R2_XORPEN);
    				setlinecolor(LIGHTCYAN);//线条颜色为亮青色
    				setlinestyle(PS_SOLID, 3);//设置画线样式为实现,10磅
    				setfillcolor(WHITE);//填充颜色为白色
    				if(button_judge(m.x,m.y)!=0)
    				{
    					if(event != button_judge(m.x,m.y))
    					{
    						event = button_judge(m.x,m.y);//记录这一次触发的按钮
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//有框填充矩形(X1,Y1,X2,Y2)
    					}
    				}
    				else
    				{
    					if(event!=0)//上次触发的按钮未被修正为原来的颜色
    					{
    						fillrectangle(r[event-1][0],r[event-1][1],r[event-1][2],r[event-1][3]);//两次同或为原来颜色
    						event = 0;
    					}
    				}
    				break;
    			case WM_LBUTTONDOWN:
    				setrop2(R2_NOTXORPEN);//二元光栅——NOT(屏幕颜色 XOR 当前颜色)
    				for(i=0;i<=10;i++)
    				{
    					setlinecolor(RGB(25*i,25*i,25*i));//设置圆颜色
    					circle(m.x,m.y,2*i);
    					Sleep(20);//停顿30ms
    					circle(m.x,m.y,2*i);//抹去刚刚画的圆
    				}
    				//按照按钮判断左键单击后的操作
    				switch(button_judge(m.x,m.y))
    				{
    					//复原按钮原型
    					case 1:
    						InputBox(s,30,"请输入碰撞时的能量损失率、球的半径、初始高度、仿真时间");
    						sscanf(s,"%f%f%f%f",&alpha,&R,&h0,&sim_t);//将输入字符串依次扫描到全局变量里面
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						break;
    					case 2:
    						simulation();//仿真运行
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						break;
    					case 3:
    						closegraph();//关闭绘图环境
    						exit(0);//正常退出
    					default:
    						FlushMouseMsgBuffer();//单击事件后清空鼠标消息
    						//printf("\r\n(%d,%d)",m.x,m.y);//打印鼠标坐标,方便调试时确定区域
    						break;
    				}
    				break;
    		}
    	}
    	return 0;
    }
    
    

    在这里插入图片描述
    在这里插入图片描述
    希望本文对您有帮助,谢谢阅读。

    展开全文
  • 2021年前端面试题及答案

    万次阅读 多人点赞 2020-02-11 19:29:34
    前端面试汇总(2020年) 一 大纲 ...4、前端安全性问题 ...5、前端跨域问题 ...7、前端http相关问题 ...9、前端技术栈问题 ...由于新冠肺炎疫情,现在成天呆在家里,加上也要准备面试,就在家里面试题...

    前端面试汇总(2020年)

    大纲

    1、前言

    2、前端工程化

    3、前端设计模式

    4、前端安全性问题

    5、前端跨域问题

    6、前端数据加密

    7、前端http相关问题

    8、*前端基础知识点面试题

    9、前端技术栈问题

    前言

    由于新冠肺炎疫情,现在成天呆在家里,加上也要准备面试,就在家里看面试题,看着网上一堆面试题,决定收集常见题目汇总一下。关于面试大纲,我认为每个人都是千差万别的。因为面试官都是对简历所写的项目经验进行深挖或者对你所掌握的基本技能进行考察。

    前端工程化

    1

    什么是"前端工程化"?

    前端工程化是使用软件工程的技术和方法来进行前端的开发流程、技术、工具、经验等规范化、标准化,其主要目的为了提高效率和降低成本,即提高开发过程中的开发效率,减少不必要的重复工作时间,而前端工程本质上是软件工程的一种,因此我们应该从软件工程的角度来研究前端工程。

    2

    如何做"前端工程化"?

    前端工程化就是为了让前端开发能够“自成体系”,个人认为主要应该从模块化组件化规范化自动化四个方面思考。

    前端设计模式

    前端常见的设计模式主要有以下几种,具体设计模式查看这篇文章
    1. 单例模式
    2. 工厂模式
    3. 策略模式
    4. 代理模式
    5. 观察者模式
    6. 模块模式
    7. 构造函数模式
    8. 混合模式

    前端安全性问题

    这个是老的话题,有的在初中级前端面试中可能不会提到。但是在高级面试的时候,你要说出前端安全性问题防御,及前端常见安全性问题的攻击原理是什么。

    1

    xss跨站脚本攻击原理?如何进行?防御手段?

    如何进行:如何XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

    主要原理:过于信任客户端提交的数据!

    防御手段:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。

    2

    CSRF跨站请求伪造原理?如何进行?防御手段?

    如何进行:当你在某网页登录之后,在没有关闭网页的情况下,收到别人的链接。例如:http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=1&password_conf=1&Change=Change#

    点击链接,会利用浏览器的cookie把密码改掉。

    主要原理:在没有关闭相关网页的情况下,点击其他人发来的CSRF链接,利用客户端的cookie直接向服务器发送请求。

    防御手段:

    检测Referer

    Anti-CSRF token机制

    业务上要求用户输入原始密码(简单粗暴),攻击者在不知道原始密码的情况下,无论如何都无法进行CSRF攻击。

    3

    Sql脚本注入原理?如何进行?防御手段?  

    如何进行:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

    主要原理:通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令

    防御手段:

    使用预编译,绑定变量(推荐)。

    检查数据类型。

    过滤特殊字符和语句。

    页面不错误回显。

    4

    web上传漏洞原理?如何进行?防御手段?  

    如何进行:用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。

    主要原理:当文件上传时没有对文件的格式和上传用户做验证,导致任意用户可以上传任意文件,那么这就是一个上传漏洞。

    防御手段:

    1. 最有效的,将文件上传目录直接设置为不可执行,对于Linux而言,撤销其目录的'x'权限;实际中很多大型网站的上传应用都会放置在独立的存储上作为静态文件处理,一是方便使用缓存加速降低能耗,二是杜绝了脚本执行的可能性;
    2. 文件类型检查:强烈推荐白名单方式,结合MIME Type、后缀检查等方式;此外对于图片的处理可以使用压缩函数或resize函数,处理图片的同时破坏其包含的HTML代码;
    3. 使用随机数改写文件名和文件路径,使得用户不能轻易访问自己上传的文件;
    4. 单独设置文件服务器的域名;

    前端跨越问题

    1

    什么是跨域?  

    由浏览器同源策略限制的一类请求场景,当不同地址,不同端口,不同级别,不同协议就会构成跨域。

    2

    什么是同源策略?  

    所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

    它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。

    3

    如何解决跨域? 能说1,2,7,8就行。

    1、 通过jsonp跨域

    2、CORS

    3、 document.domain + iframe跨域

    4、 location.hash + iframe

    5、 window.name + iframe跨域

    6、 postMessage跨域

    7、 nginx代理跨域

    8、 nodejs中间件代理跨域

    9、 WebSocket协议跨域

    前端数据加密问题

    1

    一般如何处理用户敏感信息?  

    前端一般使用md5、base64加密、sha1加密,想要了解详情请自行百度。

    前端http相关问题

    1

    HTTP常用状态码及其含义?  

    1xx:指示信息--表示请求已接收,继续处理

    100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新)

    101 Switching Protocols 服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新)

    2xx:成功--表示请求已被成功接收、理解、接受

    200 OK 一切正常,对GET和POST请求的应答文档跟在后面。

    201 Created 服务器已经创建了文档,Location头给出了它的URL。

    202 Accepted 已经接受请求,但处理尚未完成。

    203 Non-Authoritative Information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝(HTTP 1.1新)。

    204 No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。

    205 Reset Content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容(HTTP 1.1新)。

    206 Partial Content 客户发送了一个带有Range头的GET请求,服务器完成了它(HTTP 1.1新)。

    3xx:重定向--要完成请求必须进行更进一步的操作

    300 Multiple Choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。

    301 Moved Permanently 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。

    302 Found 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求http://host/~user(缺少了后面的斜杠),有的服务器返回301,有的则返回302。严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。

    303 See Other 类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取(HTTP 1.1新)。

    304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

    305 Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取(HTTP 1.1新)。

    307 Temporary Redirect 和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时 才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。(HTTP 1.1新)

    4xx:客户端错误--请求有语法错误或请求无法实现

    400 Bad Request 请求出现语法错误。

    401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。

    403 Forbidden 资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。

    404 Not Found 无法找到指定位置的资源。这也是一个常用的应答。

    405 Method Not Allowed 请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用。(HTTP 1.1新)

    406 Not Acceptable 指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容(HTTP 1.1新)。

    407 Proxy Authentication Required 类似于401,表示客户必须先经过代理服务器的授权。(HTTP 1.1新)

    408 Request Timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新)

    409 Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。(HTTP 1.1新)

    410 Gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。(HTTP 1.1新)

    411 Length Required 服务器不能处理请求,除非客户发送一个Content-Length头。(HTTP 1.1新)

    412 Precondition Failed 请求头中指定的一些前提条件失败(HTTP 1.1新)。

    413 Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头(HTTP 1.1新)。

    414 Request URI Too Long URI太长(HTTP 1.1新)。

    416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。(HTTP 1.1新)

    5xx:服务器端错误--服务器未能实现合法的请求

    500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。

    501 Not Implemented 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求。

    502 Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。

    503 Service Unavailable 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。

    504 Gateway Timeout 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。(HTTP 1.1新)505 HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新)

    2

    websocket和轮询及长轮询区别  

    轮询如下:

    客户端:啦啦啦,有没有新信息(Request)服务端:没有(Response)客户端:啦啦啦,有没有新信息(Request)服务端:没有。。(Response)客户端:啦啦啦,有没有新信息(Request)服务端:你好烦啊,没有啊。。(Response)客户端:啦啦啦,有没有新消息(Request)服务端:好啦好啦,有啦给你。(Response)客户端:啦啦啦,有没有新消息(Request)服务端:。。。。。没。。。。没。。。没有(Response) ---- loop

    长轮询如下:

    客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)服务端:额。。 等待到有消息的时候。。来 给你(Response)客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

    websocket如下:

    websocket解决了HTTP的这几个难题。 首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。

    所以上面的情景可以做如下修改。

    客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)客户端:麻烦你有信息的时候推送给我噢。。服务端:ok,有的时候会告诉你的。服务端:balabalabalabala服务端:balabalabalabala服务端:哈哈哈哈哈啊哈哈哈哈服务端:笑死我了哈哈哈哈哈哈哈

    3

    Http和Https的区别?  

    1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

    2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

    3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

    4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

    *前端基础知识点面试题

    1

    HTML/5、CSS/3相关  

    一、html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

      新特性:

      HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
      拖拽释放(Drag and drop) API
      语义化更好的内容标签(header,nav,footer,aside,article,section)
      音频、视频API(audio,video)
      画布(Canvas) API
      地理(Geolocation) API
      本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
      sessionStorage 的数据在浏览器关闭后自动删除
      表单控件,calendar、date、time、email、url、search
      新的技术webworker, websocket, Geolocation

      移除元素:
      纯表现的元素:basefont,big,center,font, s,strike,tt,u;
      对可用性产生负面影响的元素:frame,frameset,noframes;
      h5新标签兼容:
      IE8/IE7/IE6支持通过document.createElement方法产生的标签,
      可以利用这一特性让这些浏览器支持HTML5新标签,
      当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架
     
      如何区分:
      DOCTYPE声明\新增的结构元素\功能元素

    二、CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?

      CSS 选择符:

      1.id选择器( # myid)

       2.类选择器(.myclassname)

      3.标签选择器(div, h1, p)

      4.相邻选择器(h1 + p)

      5.子选择器(ul > li)

      6.后代选择器(li a)

      7.通配符选择器( * )

      8.属性选择器(a[rel = "external"])

      9.伪类选择器(a: hover, li:nth-child)

      可以继承的属性:

      可继承的样式: font-size font-family color, UL LI DL DD DT;

      不可继承的样式:border padding margin width height ;

      优先级:

      !important > id > class > tag

      important 比 内联优先级高,但内联比 id 要高

      CSS3新增伪类举例:

      p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。

      p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。

      p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。

      p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。

      p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。

      :enabled :disabled 控制表单控件的禁用状态。

      :checked 单选框或复选框被选中。

    三、CSS3有哪些新特性?

    更详细的请见:https://www.cnblogs.com/qianduantuanzhang/p/7793638.html

      CSS3实现圆角(border-radius),阴影(box-shadow),

      对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform)

      transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,定位,倾斜

      增加了更多的CSS选择器 多背景 rgba

      在CSS3中唯一引入的伪元素是::selection.

      媒体查询,多栏布局

      border-image

    四、解释盒模型宽高值得计算方式,边界塌陷,负值作用,box-sizing概念? 

      1. 盒模型:IE 678 下(不添加doctype) 使用ie盒模型,宽度 = 边框 + padding + 内容宽度; chrom、IE9+、(添加doctype) 使用标准盒模型, 宽度 = 内容宽度。 
      2. box-sizing : 为了解决标准黑子和IE盒子的不同,CSS3增添了盒模型属性box-sizing,content-box(默认),border-box 让元素维持IE传统盒子模型, inherit 继承 父盒子模型; 
      3. 边界塌陷:块元素的 top 与 bottom 外边距有时会合并(塌陷)为单个外边距(合并后最大的外边距),这样的现象称之为 外边距塌陷。 
      4. 负值作用:负margin会改变浮动元素的显示位置,即使我的元素写在DOM的后面,我也能让它显示在最前面。

    五、BFC(Block Formatting Context) 是什么?应用? 

      1. BFC 就是 ‘块级格式上下文’ 的格式,创建了BFC的元素就是一个独立的盒子,不过只有BLock-level box可以参与创建BFC,它规定了内部的Bloc-level Box 如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素。 
      2. 应用场景: 
      1. 解决margin叠加的问题 
      2. 用于布局(overflow: hidden),BFC不会与浮动盒子叠加。 
      3. 用于清除浮动,计算BFC高度。

    六、如何实现浏览器内多个标签页之间的通信?

      调用localstorge、cookies等本地存储方式

    七、简要说一下CSS的元素分类

      块级元素:div,p,h1,form,ul,li;
      行内元素 : span,a,label,input,img,strong,em;

    八、解释下浮动和它的工作原理?清除浮动的方法

      浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。

      1.使用空标签清除浮动。

      这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。

      2.使用after伪对象清除浮动

     该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;

        #parent:after{

      content:".";

      height:0;

      visibility:hidden;

      display:block;

      clear:both;

     }

      3.设置overflow为hidden或者auto

      4.浮动外部元素

    九、CSS隐藏元素的几种方法(至少说出三种)

      Opacity:元素本身依然占据它自己的位置并对网页的布局起作用。它也将响应用户交互;
      Visibility:与 opacity 唯一不同的是它不会响应任何用户交互。此外,元素在读屏软件中也会被隐藏;
      Display:display 设为 none 任何对该元素直接打用户交互操作都不可能生效。此外,读屏软件也不会读到元素的内容。这种方式产生的效果就像元素完全不存在;
      Position:不会影响布局,能让元素保持可以操作;
      Clip-path:clip-path 属性还没有在 IE 或者 Edge 下被完全支持。如果要在你的 clip-path 中使用外部的 SVG 文件,浏览器支持度还要低;

    十、如何让一个盒子水平垂直居中

    复制代码

    复制代码

    //已知宽高<div class="div1"></div><style>
        .div1{
            width:400px;
            height:400px;
            position:absolute;
            left:50%;
            top:50% 
            margin:-200px 0 0 -200px;    }   
    </style>//未知宽高<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <style>
            .div1{
                position: absolute;
                left: 0;
                top: 0;
                bottom: 0;
                right: 0;
                margin: auto;
                border: 1px solid #000;
                width: 400px;
                height: 400px;        }    </style></head><body>    <div class="div1"></div></body></html>//未知宽高方法二:<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <style>
            .div1{
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%,-50%);
                border: 1px solid #000;
                width: 400px;
                height: 400px;        }    </style></head><body>    <div class="div1"></div></body></html>

    2

    JS部分

    1、cookie、localStorage、sessionStorage的区别和使用?

    cookie:是存储在本地的数据,有时候也用cookies,通常经过加密,应用最经典的就是判断注册用户是否已经登录过该网站。   localStorage:仅在客户端保存(即浏览器),不参与和服务器的通信;没有时间限制,即使浏览器关闭,数据依然存在;
       创建和访问localStorage:
            1)、设置数据:
            var forgetData = {phone:vm.phone};        localStorage.setItem("forgetData",JSON.Stringfy(forgetData));    //forgetData是存储在localStorage里边的本地数据;JSON.Stringfy(forgetData)是将数据转化为字符串格式;
                获取数据:
            vm.forgetData=JSON.parse(localStorage.getItem("forgetData"));  //将字符串转化为JSON化;
            2)、设置:localStorage.name = "zhao";
                 获取:localStorage.name    //zhao        localStorage.setItem(key,value);//设置数据        localStorage.getItem(key);//获取数据        localStorage.removeItem(key);//删除单个数据        localStorage.clear();//清除所有localStorage的数据
    
        sessionStorage:当用户的浏览器窗口关闭时,数据会被清除;
        
        共同点:都是保存在浏览器端,且同源的。
        区别:
            cookie数据始终在同源的http请求中携带9即使不需要),即cookie在浏览器和服务器之间来回传递;cookie数据还有路径的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据大小不能超过4K,同时因为每次http请求都会携带cookie,所以cookie只能保存很小的数据。
            sessionStorage和localStorage不会自动把数据发给服务器,只在本地保存,虽然也有大小限制,但是要比cookie大得多,可以达到5M或者更大。
            数据有效期不同,sessionStorage仅在当前浏览器窗口关闭前有效,不能持久保存;localStorage:始终有效,浏览器窗口关闭也一直保存;cookie:只在cookie设置的过期时间之前保存,即使浏览器窗口关闭。
            作用域不同,sessionStorage在不同浏览器窗口的数据不能共享,即使是同一个页面;localStorage在所有的同源窗口中都是共享的;cookie也是在同源窗口中共享的,

    2、如何实现浏览器多标签页之间的通信?

        调用localStorage、cookie本地存储方式。

    3、JavaScript的typeof返回类型有哪些?

    Object(null和Array)、number、undefined、string、Boolean、function

    4、类型转换

    强制转换:parseInt();parseFloat();number();

    5、数组的方法

    var list = [1,2,3];list.pop();//删除数组的最后一个元素 var list = [1,2];list.unshift(0,1);//头部添加  var list = [0,1,1,2,3];list.push(4,5);//尾部添加   var list = [1,2,3,4,5];var arr = list.concat(4,[5,6]);//把两个数组连接起来 //var arr = [1,2,3,4,5];  //var list = [1,2,3];list.join("-");    //1-2-3list.reverse();//3,2,1list.slice(1);//var list = [2,3];list.slice(1,2);//var list = [2];list.slice(1,-2);//设置了两个参数,终止下标为负数,当出现负数时,将负数加上数组长度的值来替换该位置的数。var arr = list.splice(0,1);//删除 var list = [2,3];  var arr = [1];可以删除任意数量的项,只需指定2个参数;要删除的第一项的位置和要删除的项数。例如splice(0,2);会删除当前数组的前两项list.splice(2,0,4,6);//插入,var list = [1,2,4,6,3]; 可以向指定位置插入任意数量的项,需要3个参数,起始位置、0(要删除的项数)、要插入的任意数量的项。例如splice(2,0,4,6);会从第二个位置插入4和6;list.splice(2,1,4,6);//替换,var list = [1,2,6,3]; 可以向指定位置插入任意数量的项,同时删除任意数量的项,需要3个参数,起始位置、要删除的项数、要插入的任意数量的项。例如splice(2,1,4,6);会从位置 2 开始插入4和6。list.sort();//按照第一个数字大小进行排序;function compare(a,b){
        return a-b;//正序;
        return b-a;//倒序;}list.sort(compare);

    6、ajax请求时get和post的区别?

    get:从服务器上获取数据,传送数据量小,安全性低,请求会被缓存,缓存是针对URL进行缓存的,get请求参数直接加在URL地址后面,一种参数组合就会产生一种URL的缓存,重复的请求结果是相同的;post:向服务器发送数据;传送数据量大,请求不会被缓存,参数封装在二进制的数据体中,服务器也不会记录参数,相对安全,所以涉及用户隐私的数据都要用post传送;

    7、ajax请求时,如何解释json数据?

    使用eval方法解析的时候,eval();不会去判断该字符串是否合法,而且json对象里的js方法也会被执行,这是非常危险的;推荐使用JSON.parse(); JSON.parse();把字符串转化成json。

    8、call和apply的区别?

    共同点:
        都可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象。
        另一种说法,都能够改变方法的执行上下文(执行环境),将一个对象的方法交给另一个对象来执行,并且是立即执行。
    不同点:
        apply();//最多只能有两个参数--新this对象和一个数组argArray,如果给该方法传递多个参数,则把参数都写进这个数组里边,当然,即使只有一个参数,也要写进数组里边。
        call();//可以接收多个参数,第一个参数apply()一样,后面则是一串参数列表。
        实际上,apply和call的功能是一样的,只是传入的参数列表的形式不同。

    9、http常用状态码?

        100  Continue  继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息    200  OK   正常返回信息    201  Created  请求成功并且服务器创建了新的资源    202  Accepted  服务器已接受请求,但尚未处理    301  Moved Permanently  请求的网页已永久移动到新位置。    302 Found  临时性重定向。    303 See Other  临时性重定向,且总是使用 GET 请求新的 URI。    304  Not Modified  自从上次请求后,请求的网页未修改过。    400 Bad Request  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。    401 Unauthorized  请求未授权。    403 Forbidden  禁止访问。    404 Not Found  找不到如何与 URI 相匹配的资源。    500 Internal Server Error  最常见的服务器端错误。    503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

    10.你有哪些性能优化的方法?

        (详情请看雅虎14条性能优化原则)。
    
          (1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
    
          (2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
    
          (3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
    
          (4) 当需要设置的样式很多时设置className而不是直接操作style。
    
          (5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
    
          (6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
    
          (7) 图片预加载,将样式表放在顶部,将脚本放在底部  加上时间戳。

    11.深拷贝和浅拷贝

        基本类型指的是简单的数据段,引用类型指的是多个值构成的对象;    var name = "John"; // 基本类型值
    
        var obj = new Object(); 
        obj.name = "John"; 
        // obj 为引用类型值
        
        在复制变量中,对于基本类型来说,两者互不影响,    var num = 1;    var num1 = num; // num1 = 1;
    
        var num1 = 3; // num还是1,不会变
        
        浅拷贝和深拷贝的区别:
        对于浅拷贝来说,对于一个数组(数组是一个对象),只要我们修改了一个拷贝数组,原数组也会跟着改变。
        因为他们引用的是同一个地址的数据,拷贝的时候并没有给b数组创造独立的内存,只是把a数组指向数据的指针拷贝给了b;
        而深拷贝就与其相反,将会给b数组创造独立的内存,并且将a数组的内容一一拷贝进来,两者互不影响。
        
        实现深拷贝:
        一:层级拷贝,用递归实现;
        二:JSON解析        var b = JSON.parse(JSON.stringify(a));        

    3

    其他  

    一、怎么让Chrome支持小于12px 的文字?

    这个我们在做移动端的时候,设计师图片上的文字假如是10px,我们实现在网页上之后。往往设计师回来找我们,这个字体能小一些吗?我设计的是10px?为啥是12px?其实我们都知道,谷歌Chrome最小字体是12px,不管你设置成8px还是10px,在浏览器中只会显示12px,那么如何解决这个坑爹的问题呢?

    我们的做法是:

    针对谷歌浏览器内核,加webkit前缀,用transform:scale()这个属性进行缩放!

    <style>pspan{font-size:10px;-webkit-transform:scale(0.8);display:block;}</style><p><span>haorooms博客测试10px</span></p>

    二、IOS手机浏览器字体齿轮

    修改-webkit-font-smoothing属性,结果是:-webkit-font-smoothing:none:无抗锯齿-webkit-font-smoothing: antialiased | subpixel-antialiased |default:灰度平滑

    三、如何修改chrome记住密码后自动填充表单的黄色背景?

    大体可以通过input : -webkit-autofill来进行修改!

    input:-webkit-autofill {background-color:#FAFFBD;background-image: none;color:#000;}

    四、谷歌浏览器运行下面代码,并解释!

    [].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})

    运行上面代码之后,会发现HTML层都被使用不同的颜色添加了一个高亮的边框。为什么会这样呢?

    首先我们来看

    [].forEach.call(),关于call()和apply(),我前面有文章也写过,具体可以看http://www.haorooms.com/post/js_constructor_pro

    [].forEach.call()等价于Array.prototype.forEach.call()

    其次我们来看$$("*")

    你可以在你的Chrome浏览器控制台中输入$$('a'),然后你就能得到一个当前页面中所有锚元素的列表。

    $$函数是许多现代浏览器命令行API中的一个部分,它等价于document.querySelectorAll,你可以将一个CSS选择器作为这个函数的参数,然后你就能够获得当前页面中所有匹配这个CSS选择器的元素列表。如果你在浏览器控制台以外的地方,你可以使用document.querySelectorAll('')来代替$$('')

    为元素添加颜色

    为了让元素都有一个漂亮的边框,我们在上面的代码中使用了CSS属性outline。outline属性位于CSS盒模型之外,因此它并不影响元素的属性或者元素在布局中的位置,这对于我们来说非常有用。这个属性和修改border属性非常类似,因此下面的代码应该不会很难理解:

    a.style.outline="1px solid #"+ color

    真正有趣的地方在于定义颜色部分:

    (~~(Math.random()*(1<<24))).toString(16)

    ~~的作用相当于parseInt,和我前面讲解的“|”功能类似,关于运算符“I” ,可以去看看!

    通过上面代码可以获取到一个随机的颜色值!

    五、input [type=search] 搜索框右侧小图标如何美化?

    美化效果如下图:

    enter image description here

    右侧默认的比较难看的按钮,美化成右侧效果。

    input[type="search"]::-webkit-search-cancel-button{-webkit-appearance: none;height:15px;width:15px;border-radius:8px;background:url("images/searchicon.png")no-repeat 00;background-size:15px15px;}

    用到的是伪元素::-webkit-search-cancel-button,关于什么是伪类和为元素,请看:http://www.haorooms.com/post/css_wl_wys

    六、iOS safari 如何阻止“橡皮筋效果”?

    可以参考一下知乎上的回答 https://www.zhihu.com/question/22256539 。

    但是,我们遇到的问题不是这样,我是要解决弹跳导致弹出层(position:absolute)的覆盖层高度小于100%;

    针对这个问题,我想到的解决方案如下:

    方法一: 把position:absolute改成position:fixed,并在弹出层之后,设置body的高度是100%;overflow是hidden。

    方法二:

    思路是获取苹果浏览器导航栏的高度。然后滚动的时候,重新获取其高度。在导航栏高度变小的时候,给弹出层增加高度的百分比!

    代码如下:

    //ios safari 伸缩判断var topbarHeight=window.outerHeight-window.innerHeight,agent=navigator.userAgent,globleflag=true;
            $(window).scroll(function(){if(agent.indexOf("iPhone")!=-1|| agent.indexOf("iPad")!=-1){var topbarHeightNow=window.outerHeight-window.innerHeight;if(topbarHeightNow<topbarHeight){
                        globleflag=false//此处写处理逻辑}else{
                     globleflag=true//此处写处理逻辑}}});

    七、实现点击文字,文字后面radio选中效果

    这个效果是前端很经常用到和遇到的效果了,实现这个效果的方式也很多,很多朋友用js和jquery来实现,但是最简单的,我们可以直接用lable标签的 for 属性来实现。

    看下下面例子:

    <form><labelfor="male">Male</label><inputtype="radio"name="sex"id="male"/><br/><labelfor="female">Female</label><inputtype="radio"name="sex"id="female"/></form>

    label 的for属性后面跟着input的id,就可以点击label,来触发input效果了,大家可以试一试!

    八、网站中,图片文件(jpg,png,gif),如何点击下载?而非点击预览?

    我们平时在网站中的图片,假如我们要下载,如下写:

    <ahref="haorooms博客.jpg">下载</a>

    我们点击下载按钮,只会预览“haorooms博客.jpg”这张图片,并不会出现下载框,另存为那种?那么我们如何做呢?

    我们只需要如下写

    <ahref="haorooms博客.jpg"download>下载</a>

    就可以下载了。点击如下进行尝试吧!下载

    不但如次,我们还可以指定文件名称,如下写法:

    <ahref="haorooms博客.jpg"download="haoroom前端博客图片下载">下载</a>

    测试如下:下载

    上面就是指定下载的写法!

    九、Math.min()比Math.max()大

    Math.min()<Math.max()// falseMath.min()>Math.max()// true

    因为Math.min() 返回 Infinity, 而 Math.max()返回 -Infinity。

    前端技术栈问题

    1

    vue相关问题?  

    更多前端技能请关注公众号”极致简文“

    往期精彩回顾

    React组件与生命周期

    React函数组件和Class组件以及Hooks

    2020年最火爆的Vue.js面试题

    Redux使用之我要买个女朋友(入门篇)

    关注公众号,精彩不间断

    展开全文
  • 优点:简单、代码少、容易掌握 缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题 2,结尾处加空div标签 clear:both 原理:添加一个空div,利用css提高的clear:both清除浮动,...

    近期总结一一些面试题 都是企业的面试题笔记题

    感觉薪资10k下的都会出笔试题   

    特别高的薪资都是直接技术面试或者是 现场编程 

    总结很多人的面试题,后期会对于单个知识点再说笔记详细讲解。

    最新Vue面试题网址:2021年 Vue经典面试题 -- 必问知识点 --(包含答案)_xm1037782843的博客-CSDN博客_vue面试题

    敬请关注公众 :包含全套 Vue 最新面试题  js最近面试题 等大量前端知识技术。

     

    部分都是百度的答案,不是特全面的,可以自己找下

    同时分享一个自己录制的CSS3动画特效经典案例【推荐教程】--后期会更新vue框架 微信小程序等内容。

    最近录制的ajax从基础到实战的视频,包含原生ajax  jquery的ajax 以及ajax接口获取数据等

    Ajax前端开发、项目实战、从零基础到精通、接口数据调用-学习视频教程-腾讯课堂

    红色为常见面试题

    =============================================================

    前端面试题: 

    1. 一个200*200的div在不同分辨率屏幕上下左右居中,用css实现

    <div style="width:500px;height:500px;border:1px solid green;display:flex;justify-content:center;align-items:center;">
      <div style="">
        上下左右居中
      </div>
    </div>

    2. 写一个左中右布局占满屏幕,其中左右两块是固定宽度200 ,中间自适应宽,要求先加载中间块,请写出结构及样式:

    <div id="left">我是左边</div>
        <div id="center">我是中间</div>
        <div id="right">我是右边</div>
    
    html,body{ margin: 0px;width: 100%; } 
    #left,#right{width: 200px;height: 200px;background-color: aqua;
        position: absolute;}
        #left{left: 0;top:0;}
        #right{right: 0;top:0;}
        #center{margin: 0 200px;background-color: blue;height: 200px;}

    或者利用弹性盒子

        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            html,
            body {
                height: 100%;
            }
    
            body {
                display: flex;
            }
    
            .left {
                width: 100px;
                background-color: rgb(199, 170, 223);
            }
    
            .center {
                background-color: rgb(151, 228, 148);
                flex: 1;
            }
    
            .right {
                width: 100px;
                background-color: rgb(199, 170, 223);
    
    
            }
        </style>
    
    <body>
        <div class="left">left</div>
        <div class="center">center</div>
        <div class="right">right</div>
    </body>
    

    3. 阐述清楚浮动的几种方式(常见问题)

    1.父级div定义 height

    原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
    优点:简单、代码少、容易掌握
    缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

    2.父级div定义 overflow:hidden

    原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
    优点:简单、代码少、浏览器支持好

    4. 结尾处加空div标签 clear:both

    原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
    优点:简单、代码少、浏览器支持好、不容易出现怪问题

    缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好

    5. 解释css sprites ,如何使用?

    CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。

    CSS Sprites为一些大型的网站节约了带宽,让提高了用户的加载速度和用户体验,不需要加载更多的图片

    6. 如何用原生js给一个按钮绑定两个onclick事件?

    Var  btn=document.getElementById(‘btn’);

    //事件监听 绑定多个事件

    var btn4 = document.getElementById("btn4");

    btn4.addEventListener("click",hello1);

    btn4.addEventListener("click",hello2);

    function hello1(){

     alert("hello 1");

    }

    function hello2(){

     alert("hello 2");

    }

    7. 拖拽会用到哪些事件

    · dragstart:拖拽开始时在被拖拽元素上触发此事件,监听器需要设置拖拽所需数据,从操作系统拖拽文件到浏览器时不触发此事件.

    · dragenter:拖拽鼠标进入元素时在该元素上触发,用于给拖放元素设置视觉反馈,如高亮

    · dragover:拖拽时鼠标在目标元素上移动时触发.监听器通过阻止浏览器默认行为设置元素为可拖放元素.

    · dragleave:拖拽时鼠标移出目标元素时在目标元素上触发.此时监听器可以取消掉前面设置的视觉效果.

    · drag:拖拽期间在被拖拽元素上连续触发

    · drop:鼠标在拖放目标上释放时,在拖放目标上触发.此时监听器需要收集数据并且执行所需操作.如果是从操作系统拖放文件到浏览器,需要取消浏览器默认行为.

    · dragend:鼠标在拖放目标上释放时,在拖拽元素上触发.将元素从浏览器拖放到操作系统时不会触发此事件.

    8. 请列举jquery中的选择器:

    9. Javascript中的定时器有哪些?他们的区别及用法是什么?

    setTimeout 只执行一次
    setInterval 会一直重复执行

    9.请描述一下 cookies sessionStorage和localstorage区别

    相同点:都存储在客户端
    不同点:1.存储大小

    · cookie数据大小不能超过4k。

    · sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

    2.有效时间

    · localStorage    存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;

    · sessionStorage  数据在当前浏览器窗口关闭后自动删除。

    · cookie          设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

    3. 数据与服务器之间的交互方式

    · cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端

    · sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

    10.计算一个数组arr所有元素的和

    var arr1=[1,2,3,4,5,6,7,8,9];

    var sum1=0;

    for (var i=0;i<=arr1.length;i++) {

    if (typeof arr1[i]=="number") {

    sum1+=arr1[i];

    }

    }

    document.write(sum1);

    //====================================

    function sum2(arr){

    var all=0;

    for (var i=0;i<arr.length;i++) {

    if (typeof arr[i]=="number") {

    all+=arr[i];

    }

    }

    return all;

    }

    document.write(sum2([1,2,3,4]));

    11.编写一个方法去掉数组里面 重复的内容  var arr=[1,2,3,4,5,1,2,3]

    一个数组去重的简单实现

     

    var arr = ['abc','abcd','sss','2','d','t','2','ss','f','22','d'];

    //定义一个新的数组

    var s = [];

    //遍历数组

    for(var i = 0;i<arr.length;i++){

        if(s.indexOf(arr[i]) == -1){  //判断在s数组中是否存在,不存在则push到s数组中

            s.push(arr[i]);

        }

    }

    console.log(s);

    //输出结果:["abc", "abcd", "sss", "2", "d", "t", "ss", "f", "22"]

    方法二:用sort()  然后相邻比较也可以实现

    12.document.write和innerHTML的区别:

    document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。

    innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。

    innerHTML将内容写入某个DOM节点,不会导致页面全部重绘

     

    innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

    13.ajax的步骤

    什么是ajax?

    ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页。

    如何使用ajax?

    第一步,创建xmlhttprequest对象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest对象用来和服务器交换数据。

    var xhttp;

    if (window.XMLHttpRequest) {

    //现代主流浏览器

    xhttp = new XMLHttpRequest();

    } else {

    // 针对浏览器,比如IE5或IE6

    xhttp = new ActiveXObject("Microsoft.XMLHTTP");

    }

    第二步,使用xmlhttprequest对象的open()和send()方法发送资源请求给服务器。

    第三步,使用xmlhttprequest对象的responseText或responseXML属性获得服务器的响应。

    第四步,onreadystatechange函数,当发送请求到服务器,我们想要服务器响应执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readyState发生改变都会触发onreadystatechange函数

    14.xml和json的区别,请用四个词语来形容

    ·  JSON相对于XML来讲,数据的体积小,传递的速度更快些

    ·  JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互

    ·  XML对数据描述性比较好;

    ·  JSON的速度要远远快于XML

     

    15.清楚浮动的方法?(多次出现在面试题)

    1.父级div定义 height
    原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
    优点:简单、代码少、容易掌握

    缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

    2,结尾处加空div标签 clear:both

    原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
    优点:简单、代码少、浏览器支持好、不容易出现怪问题
    缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好
    3,父级div定义 伪类:after 和 zoom

    原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
    优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)
    缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持
    4,父级div定义 overflow:hidden

    原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
    优点:简单、代码少、浏览器支持好
    缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。

     

    16.box-sizing常用的属性有哪些?分别有什么作用?

    属性值

    · box-sizing:content-box

    · box-sizing:border-box

    · box-sizing:inherit

     

    content-box

    · 这是box-sizing的默认属性值

    · 是CSS2.1中规定的宽度高度的显示行为

    · 在CSS中定义的宽度和高度就对应到元素的内容框

    · 在CSS中定义的宽度和高度之外绘制元素的内边距和边框

     

    border-box

    · 在CSS中微元素设定的宽度和高度就决定了元素的边框盒

    · 即为元素在设置内边距和边框是在已经设定好的宽度和高度之内进行绘制

    · CSS中设定的宽度和高度减去边框和内间距才能得到元素内容所占的实际宽度和高度

    (Q1)box-sizing: content-box|border-box|inherit;
    (Q2)content-box:宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
    border-box:元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。

     

    17.css选择器有哪些,选择器的权重的优先级

    选择器类型

    1、ID  #id

    2、class  .class

    3、标签  p

    4、通用  *

    5、属性  [type="text"]

    6、伪类  :hover

    7、伪元素  ::first-line

    8、子选择器、相邻选择器

    三、权重计算规则

    1. 第一等:代表内联样式,如: style=””,权值为1000。

    2. 第二等:代表ID选择器,如:#content,权值为0100。

    3. 第三等:代表类,伪类和属性选择器,如.content,权值为0010。

    4. 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。

    5. 通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。

    6. 继承的样式没有权值。

    18. 块级元素水平垂直居中的方法有哪些(三个方法)

    让div等块级元素水平和垂直都居中,即永远处于屏幕的正中央,当我们做如登录块时非常有用!

     实现一、原理:要让div等块级元素水平和垂直居中,必需知道该div等块级元素的宽度和高度,然后设置位置为绝对位置,距离页面窗口左边框和上边框的距离设置为50%,这个50%就是指页面窗口的宽度和高度的50%,最后将该div等块级元素分别左移和上移,左移和上移的大小就是该div等块级元素宽度和高度的一半。

       CSS代码:

    .mycss{ 

       width:300px;  

       height:200px;  

       position:absolute;  

       left:50%;  

       top:50%;  

       margin:-100px 0 0 -150px }

     实现二原理:利用CSS的margin设置为auto让浏览器自己帮我们水平和垂直居中。

       CSS代码:

    .mycss{

        position: absolute;

        left: 0px;

        right: 0;

        top: 0;

        bottom: 0;

        margin: auto;

        height: 200px;

        width: 300px;

    }

    jQuery实现水平和垂直居中

     原理:jQuery实现水平和垂直居中的原理就是通过jQuery设置div等块级元素的CSS,获取div等块级元素的左、上的边距偏移量,边距偏移量的算法就是用页面窗口 的宽度减去该div等块级元素的宽度,得到的值再除以2即左偏移量,右偏移量算法相同。注意div等块级元素的CSS设置要在resize()方法中完成,就是每次改变窗口大 小时,都要执行设置div等块级元素的CSS。

    jquery代码:

    $(window).resize(function(){

        $(".myblock").css({

            position: "absolute",

            left: ($(window).width() - $(".myblock").outerWidth())/2,

            top: ($(window).height() - $(".myblock").outerHeight())/2     });        

    });

    此外在页面载入时,就需要调用resize()方法

    $(function(){

        $(window).resize();

    });

     

    19.三个盒子,左右定宽,中间自适应有几种方法

    第一种:左右侧采用浮动 中间采用margin-left 和 margin-right 方法。

    代码如下:

    <div style="width:100%; margin:0 auto;"> 

     

           <div style="width:200px; float:right; background-color:#960">这是右侧的内容 固定宽度</div>

     

           <div style="width:150px; float:left; background:#6FF">这是左侧的内容 固定宽度</div>

     

           <div style="margin-left:150px;margin-right:200px; background-color:#9F3">中间内容,自适应宽度</div>

     

        </div>

    第二种:左右两侧采用绝对定位 中间同样采用margin-left margin-right方法:

     

    第三种负的margin

    使用这种方法就稍微复杂了一些了,使用的是负的margin值,而且html标签也增加了,先来看其代码吧:

    <div id="main">

     <div id="mainContainer">main content</div></div><div id="left">

     <div id="leftContainer" class="inner">left content</div></div><div id="right">

     <div id="rightContainer" class="inner">right</div></div>

    #main {

     float: left;

     width: 100%;

    }

    #mainContainer {

     margin: 0 230px;

     height: 200px;

     background: green;

    }

    #left {

     float: left;

     margin-left: -100%;

     width: 230px} 

    #right {

     float: left;

     margin-left: -230px;

     width: 230px;

    } 

    #left .inner,

    #right .inner {

     background: orange;

     margin: 0 10px;

     height: 200px;

    }

    20.js有几种数据类型,其中基本数据类型有哪些

    五种基本类型: Undefined、Null、Boolean、Number和String。

    1中复杂的数据类型————Object,Object本质上是由一组无序的名值对组成的。

    Object、Array和Function则属于引用类型

     

    21.undefined 和 null 区别

     

    null: Null类型,代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。

    undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。

    null是javascript的关键字,可以认为是对象类型,它是一个空对象指针,和其它语言一样都是代表“空值”,不过 undefined 却是javascript才有的。undefined是在ECMAScript第三版引入的,为了区分空指针对象和未初始化的变量,它是一个预定义的全局变量。没有返回值的函数返回为undefined,没有实参的形参也是undefined。

     

    javaScript权威指南: null 和 undefined 都表示“值的空缺”,你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。

    22.http 和 https 有何区别?如何灵活使用?

     

    http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。

    https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份


    23.常见的HTTP状态码

    2开头 (请求成功)表示成功处理了请求的状态代码。

    200   (成功)  服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 
    201   (已创建)  请求成功并且服务器创建了新的资源。 
    202   (已接受)  服务器已接受请求,但尚未处理。 
    203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。 
    204   (无内容)  服务器成功处理了请求,但没有返回任何内容。 
    205   (重置内容) 服务器成功处理了请求,但没有返回任何内容。
    206   (部分内容)  服务器成功处理了部分 GET 请求。

    3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

    300   (多种选择)  针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
    301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
    302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
    303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
    304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。 
    305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 
    307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

    4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。

    400   (错误请求) 服务器不理解请求的语法。 
    401   (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
    403   (禁止) 服务器拒绝请求。
    404   (未找到) 服务器找不到请求的网页。
    405   (方法禁用) 禁用请求中指定的方法。 
    406   (不接受) 无法使用请求的内容特性响应请求的网页。 
    407   (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
    408   (请求超时)  服务器等候请求时发生超时。 
    409   (冲突)  服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 
    410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。 
    411   (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 
    412   (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 
    413   (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 
    414   (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 
    415   (不支持的媒体类型) 请求的格式不受请求页面的支持。 
    416   (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 
    417   (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

    5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

    500   (服务器内部错误)  服务器遇到错误,无法完成请求。 
    501   (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 
    502   (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
    503   (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 
    504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
    505   (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

     

     

    24. 如何进行网站性能优化

    1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
    2. 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
      总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。
      前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
      一、页面级优化
    1. JavaScript 压缩和模块打包
    2. 按需加载资源
    3. 在使用 DOM 操作库时用上 array-ids
    4. 缓存
    5. 启用 HTTP/2
    6. 应用性能分析
    7. 使用负载均衡方案
    8. 为了更快的启动时间考虑一下同构
    9. 使用索引加速数据库查询
    10. 使用更快的转译方案
    11. 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染
    12. 用于未来的一个建议:使用 service workers + 流
    13. 图片编码优化

    25. react和vue有哪些不同,说说你对这两个框架的看法

    相同点

    · 都支持服务器端渲染

    · 都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范

    · 数据驱动视图

    · 都有支持native的方案,React的React native,Vue的weex

    不同点

    · React严格上只针对MVC的view层,Vue则是MVVM模式

    · virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制

    · 组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即'all in js'; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,jd写在同一个文件;

    · 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的

    · state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理

    26.什么是mvvm mvc是什么区别 原理

    一、MVC(Model-View-Controller)

    MVC是比较直观的架构模式,用户操作->View(负责接收用户的输入操作)->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)。

    MVC使用非常广泛,比如JavaEE中的SSH框架

     

    三、MVVM(Model-View-ViewModel)

    如果说MVP是对MVC的进一步改进,那么MVVM则是思想的完全变革。它是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应view

    27.px和em的区别

    px表示像素 (计算机屏幕上的一个点:1px = 1/96in),是绝对单位,不会因为其他元素的尺寸变化而变化;

    · 

    · 

    em表示相对于父元素的字体大小。em是相对单位 ,没有一个固定的度量值,而是由其他元素尺寸来决定的相对值。

    28.优雅降级和渐进增强

    渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。

    优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。

    其实渐进增强和优雅降级并非什么新概念,只是旧的概念换了一个新的说法。在传统软件开发中,经常会提到向上兼容向下兼容的概念。渐进增强相当于向上兼容,而优雅降级相当于向下兼容

    29.eval()的作用

    把字符串参数解析成JS代码并运行,并返回执行的结果;

    eval("2+3");//执行加运算,并返回运算值。  

    eval("varage=10");//声明一个age变量  

    eval的作用域

    functiona(){  

    1.  eval("var x=1"); //等效于 var x=1;  

    2.  console.log(x); //输出1  

    3. }  

    4. a();  

    5. console.log(x);//错误 x没有定

    30. JS哪些操作会造成内存泄露

    1)意外的全局变量引起的内存泄露

    function leak(){  

      leak="xxx";//leak成为一个全局变量,不会被回收  

    }

    2)闭包引起的内存泄露

    3)3)没有清理的DOM元素引用

    4)被遗忘的定时器或者回调 5)子元素存在引起的内存泄露

    31. 浏览器缓存有哪些,通常缓存有哪几种

    一、http缓存

    二、websql

    cookie

    localstorage

    sessionstorage

    flash缓存

    32:bootstrap响应式实现的原理

    百分比布局+媒体查询

    33.关于JS事件冒泡与JS事件代理(事件委托)

     事件作为DOM操作重要的一环,需要大家好好理解和运用,今天特意看了一下事件冒泡和事件代理的相关资料,感触颇深,也深感自己的无知不知道多浪费了多少内存,废话不多说进入正题:

    1.事件冒泡:

          通俗易懂的来讲,就是当一个子元素的事件被触发的时候(如onclick事件),该事件会从事件源(被点击的子元素)开始逐级向上传播,触发父级元素的点击事件。

    2.事件委托

        事件委托,首先按字面的意思就能看你出来,是将事件交由别人来执行,再联想到上面讲的事件冒泡,是不是想到了?对,就是将子元素的事件通过冒泡的形式交由父元素来执行。下面经过详细的例子来说明事件委托:

    有可能在开发的时候会遇到这种情况:如导航每一个栏目都要加一个事件,你可能会通过遍历来给每个栏目添加事件:

    事件委托是怎

    1. var ul = document.getElementById('parentUl');  

    2.     ul.οnclick=function (event) {  

    3.       var e = event||window.event,  

    4.               source = e.target || e.srcElement;//target表示在事件冒泡中触发事件的源元素,在IE中是srcElement  

    5.         if(source.nodeName.toLowerCase() == "li"){   //判断只有li触发的才会输出内容  

    6.             alert(source.innerHTML);  

    7.         }  

    8.         stopPropagation(e);                           //阻止继续冒泡  

    9.     };  

    10.     function addElement() {  

    11.         var li = document.createElement('li');  

    12.         li.innerHTML="我是新孩子";  

    13.         ul.appendChild(li);  

    14.     }  

    34. CSS样式覆盖规则

    规则一:由于继承而发生样式冲突时,最近祖先获胜。

    规则二:继承的样式和直接指定的样式冲突时,直接指定的样式获胜

    规则三:直接指定的样式发生冲突时,样式权值高者获胜。

    样式的权值取决于样式的选择器,权值定义如下表。

    CSS选择器

    权值

    标签选择器

    1

    类选择器

    10

    ID选择器

    100

    内联样式

    1000

    伪元素(:first-child等)

    1

    伪类(:link等)

    10

    可以看到,内联样式的权值>>ID选择器>>类选择器>>标签选择器,除此以外,后代选择器的权值为每项权值之和,比如”#nav .current a”的权值为100 + 10 + 1 = 111。

    规则四:样式权值相同时,后者获胜。

    规则五:!important的样式属性不被覆盖。

    !important可以看做是万不得已的时候,打破上述四个规则的”金手指”。如果你一定要采用某个样式属性,而不让它被覆盖的,可以在属性值后加上!important,以规则四的例子为例,”.byline a {color:red !important;}”可以强行使链接显示红色。大多数情况下都可以通过其他方式来控制样式的覆盖,不能滥用!important。

    35. 介绍一下box-sizing属性

    兼容问题 
    首先,box-sizing属性在FireFox中存在兼容问题,所以需要使用-moz-box-sizing做一下兼容。

     

    属性值

    · box-sizing:content-box

    · box-sizing:border-box

    · box-sizing:inherit

     

    content-box

    · 这是box-sizing的默认属性值

    · 是CSS2.1中规定的宽度高度的显示行为

    · 在CSS中定义的宽度和高度就对应到元素的内容框

    · 在CSS中定义的宽度和高度之外绘制元素的内边距和边框

     

    border-box

    · 在CSS中微元素设定的宽度和高度就决定了元素的边框盒

    · 即为元素在设置内边距和边框是在已经设定好的宽度和高度之内进行绘制

    · CSS中设定的宽度和高度减去边框和内间距才能得到元素内容所占的实际宽度和高度

    36. css选择符有哪些?优先级算法如何计算?(常见)

    37. 请简要描述margin重合问题,及解决方式

    1.同向margin的重叠:
    1图片的margin-top与3图片的margin-top发生重叠,2图片的margin-bottom与3图片的margin-bottom发生重叠。这时候重叠之后的margin值由发生重叠两片的最大值决定;如果其中一个出现负值,则由最大的正边距减去绝对值最大的负边距,如果没有最大正边距,则由0减去绝对值最大的负边距。
    解决同向重叠的方法:
    (1)在最外层的div中加入overflow:hidden;zoom:1
    (2)在最外层加入padding:1px;属性
    (3)在最外层加入:border:1px solid #cacbcc;
    2.异向重叠问题:
    1图片的margin-bottom与2图片的margin-top发生重叠,这时候重叠之后的margin值由发生重叠两图片的最大值的决定的。
    解决异向重叠问题:
    float:left(只能解决IE6浏览器中的异向重叠问题,可以解决IE8以上、chorme、firefox、opera下的同向重叠问题)

     

    38:position的值,relative\absolute\fixed分别相对于进行谁定位,有什么区别,什么时候用?

    39.解释下CSS sprites,以及你要如何在页面或网站中使用它。

    CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置

     

    40.什么是闭包,如何使用它,为什么要使用它?

    包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    使用闭包的注意点:

    · 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    · 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

     

    41.请解释JSONP的工作原理,以及它为什么不是真正的AJAX。

    JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。

    AJAX是不跨域的,而JSONP是一个是跨域的,还有就是二者接收参数形式不一样!

    42.请解释一下JavaScript的同源策略。

    在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议, 相同的端口,相同的host,那么我们就可以认为它们是相同的域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

    43.怎样添加、移除、移动、复制、创建和查找节点?

     1)创建新节点

    createDocumentFragment() //创建一个DOM片段
    createElement() //创建一个具体的元素
    createTextNode() //创建一个文本节点

    2)添加、移除、替换、插入
    appendChild() //添加
    removeChild() //移除
    replaceChild() //替换
    insertBefore() //插入

    3)查找
    getElementsByTagName() //通过标签名称
    getElementsByName() //通过元素的Name属性的值
    getElementById() //通过元素Id,唯一性

    44.谈谈垃圾回收机制方式及内存管理

    回收机制方式

    1、定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。

    2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

    3、实例如下:

    function fn1() {

        var obj = {name: 'hanzichi', age: 10};

    }

    function fn2() {

        var obj = {name:'hanzichi', age: 10};

       return obj;

    }var a = fn1();var b = fn2();

    fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

     4、垃圾回收策略:标记清除(较为常用)和引用计数。

    标记清除:

      定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。

      到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

    引用计数:

      定义和用法:引用计数是跟踪记录每个值被引用的次数。

      基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

    45、jQuery的事件委托方法bind 、live、delegate、on之间有什么区别?

    (1)、bind 【jQuery 1.3之前】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:bind(type,[data],function(eventObject));

    特点:

    (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

    (2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

    实例如下:$( "#members li a" ).bind( "click", function( e ) {} );

    (2)、live 【jQuery 1.3之后】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:live(type, [data], fn);

    特点:

    (1)、live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

    (2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

    (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 

    实例如下:$( document ).on( "click", "#members li a", function( e ) {} );

    (3)、delegate 【jQuery 1.4.2中引入】

    定义和用法:将监听事件绑定在就近的父级元素上

    语法:delegate(selector,type,[data],fn)

    特点:

    (1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

    (2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

    实例如下:

    $("#info_table").delegate("td","click",function(){/*显示更多信息*/});

    $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});

    (4)、on 【1.7版本整合了之前的三种方式的新事件绑定机制】

    定义和用法:将监听事件绑定到指定元素上。

    语法:on(type,[selector],[data],fn)

    实例如下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

     总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

    46、px和em的区别

    相同点:px和em都是长度单位;

    异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
    浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

    47、浏览器的内核分别是什么?

    IE: trident内核

    Firefox:gecko内核

    Safari:webkit内核

    Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核

    Chrome:Blink(基于webkit,Google与Opera Software共同开发)

    48、什么叫优雅降级和渐进增强?

    渐进增强 progressive enhancement:
    针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

    优雅降级 graceful degradation:
    一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

    区别:

    a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

    b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

    c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

    49、sessionStorage 、localStorage 和 cookie 之间的区别

     共同点:用于浏览器端存储的缓存数据

    不同点:

    (1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

            web storage,会将数据保存到本地,不会造成宽带浪费;

    (2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

    (3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

            sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

    (4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

    50、浏览器是如何渲染页面的?

    渲染的流程如下:

    1.解析HTML文件,创建DOM树。

       自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。

    2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;

    3.将CSS与DOM合并,构建渲染树(Render Tree)

    4.布局和绘制,重绘(repaint)和重排(reflow)

    51:js的基本数据类型

    JavaScript中有五种基本数据类型,它们分别是:undefined,null,boolean,number,string。

    还有一种复杂数据类型-object。 

    52:事件委托

    事件委托就是利用的DOM事件的事件捕获阶段。把具体dom上发生的事件,委托给更大范围的dom去处理。好比送信员,如果每次都把信件送给每一户,非常繁琐。但是如果交给一个大范围的管理者,比如小区的传达室,那么事情会变得非常简单。事件委托就类似这种原理,我页面中有很多按钮,如果不使用事件委托,我只能在每个按钮上注册事件。非常麻烦。但如果我把事件注册在一个大范围的div(假设所有的按钮都在这个div中),那么我只要注册一次事件,就可以处理所有按钮(只要按钮包含在上述div中)事件的响应了

    53:CSS3新增了很多的属性,下面一起来分析一下新增的一些属性:

    1.CSS3边框:

    · border-radius:CSS3圆角边框。在 CSS2 中添加圆角矩形需要技巧,我们必须为每个圆角使用不同的图片,在 CSS3 中,创建圆角是非常容易的,在 CSS3 中,border-radius 属性用于创建圆角。border:2px solid;

    · box-shadow:CSS3边框阴影。在 CSS3 中,box-shadow 用于向方框添加阴影。box-shadow:10px 10px 5px #888888;

    · border-image:CSS3边框图片。通过 CSS3 的 border-image 属性,您可以使用图片来创建边框。border-image:url(border.png) 30 30 round;

    2.CSS3背景:

    · background-size: 属性规定背景图片的尺寸。在 CSS3 之前,背景图片的尺寸是由图片的实际尺寸决定的。在 CSS3 中,可以规定背景图片的尺寸,这就允许我们在不同的环境中重复使用背景图片。您能够以像素或百分比规定尺寸。如果以百分比规定尺寸,那么尺寸相对于父元素的宽度和高度。

    · background-origin :属性规定背景图片的定位区域。背景图片可以放置于 content-box、padding-box 或 border-box 区域。

    3.CSS3文字效果:

    · text-shadow:在 CSS3 中,text-shadow 可向文本应用阴影。text-shadow:5px 5px 5px #FFFFFF;

    · word-wrap :单词太长的话就可能无法超出某个区域,允许对长单词进行拆分,并换行到下一行:p{word-wrap:break-word;}

    4.CSS3 2D转换:

    transform:通过 CSS3 转换,我们能够对元素进行移动、缩放、转动、拉长或拉伸。

    · translate():元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数:transform:translate(50px,100px);值 translate(50px,100px) 把元素从左侧移动 50 像素,从顶端移动 100 像素。

    · rotate():元素顺时针旋转给定的角度。允许负值,元素将逆时针旋转。transform:rotate(30deg);值 rotate(30deg) 把元素顺时针旋转 30 度。

    · scale():元素的尺寸会增加或减少,根据给定的宽度(X 轴)和高度(Y 轴)参数:transform:scale(2,4);值 scale(2,4) 把宽度转换为原始尺寸的 2 倍,把高度转换为原始高x() 5.CSS3 3D转换:

    · rotateX():元素围绕其 X 轴以给定的度数进行旋转。transform:rotateX(120deg);

    · rotateY():元素围绕其 Y 轴以给定的度数进行旋转。transform:rotateY(120deg);

    6.CSS3 过渡:当元素从一种样式变换为另一种样式时为元素添加效果。

    7.CSS3动画:通过 CSS3,我们能够创建动画,这可以在许多网页中取代动画图片、Flash 动画以及 JavaScript。

    8.CSS3多列:

    · column-count:属性规定元素应该被分隔的列数。

    · column-gap:属性规定列之间的间隔。

    · column-rule :属性设置列之间的宽度、样式和颜色规则。

    9.CSS3用户界面:

    · resize:属性规定是否可由用户调整元素尺寸。

    · box-sizing:属性允许您以确切的方式定义适应某个区域的具体内容。

    · outline-offset :属性对轮廓进行偏移,并在超出边框边缘的位置绘制轮廓。

    54:从输入url到显示页面,都经历了什么

    第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。

    第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。

    第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址。
    第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
    第五步:重复第四步,直到找到正确的纪录

    2种解释:

    一般会经历以下几个过程:

    1、首先,在浏览器地址栏中输入url

    2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

    3、在发送http请求前,需要域名解析(DNS解析)(DNS(域名系统,Domain Name System)是互联网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住IP地址。),解析获取相应的IP地址。

    4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手(TCP即传输控制协议。TCP连接是互联网连接协议集的一种。)

    5、握手成功后,浏览器向服务器发送http请求,请求数据包

    6、服务器处理收到的请求,将数据返回至浏览器

    7、浏览器收到HTTP响应

    8、读取页面内容,浏览器渲染,解析html源码

    9、生成Dom树、解析css样式、js交互

    10、客户端和服务器交互

    11、ajax查询

    55:对<meta></meta>标签有什么理解

    什么是meta标签?

    引自下W3school的定义说明一下。

    元数据(metadata)是关于数据的信息。

    标签提供关于 HTML 文档的元数据。元数据不会显示在页面上,但是对于机器是可读的。

    典型的情况是,meta 元素被用于规定页面的描述、关键词、文档的作者、最后修改时间以及其他元数据。

    标签始终位于 head 元素中。

    元数据可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。

    其实对上面的概念简单总结下就是:<meta> 标签提供关于 HTML 文档的元数据。它不会显示在页面上,但是对于机器是可读的。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。

    meta的作用

    meta里的数据是供机器解读的,告诉机器该如何解析这个页面,还有一个用途是可以添加服务器发送到浏览器的http头部内容

    56:new操作符到底到了什么

    先看代码

    [javascript] view plain copy

    1. var Func=function(){  

    2. };  

    3. var func=new Func ();  

    new共经过了4几个阶段

    1、创建一个空对象

    [javascript] view plain copy

    1. varobj=new Object();  

    2、设置原型链

    [javascript] view plain copy

    1. obj.__proto__= Func.prototype;  

    3、让Func中的this指向obj,并执行Func的函数体。

    [javascript] view plain copy

    1. var result =Func.call(obj);  

    4、判断Func的返回值类型:

    如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。

    [javascript] view plain copy

    1. if (typeof(result) == "object"){  

    2.   func=result;  

    3. }  

    4. else{  

    5.     func=obj;;  

    6. }  

    57:h5新特性

    HTML5新特性 —— 新特性
    (1)新的语义标签和属性
    (2)表单新特性
    (3)视频和音频
    (4)Canvas绘图
    (5)SVG绘图
    (6)地理定位
    (7)拖放API
    58:vue的生命周期

     

     

    58:请写出你对闭包的理解,并列出简单的理解

    使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

    闭包有三个特性:

    1.函数嵌套函数 

    2.函数内部可以引用外部的参数和变量 

    3.参数和变量不会被垃圾回收机制回收

     

    59:display none visibility hidden区别?

    1.display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;

    2.使用visibility:hidden比display:none性能上要好,display:none切换显示时visibility,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),而visibility切换是否显示时则不会引起回流。

    60:JavaScript中如何检测一个变量是一个String类型?请写出函数实现

    typeof(obj) === "string"

    typeof obj === "string"

    obj.constructor === String

    61:如何理解闭包?

    1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。

    2、表现形式:使函数外部能够调用函数内部定义的变量。

    3、实例如下:

    (1)、根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,没有就返回undefined。这里明显count 是函数内部的flag2 的那个count 。

    var count=10;   //全局作用域 标记为flag1function add(){

        var count=0;    //函数全局作用域 标记为flag2

        return function(){

            count+=1;   //函数的内部作用域        alert(count);

        }

    }var s = add()

    s();//输出1

    s();//输出2

    4、变量的作用域

    要理解闭包,首先必须理解Javascript特殊的变量作用域。

    变量的作用域分类:全局变量和局部变量。

    特点:

    1、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。

    2、函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

     5、使用闭包的注意点

    1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    62:谈谈垃圾回收机制方式及内存管理

    回收机制方式

    1、定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。

    2、原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

    3、实例如下:

    function fn1() {

        var obj = {name: 'hanzichi', age: 10};

    }

    function fn2() {

        var obj = {name:'hanzichi', age: 10};

       return obj;

    }var a = fn1();var b = fn2();

    fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

     4、垃圾回收策略:标记清除(较为常用)和引用计数。

    标记清除:

      定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。

      到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

    引用计数:

      定义和用法:引用计数是跟踪记录每个值被引用的次数。

      基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

    63:判断一个字符串中出现次数最多的字符,统计这个次数

    var str = 'asdfssaaasasasasaa';

    var json = {};

    for (var i = 0; i < str.length; i++) {

        if(!json[str.charAt(i)]){

           json[str.charAt(i)] = 1;

        }else{

           json[str.charAt(i)]++;

        }

    };var iMax = 0;var iIndex = '';for(var i in json){

        if(json[i]>iMax){

             iMax = json[i];

             iIndex = i;

        }

    }        console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次');

    64、$(document).ready()方法和window.onload有什么区别?

     (1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。

     (2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。

    65、 jquery中$.get()提交和$.post()提交有区别吗?

    相同点:都是异步请求的方式来获取服务端的数据;

    异同点:

    1、请求方式不同:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。

    2、参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。

    3、数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多

    4、安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。

    66、jQuery的事件委托方法bind 、live、delegate、on之间有什么区别?(常见)

    (1)、bind 【jQuery 1.3之前】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:bind(type,[data],function(eventObject));

    特点:

    (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

    (2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

    实例如下:$( "#members li a" ).bind( "click", function( e ) {} );

    (2)、live 【jQuery 1.3之后】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:live(type, [data], fn);

    特点:

    (1)、live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

    (2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

    (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 

    实例如下:$( document ).on( "click", "#members li a", function( e ) {} );

    (3)、delegate 【jQuery 1.4.2中引入】

    定义和用法:将监听事件绑定在就近的父级元素上

    语法:delegate(selector,type,[data],fn)

    特点:

    (1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

    (2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

    实例如下:

    $("#info_table").delegate("td","click",function(){/*显示更多信息*/});

    $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});

    (4)、on 【1.7版本整合了之前的三种方式的新事件绑定机制】

    定义和用法:将监听事件绑定到指定元素上。

    语法:on(type,[selector],[data],fn)

    实例如下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

     总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

    67、px和em的区别(常见)

     

    相同点:px和em都是长度单位;

    异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
    浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

    68、浏览器的内核分别是什么?

    IE: trident内核

    Firefox:gecko内核

    Safari:webkit内核

    Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核

    Chrome:Blink(基于webkit,Google与Opera Software共同开发)

    69、什么叫优雅降级和渐进增强?(常见)

    渐进增强 progressive enhancement:
    针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

    优雅降级 graceful degradation:
    一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

    区别:

    a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

    b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

    c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

    70、sessionStorage 、localStorage 和 cookie 之间的区别(常见)

     共同点:用于浏览器端存储的缓存数据

    不同点:

    (1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

            web storage,会将数据保存到本地,不会造成宽带浪费;

    (2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

    (3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

            sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

    (4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

     

    展开全文
  • matlab人脸识别论文

    万次阅读 多人点赞 2019-10-11 17:41:51
    这些研究受到军方、警方及大公司的高度重视资助,国内的一些知名院校也开始从事人脸识别的研究。 人脸识别是当前模式识别领域的一个前沿课题,但目前人脸识别尚处于研究课题阶段,尚不是实用化领域的活跃课题。...

    摘 要

     本文设计了一种基于BP神经网络的人脸识别系统,并对其进行了性能分析。该系统首先利用离散小波变换获取包含人脸图像大部分原始信息的低频分量,对图像数据进行降维;再由PCA算法对人脸图像进行主成分特征提取,进--步降低图像数据的处理量;最后使用经过训练后的BP神经网络对待测人脸进行分类识别。详细介绍了离散小波变换PCA特征提取以及BP神经网络分类设计。通过系统仿真实验与分析发现:人脸特征的提取是该系统的关键;同时,由于人脸灰度信息的统计特征与有监督训练BP神经网络分类器,使该系统只在固定类别,并且光照均匀的人脸识别应用场景中具有较高的识别准确率。因此,很难在复杂环境中应用。
    

    关键词:人脸识别;人工神经网络;离散小波变换; PCA; BP神经网络
    Abstract
    In this paper, a face recognition system based on BP neural network is designed and its performance is analyzed. The system first uses discrete wavelet transform to obtain the low-frequency components which contain most of the original information of the face image, and then uses PCA algorithm to extract the principal component features of the face image, progressively reducing the processing capacity of the image data. Finally, the trained BP neural network is used to classify and recognize the tested face. Discrete wavelet transform PCA feature extraction and BP neural network classification design are introduced in detail. Through the system simulation experiment and analysis, it is found that the extraction of facial features is the key of the system. At the same time, because of the statistical features of gray information and the supervised training of BP neural network classifier, the system only has a high recognition accuracy in fixed categories and uniform illumination of face recognition application scenarios. Therefore, it is difficult to apply in complex environment.

    Key words: face recognition; artificial neural network; discrete wavelet transform; PCA; BP neural network
    1绪论

      人脸识别是模式识别研究的一个热点,它在身份鉴别、信用卡识别,护照的核对及监控系统等方面有着I泛的应用。人脸图像由于受光照、表情以及姿态等因索的影响,使得同一个人的脸像矩阵差异也比较大。因此,进行人脸识别时,所选取的特征必须对上述因素具备-一定的稳定性和不变性。主元分析(PCA)方法是一种有效的特征提取方法,将人脸图像表示成一一个列向量,经过PCA变换后,不仅可以有效地降低其维数,同时又能保留所需要的识别信息,这些信息对光照、表情以及姿态具有一定的不敏感性。 在获得有效的特征向量后,关键问题是设计具有良好分类能力和鲁棒性的分类器、支持向量机(SVI )模式识别方法,兼顾调练误差和泛化能力,在解决小样本、非线性及高维模式识别问题中表现出许多特有的优势。
    

    1.1人脸识别技术的细节

    一般来说,人脸识别系统包括图像提取、人脸定位、图形预处理、以及人脸识别(身份确认或者身份查找)。系统输入一般是一张或者一系列含有未确定身份的人脸图像,以及人脸数据库中的若干已知身份的人脸图像或者相应的编码,而其输出则是一系列相似度得分,表明待识别的人脸的身份。
    1.2人脸识别技术的广泛应用

    一项技术的问世和发展与人类的迫切需求是密切相关的,快速发展的社会经济和科学技术使得人类对安全(包括人身安全、隐私保护等)得认识越来越重视。人脸识别得一个重要应用就是人类的身份识别。一-般来说, 人类得身份识别方式分为三类:
    1.特征物品,包括各种证件和凭证,如身份证、驾驶证、房门钥匙、印章等;
    2.特殊知识,包括各种密码、口令和暗号等;

    3.人类生物特征,包括各种人类得生理和行为特征,如人脸、指纹、手形、掌纹、虹膜. DNA、签名、语音等。前两类识别方式属于传统的身份识别技术,其特点是方便、快捷,但致命的缺点是安全性差、易伪造、易窃取。特殊物品可能会丢失、偷盗和复制,特殊知识可以被遗忘、混淆和泄漏。相比较而言,由于生物特征使人的内在属性,具有很强的自身稳定性和个体差异性,因此生物特征是身份识别的最理想依据。基于以上相对独特的生物特征,结合计算机技术,发展了众多的基于人类生物特征的身份识别技术,如DNA识别技术、指纹识别技术、虹膜识别技术、语音识别技术和人脸识别技术等。生物识别技术在上个世纪已经有了- -定得发展,其中指纹识别技术已经趋近成熟,但人脸识别技术的研究还处于起步阶段。指纹、虹膜、掌纹等识别技术都需要被识别者的配合,有的识别技术还需要添置复杂昂贵的设备。人脸识别可以利用已有的照片或是摄像头远距离捕捉图像,无需特殊的采集设备,系统的成本低。并且自动人脸识别可以在当事人毫无觉察的情况下完成身份确认识别工作,这对反恐怖活动有非常重要的意义。基于人脸识别技术具有如此多的优势,因此它的应用前最非常广阔,已成为最具潜力的生物特征识别技术之一
    1.3人脸识别技术的难点

      虽然人类可以毫不困难地根据人脸来辨别一个人,但是利用计算机进行完全自动的人脸识别仍然有许多困难。人脸模式差异性使得人脸识别成为-个非常困难的问题,表现在以下方面:
    
      1.人脸表情复杂,人脸具有多样的变化能力,人的脸上分布着Ii十多块面部肌肉,这些肌肉的运动导致不同面部表情的出现,会造成人脸特征的显著改变。
    
      2.随着年龄而改变,随着年龄的增长,皱纹的出现和面部肌肉的松驰使得人脸的结构和纹理都将发生改变。
    
      3.人脸有易变化的附加物,例如改变发型,留胡须,戴帽子或眼镜等饰物。4.人脸特征遮掩,人脸全部、部分遮掩将会造成错误识别。
    
      5.人脸图像的畸变,由于光照、视角、摄取角度不同,可能造成图像的灰度。
    

    1.4国内外研究状况

    人脸识别是人类视觉最杰出的能力之-。 它的研究涉及模式识别、图像处理、生物学、心理学、认知科学,与基于其它生物特征的身份鉴别方法以及计算机人机感知交互领域都有密切联系。人脸识别早在六七十年代就引起了研究者的强烈兴趣。20世纪60年代,Bledsoe 提出了人脸识别的半自动系统模式与特征提取方法。70年代,美、英等发达国家开始重视人脸识别的研究工作并取得进展。1972 年,Harmon 用交互人脸识别方法在理论上与实践上进行了详细的论述。同年,Sakai 设计了人脸图像自动识别系统。80年代初
    T. Minami 研究出了优于Sakai的人脸图像自动识别系统。但早期的人脸识别一般都需要人的某些先验知识,无法摆脱人的干预。进入九十年代,由于各方面对人脸识别系统的迫切需求,人臉识别的研究变的非常热门。人脸识别的方法有了重大突破,进入了真正的机器自动识别阶段,如Kartbunen-Loeve变换等或新的神经网络技术。人脸识别研究

    得到了前所未有的重视,国际上发表有关人脸识别等方面的论文数量大幅度增加,仅从1990年到2000年之间,sCl 及EI可检索到的相关文献多达数千篇,这期间关于人脸识别的综述也屡屡可见。国外有许多学校在研究人脸识别技术,研究涉及的领域很广。这些研究受到军方、警方及大公司的高度重视和资助,国内的一些知名院校也开始从事人脸识别的研究。

      人脸识别是当前模式识别领域的一个前沿课题,但目前人脸识别尚处于研究课题阶段,尚不是实用化领域的活跃课题。虽然人类可以毫不困难地由人脸辨别一个人,但利用计算机进行完全自动的人脸识别存在许多困难,其表现在:人脸是非刚体,存在表情变化:人脸随年龄增长面变化:发型、眼镜等装饰对人脸造成遮挡:人脸所成图像受光照、成像角度、成像距离等影响。人脸识别的困难还在于图像包括大量的数据,输入的像素可能成百上千,每个像素都含有各自不同的灰度级,由此带来的计算的复杂度将会增加。现有的识别方法中,通过从人脸图像中提取出特征信息,来对数据库进行检索的方法速度快,而利用拓扑属性图匹配来确定匹配度的方法则相对较快。
    

    1.5人脸识别的研究内容

    人脸识别技术(AFR)就是利用计算机技术,根据数据库的人脸图像,分析提取出有效的识别信息,用来“辨认”身份的技术。人脸识别技术的研究始于六十年代末七十年代初,其研究领城涉及图像处理、计算机视觉、模式识别、计算机智能等领城,是伴随着现代化计算机技术、数据库技术发展起来的综合交叉学科。
    1.5.1人脸识别研究内容

      人脸识别的研究范围广义上来讲大致包括以下hi个方面的内容。
    
      1.人脸定位和检测(Face Detection) :即从动态的场景与复杂的背景中检测出人臉的存在并且确定其位置,最后分离出来。这一任务主要受到光照、噪声、面部倾斜以及各种各样遮挡的影响。
    
      2.人脸表征(Face Representation) (也称人脸特征提取) :即采用某种表示方法来表示检测出人脸与数据库中的已知人脸。通常的表示方法包括几何特征(如欧氏距离、曲率、角度)、代数特征(如矩阵特征向量)、固定特征模板等。
    
      3.人脸识别(Face Recogni tion) :即将待识别的人脸与数据库中已知人脸比较,得出相关信息。这一过程的核心是选择适当的人脸表征方法与匹配策略。
    
      4.表情姿态分析(Expression/Gesture Analysis) :即对待识别人脸的表情或姿态信息进行分析,并对其加以归类。
    
    
      5.生理分类(Physical Classi fication) :即对待识别人脸的生理特征进行分析,得出其年龄、性别等相关信息,或者从几幅相关的图像推导出希望得到的人脸图像,如从父母图像推导出孩子脸部图像和基于年龄增长的人脸图像估算等。
    
      人臉识别的研究内容,从生物特征技术的应用前景来分类,包括以下两个方面:人脸验证与人脸识别。
    
      1.人脸验证((Face Veri ficat ion/Authenticat ion):即是回答“是不是某人?"的问题.它是给定一幅待识别人脸图像,判断它是否是某人的问题,属于一对一的两类模式分类问题,主要用于安全系统的身份验证。
    
      2.人脸识别(Face 。Recognition) :即是回答“是谁”的问题。它是给定-幅待识别人脸图像,再已有的人脸数据库中,判断它的身份的问题。它是个“-对多”的多类模式分类问题,通常所说的人脸识别即指此类问题,这也是本文的主要研究内容。
    

    1.5.2人脸识别系统的组成

      在人脸识别技术发展的几十年中,研究者们提出了多种多样的人脸识别方法,但大部分的人脸识别系统主要由三部分组成:图像预处理、特征提取和人脸的分类识别。一个完整的自动人脸识别系统还包括人脸检测定位和数据库的组织等模块,如图1.1.其中人脸检测和人脸识别是整个自动人脸识别系统中非常重要的两个环节,并且相对独立。下面分别介绍这两个环节。
    

    人脸检测与定位,检测图像中是否由人脸,若有,将其从背景中分割出来,并确定其在图
    像中的位置。在某些可以控制拍摄条件的场合,如警察拍罪犯照片时将人脸限定在标尺内,此时人脸的定位很简单。证件照背景简单,定位比较容易。在另一些情况下,人脸在图像
    中的位置预先是未知的,比如在复杂背景下拍摄的照片,这时人脸的检测与定位将受以下因素的影响: :

      1.人脸在图像中的位置、角度、不固定尺寸以及光照的影响:
    
      2.发型、眼睛、胡须以及人脸的表情变化等,3.图像中的噪声等。
    
      特征提取与人脸识别,特征提取之前一般都要敌几何归一化和灰度归一化的工作。前者指根据人脸定位结果将图像中的人脸变化到同一位置和大小:后者是指对图像进行光照补偿等处理,以克服光照变化的影响,光照补偿能够一定程度的克服光照变化的影响而提高识别率。提取出待识别的人脸特征之后,即进行特征匹配。这个过程是一对多或者一对一的匹配过程,前者是确定输入图像为图象库中的哪一个人(即人脸识别),后者是验证输入图像的人的身份是否属实(人脸验证).  
    

    以上两个环节的独立性很强。在许多特定场合下人脸的检测与定位相对比较容易,因此“特征提取与人脸识别环节”得到了更广泛和深入的研究。近几年随着人们越来越关心各种复杂的情形下的人臉自动识别系统以及多功能感知研究的兴起,人脸检测与定位才作为一个独立的模式识别问题得到了较多的重视。本文主要研究人脸的特征提取与分类识别的问题。

    2基于bp神经网络的人脸识别算法

      虽然人脸识别方法的分类标准可能有所不同,但是8前的研究主要有两个方向,一类是从人脸图像整体(Holistic Approaches)出发,基于图像的总体信息进行分类识别,他重点考虑了模式的整体属性,其中较为著名的方法有:人工神经网络的方法、统计模式的方法等。另一类是基于提取人脸图像的几何特征参数(Feature-Based Approaches), 例如眼、嘴和鼻子的特征,再按照某种距离准则进行分类识别。这种方法非常有效,因为人脸不是刚体,有着复杂的表情,对其严格进行特征匹配会出现困难。面分别介绍- -些常 用的方法,前两种方法属于从图像的整体方面进行研究,后三种方法主要从提取图像的局部特征讲行研究。
    
    
      2.1基于特征脸的方法
    

    特征脸方法(cigenface)是从生元分析方法PCA c Principal ComponentAnalysis 导出的一种人脸分析识别方法,它根据一-组人脸图像构造主元子空间,由于主元具有人脸的形状也称作特征脸。识别时将测试图像投影到主元子空间上得到了-组投影系数,然后和各个已知人的人脸图像进行比较识别,取得了很好的识别效果。在此基础上出现了很多特征脸的改进算法。

      特征脸方法原理简单、易于实现,它把人脸作为一个整体来处理,大大降低了识别复杂度。但是特征脸方法忽视了人脸的个性差异,存在着一定的理论缺陷。研究表明:特征脸方法随光线角度及人脸尺寸的影响,识别率会有所下降。
    

    2.2基于bp神经网络的方法

    一、实验要求采用三层前馈BP神经网络实现标准人脸YALE数据库的识别,编程语言为C系列语言。
    二、BP神经网络的结构和学习算法实验中建议采用如下最简单的三层BP神经网络,输入层为,有n个神经元节点,输出层具有m个神经元,网络输出为,隐含层具有k个神经元,采用BP学习算法训练神经网络。BP神经网络的结构BP网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间的精确的数学表达式,只要用已知的模式对BP网络加以训练,网络就具有输入输出对之间的映射能力。BP网络执行的是有教师训练,其样本集是由形如(输入向量,期望输出向量)的向量对构成的。在开始训练前,所有的权值和阈值都应该用一些不同的小随机数进行初始化。BP算法主要包括两个阶段:

    2.2.1向前传播阶段

    ①从样本集中取一个样本(Xp,Yp),将Xp输入网络,其中Xp为输入向量,Yp为期望输出向量。
    ②计算相应的实际输出Op。在此阶段,信息从输入层经过逐级的变换,传送到输出层。这个过程也是网络在完成训练后正常运行时执行的过程。在此过程中,网络执行的是下列运算:

    (2) 向后传播阶段
    ①计算实际输出Op与相应的理想输出Yp的差;
    ②按极小化误差的方法调整权矩阵。这两个阶段的工作一般应受到精度要求的控制

    (1)作为网络关于第p个样本的误差测度(误差函数)。

    (2)如前所述,之所以将此阶段称为向后传播阶段,是对应于输入信号的正常传播而言的,也称之为误差传播阶段。为了更清楚地说明本文所使用的BP网络的训练过程,首先假设输入层、中间层和输出层的单元数分别是N、L和M。X=(x0,x1,…,xN-1)是加到网络的输入矢量,H=(h0,h1,…,hL-1)是中间层输出矢量,Y=(y0,y1,…,yM-1)是网络的实际输出矢量,并且用D=(d0,d1,…,dM-1)来表示训练组中各模式的目标输出矢量。输出单元i到隐单元j的权值是Vij,而隐单元j到输出单元k的权值是Wjk。另外用θk和Φj来分别表示输出单元和隐单元的阈值。于是,中间层各单元的输出为:

    (3)而输出层各单元的输出是:

    其中f(*)是激励函数,采用S型函数:

    2.2.2在上述条件下,网络的训练过程如下:

    (1) 选定训练集。由相应的训练策略选择样本图像作为训练集。
    (2) 初始化各权值Vij,Wjk和阈值Φj,θk,将其设置为接近于0的随机值,并初始化精度控制参数ε和学习率α。
    (3) 从训练集中取一个输入向量X加到网络,并给定它的目标输出向量D。
    (4) 利用式(3)计算出一个中间层输出H,再用式(4)计算出网络的实际输出Y。
    (5) 将输出矢量中的元素yk与目标矢量中的元素dk进行比较,计算出M个输出

    误差项:

    对中间层的隐单元也计算出L个误差项:

    (6) 依次计算出各权值和阈值的调整量:

    (8) 当k每经历1至M后,判断指标是否满足精度要求:E≤ε,其中E是总误差函数。

    如果不满足,就返回(3),继续迭代。如果满足,就进入下一步。
    (9) 训练结束,将权值和阈值保存在文件中。这时可以认为各个权值已经达到稳定,分类器形成。再一次进行训练时,直接从文件导出权值和阈值进行训练,不需要进行初始化。

    YALE数据库是由耶鲁大学计算视觉与扼制中心创立,包括15位志愿者,每个人有11张不同姿势、光照和表情的图片,共计165张图片,图片均为80*100像素的BMP格式图像。我们将整个数据库分为两个部分,每个人的前5幅图片作为网络的训练使用,后6副图片作为测试使用。测试样例:

    输入输出:

      神经网络在人脸识别应用中有很长的历史。早期用于人脸识别的神经网络主要是Kohonen自联想映射神经网络,用于人脸的“回忆”。所谓“回忆”是指当输入图像上的人脸受噪声污染严重或部分缺损时,能用Kohonen网络恢复出原来完整的人脸。Intrator 等人用一个无监督/监督混合神经网络进行人脸识别。其输入是原始图像的梯度图像,以此可以去除光照的变化。监督学习目的是寻找类的特征,有监督学习的目的是减少训练样本被错分的比例。这种网络提取的特征明显,识别率高,如果用几个网络同时运算,求其平均,识别效果还会提高。
    
      与其他类型的方法相比,神经网络方法在人脸识别上有其独到的优势,它避免了复:杂的特征提取工作,可以通过学习的过程获得其他方法难以实现的关于人脸识别的规律和规则的隐性表达。此外,神经网络以时示方式处理信息,如果能用硬件实现,就能显著提高速度。神经网络方法除了用于人脸识别外,还适用于性别识别、种族识别等。
    

    2.3弹性图匹配法

    弹性图匹配方法是-种基于动态链接结构DLA C Dynamic Link Architecture的方法。它将人脸用格状的稀疏图表示,图中的节点用图像位置的Gabor小波分解得到的特征向量标记,图的边用连接节点的距离向量标记。匹配时,首先J找与输入图像最相似的模型图,再对图中的每个节点位置进行最佳匹配,这样产生-一个变形图,其节点逼近模型图的对应点的位置。弹性图匹配方法对光照、位移、旋转及尺度变化都敏感。此方法的主要缺点是对每个存储的人臉需计算其模型图,计算量大,存储量大。为此,Wiskott 在原有方法的基础上提出聚東图匹配,部分克服了这些缺点。在聚束图中,所有节点都已经定位在相应目标上。对于大量数据库,这样可以大大减少识别时间。另外,利用聚束图还能够匹配小同人的最相似特征,因此可以获得关于未知人的性别、胡须和眼镜等相关信息。
    2.4基于模板匹配的方法
    模板匹配法是一-种经典的模式识别方法,这种方法大多是用归一一化和互相关,直接计算两副图像之间的匹配程度。由于这种方法要求两副图像上的目标要有相同的尺度、取向和光照条件,所以预处理要做尺度归一化和灰度归一化的工作。最简单的人脸模板是将人脸看成-一个椭圆,检测人臉也就是检测图像中的椭圆。另一种方法是将人脸用一-组独立的小模板表示,如眼睛模板、嘴巴模板、鼻子模板、眉毛模板和下巴模板等。但这些模板的获得必须利用各个特征的轮廓,而传统的基于边缘提取的方法很难获得较高的连续边缘。即使获得了可靠度高的边缘,也很难从中自动提取所需的特征量。模板匹配方法在尺度、光照、旋转角度等各种条件稳定的状态下,它的识别的效果优于其它方法,但它对光照、旋转和表情变化比较敏感,影响了它的直接使用。2.5基于人脸特征的方法人脸由眼睛、鼻子、嘴巴、下巴等部件构成,正因为这些部件的形状、大小和结构上的各种差异才使得世界上每个人脸千差万别,因此对这些部件的形状和结构关系的几何描述,可以作为人脸识别的重要特征。几何特征最早是用于人脸检测轮廓的描述与识别,首先根据检测轮廓曲线确定若干显著点,并由这些显著点导出- -组用于识别的特征度量如距离、角度等。采用儿何特征进行正面人脸识别一般是通过提取人眼、口、鼻等重要特征点的位置和眼睛等重要器官的几何形状作为分类特征。
    定位眼睛往往是提取人脸几何特征的第-步。由于眼睛的对称性以及眼珠呈现为低灰度值的圆形,因此在人脸图像清晰瑞正的时候,眼睛的提取是比较容易的。但是如果人脸图像模糊,或者噪声很多,则往往需要利用更多的信息(如眼睛和眉毛、鼻子的相对位置等),而且.这将使得眼睛的定位变得很复杂。而且实际图像中,部件未必轮廓分明,有时人用眼看也只是个大概,计算机提取就更成问题,因而导致描述同-一个人的不同人脸时,其模型参数可能相差很大,面失去识别意义。尽管如此,在正确提取部件以及表情变化微小的前提下,该方法依然奏效,因此在许多方面仍可应用,如对标准身份证照片的应用。

    2.5九个人脸库介绍

    1. FERET人脸数据库
      http://www.nist.gov/itl/iad/ig/colorferet.cfm
      由FERET项目创建,此图像集包含大量的人脸图像,并且每幅图中均只有一个人脸。该集中,同一个人的照片有不同表情、光照、姿态和年龄的变化。包含1万多张多姿态和光照的人脸图像,是人脸识别领域应用最广泛的人脸数据库之一。其中的多数人是西方人,每个人所包含的人脸图像的变化比较单一。

    2. CMU Multi-PIE人脸数据库
      http://www.flintbox.com/public/project/4742/
      由美国卡耐基梅隆大学建立。所谓“PIE”就是姿态(Pose),光照(Illumination)和表情(Expression)的缩写。CMU Multi-PIE人脸数据库是在CMU-PIE人脸数据库的基础上发展起来的。包含337位志愿者的75000多张多姿态,光照和表情的面部图像。其中的姿态和光照变化图像也是在严格控制的条件下采集的,目前已经逐渐成为人脸识别领域的一个重要的测试集合。

    3. YALE人脸数据库(美国,耶鲁大学)
      http://cvc.cs.yale.edu/cvc/projects/yalefaces/yalefaces.html
      由耶鲁大学计算视觉与控制中心创建,包含15位志愿者的165张图片,包含光照、表情和姿态的变化。
      Yale人脸数据库中一个采集志愿者的10张样本,相比较ORL人脸数据库Yale库中每个对象采集的样本包含更明显的光照、表情和姿态以及遮挡变化。

    4. YALE人脸数据库B
      https://computervisiononline.com/dataset/1105138686
      包含了10个人的5850幅在9种姿态,64种光照条件下的图像。其中的姿态和光照变化的图像都是在严格控制的条件下采集的,主要用于光照和姿态问题的建模与分析。由于采集人数较少,该数据库的进一步应用受到了比较大的限制。

    5. MIT人脸数据库
      由麻省理工大学媒体实验室创建,包含16位志愿者的2592张不同姿态(每人27张照片),光照和大小的面部图像。

    6. ORL人脸数据库
      https://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
      由英国剑桥大学AT&T实验室创建,包含40人共400张面部图像,部分志愿者的图像包括了姿态,表情和面部饰物的变化。该人脸库在人脸识别研究的早期经常被人们采用,但由于变化模式较少,多数系统的识别率均可以达到90%以上,因此进一步利用的价值已经不大。
      ORL人脸数据库中一个采集对象的全部样本库中每个采集对象包含10幅经过归一化处理的灰度图像,图像尺寸均为92×112,图像背景为黑色。其中采集对象的面部表情和细节均有变化,例如笑与不笑、眼睛睁着或闭着以及戴或不戴眼镜等,不同人脸样本的姿态也有变化,其深度旋转和平面旋转可达20度。

    7. BioID人脸数据库
      https://www.bioid.com/facedb/
      包含在各种光照和复杂背景下的1521张灰度面部图像,眼睛位置已经被手工标注。

    8. UMIST图像集
      由英国曼彻斯特大学建立。包括20个人共564幅图像,每个人具有不同角度、不同姿态的多幅图像。

    9. 年龄识别数据集IMDB-WIKI
      https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/
      包含524230张从IMDB和Wikipedia爬取的名人数据图片。应用了一个新颖的化回归为分类的年龄算法。本质就是在0-100之间的101类分类后,对于得到的分数和0-100相乘,并将最终结果求和,得到最终识别的年龄

    3matlab分析人脸方法介绍
    人脸识别之一:查找图片中的人脸并用方框圈出
    这种类似于智能手机拍照时,屏幕里那个框任务头部的红框。大致步骤为:获取RGB图片—>转换为灰度图像—>图像处理—>人脸识别。代码如下:clear all
    clc

    %获取原始图片
    i=imread(‘face.jpg’);
    I=rgb2gray(i);
    BW=im2bw(I); %利用阈值值变换法将灰度图像转换成二进制图像
    figure(1);
    imshow(BW);
    %最小化背景
    [n1 n2]=size(BW);
    r=floor(n1/10);
    c=floor(n2/10);
    x1=1;x2=r;
    s=r*c;

    for i=1:10
    y1=1;y2=c;
    for j=1:10
    if(y2<=c || y2>=9c) || (x11 || x2r10)
    loc=find(BW(x1:x2,y1:y2)==0);
    [o p]=size(loc);
    pr=o*100/s;
    if pr<=100
    BW(x1:x2,y1:y2)=0;
    r1=x1;r2=x2;s1=y1;s2=y2;
    pr1=0;
    end
    imshow(BW);
    end
    y1=y1+c;
    y2=y2+c;
    end
    x1=x1+r;
    x2=x2+c;
    end
    figure(2)
    subplot(1,2,1);
    imshow(BW)
    title(‘图像处理’);
    %人脸识别
    L=bwlabel(BW,8);
    BB=regionprops(L,‘BoundingBox’);
    BB1=struct2cell(BB);
    BB2=cell2mat(BB1);

    [s1 s2]=size(BB2);
    mx=0;
    for k=3:4:s2-1
    p=BB2(1,k)*BB2(1,k+1);
    if p>mx && (BB2(1,k)/BB2(1,k+1))<1.8
    mx=p;
    j=k;
    end
    end
    subplot(1,2,2);
    title(‘人脸识别’);
    imshow(I);
    hold on;
    rectangle(‘Position’,[BB2(1,j-2),BB2(1,j-1),BB2(1,j),BB2(1,j)],‘EdgeColor’,‘r’)实验效果图:

             从实验效果图中,可以看出红框框出了人脸部分。
    

    人脸识别之二:由输入的人像识别出数据库中人像
    这种情况类似于手机人脸解锁,通过当前的人脸去和保存的人脸做比对来实现解锁等功能;从网上看了好多资料,由于个人能力有限大多都没仿真出来,最后通过学习PCA算法,了解到可通过PCA算法对输入矩阵降维,提取特征值和特征向量的方式来做人脸比对。具体的PCA的东西在这里不作介绍,主要介绍一下如何实现人脸比对。
    大致步骤:制作人脸数据样本—>PCA提取样本数据特征值—>人脸比对1.人脸样本
    从网上搜集了10张人脸图片,来制作成样本。

                         %读取转换10张图片,生成数据矩阵function ImgData = imgdata()  
    

    %导入图片
    picture1 = rgb2gray(imread(‘1.jpg’));
    picture2 = rgb2gray(imread(‘2.jpg’));
    picture3 = rgb2gray(imread(‘3.jpg’));
    picture4 = rgb2gray(imread(‘4.jpg’));
    picture5 = rgb2gray(imread(‘5.jpg’));
    picture6 = rgb2gray(imread(‘6.jpg’));
    picture7 = rgb2gray(imread(‘7.jpg’));
    picture8 = rgb2gray(imread(‘8.jpg’));
    picture9 = rgb2gray(imread(‘9.jpg’));
    picture10 = rgb2gray(imread(‘10.jpg’));
    [m,n] = size(picture1);
    picture_ten = {picture1,picture2,picture3,picture4,picture5,picture6,picture7,picture8,picture9,picture10};
    for i=1:10
    %把mn的矩阵变换成1(mn)的矩阵
    ImgData(i,:) = reshape(picture_ten{i},1,m
    n);
    end
    %数据范围缩小到0到1之间
    ImgData = double(ImgData)/255;

    PCA分析function Cell_ten = PCA(imgdata,k)
    [m,n] = size(imgdata);
    img_mean = mean(imgdata); %计算每列平均值
    img_mean_ten = repmat(img_mean,m,1); %复制m行平均值至矩阵img_mean_ten
    Z = imgdata - img_mean_ten;
    T = Z’Z;%协方差矩阵
    [V,D] = eigs(T,k); %计算T中最大的前k个特征值与特征向量
    img_new = imgdata
    V*D; %低维度下的各个人脸的数据
    Cell_ten = {img_new,V,D};3.通过输入测试人脸从数据库中找到相对应人脸function face= facefind(Cell_ten,testdata)%此函数代码借鉴于他人,还未征求其同意,这里就暂时略过这里testdata是测试图片的数据4.主程序调用img=imgdata(); %图片矩阵数据
    Cell_ten=PCA(img,2);% PCA
    face1=facefind(Cell_ten,imread(‘test.jpg’));%识别
    subplot(1,2,1)
    imshow(‘test.jpg’)
    title(‘测试图像’)
    subplot(1,2,2)
    imshow(strcat(num2str(face1),’.jpg’))
    title(‘数据库图像’)测试效果: 使用这个方式可以实现简单的人脸识别,但精确度不高;

    4 分析算法
    在人脸识别系统中有许多关键环节,其中最重要的莫过于特征提取。利用主成分分析法(PCA)进行特征提取是目前应用最多的提取方法。作为一种科学的统计方法,它在模式识别、信号处理、数字图像处理等等领域都有广泛涉猎。基于PCA中空间原始数据主要特征提取,减少数据冗余的思想,一些在低维特征空间的数据被处理,并合理保留了原始数据中有用的信息,数据空间中维数过高的问题也得以解决。
    4.1  主成分分析的基本原理

    实际上主成分分析就是一种数学降维演算方法,用若干个综合变量来代替原本更多的变量,让这些综合变量尽可能的实现对原有变量信息的取代,并保持彼此之间不存在关联。这种多变量化为少数相互无关的变量且信息量不变的统计分析方法就叫做主成分分析法。
      假设F1表示原变量的首个线性组合所组成的主要成分指标,就有F1=a11X1+a21X2+…ap1Xp。根据这个数学式可知,如果在每一个主成分中提取一个信息量,即可用方差(F1)进行度量,随着方差F1的增大,F1所包含的信息也就越多,同时它的线性组合选取也可表示为X1、X2…XP,它们都被称为方差F1中的第一主成分。如果第一主成分不足以代表原有的P个变量信息时,就可以考虑选取F2,即第二个线性组合,借由它来反映原本的有效信息。在F2中可以不显示第一主成分中已有的信息,以数学语言来表达要求的话即Cov(F1,F2)=0,其中F2为第二主成分。所以按照实际原变量的变化需求,就可以构造出多个主成分指标。
      4.2人脸识别的技术特点

    人脸识别是模式识别中的重要分支,它是指通过计算机系统来分析人脸图像,从中获取有价值的识别信息,从而辨识身份。所以说从技术特点上来看,人脸识别具有以下几个关键特色。
     1、PCA算法
    算法大致步骤:
    设有m条n维数据。
    1)将原始数据按列组成n行m列矩阵X;
    2)将X的每一行(这里是图片也就是一张图片变换到一行)进行零均值化,即减去这一行的均值(样本中心化和标准化);将所有的样本融合到一个矩阵里面特征向量就是变换空间的基向量U=[u1,u2,u3,u4,…],脑袋里面要想到一个样本投影变换就是该空间的一个点,然后对于许多点可以用KNN等不同的方法进行分类。
    3)求出协方差矩阵C=1mXXTC=1mXXT C=\frac {1 }{m } XX^TC=m1XXT;
    4)求出协方差矩阵的特征值及对应的特征向量;
    5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P;
    6)Y=PXY=PX Y=PXY=PX即为降维到kk kk维后的数据。
      对数据进行中心化预处理,这样做的目的是要增加基向量的正交性,便于高维度向低纬度的投影,即便于更好的描述数据。
      对数据标准化的目的是消除特征之间的差异性,当原始数据不同维度上的特征的尺度不一致时,需要标准化步骤对数据进行预处理,使得在训练神经网络的过程中,能够加速权重参数的收敛。
      过中心化和标准化,最后得到均值为0,标准差为1的服从标准正态分布的数据。
      求协方差矩阵的目的是为了计算各维度之间的相关性,而协方差矩阵的特征值大小就反映了变换后在特征向量方向上变换的幅度,幅度越大,说明这个方向上的元素差异也越大(越有投影的必要,矩阵相乘的过程就是投影),故而选取合适的前k个能以及小的损失来大量的减少元数据的维度。

    2、PCA原理推导
    基于K-L展开的PCA特征提取:

    5.算法优化方法
    我用了三种方法对其进行优化
    1.采用动量梯度下降算法训练 BP 网络。
    训练样本定义如下:
    输入矢量为
    p =[-1 -2 3 1
    -1 1 5 -3]
    目标矢量为 t = [-1 -1 1 1]
    2. 采用贝叶斯正则化算法提高 BP 网络的推广能力。在本例中,我们采用两种训练方法,即 L-M 优化算法(trainlm)和贝叶斯正则化算法(trainbr),用以训练 BP 网络,使其能够拟合某一附加有白噪声的正弦样本数据。其中,样本数据可以采用如下MATLAB 语句生成:
    输入矢量:P = [-1:0.05:1];
    目标矢量:randn(’seed’,78341223);
    T = sin(2piP)+0.1randn(size§);
    3. 采用“提前停止”方法提高 BP 网络的推广能力。对于和例 2相同的问题,在本例中我们将采用训练函数 traingdx 和“提前停止”相结合的方法来训练 BP 网络,以提高 BP 网络的推广能力。在利用“提前停止”方法时,首先应分别定义训练样本、验证样本或测试样本,其中,验证样本是必不可少的。在本例中,我们只定义并使用验证样本,即有
    验证样本输入矢量:val.P = [-0.975:.05:0.975]
    验证样本目标矢量:val.T = sin(2
    pival.P)+0.1randn(size(val.P))
    值得注意的是,尽管“提前停止”方法可以和任何一种 BP 网络训练函数一起使用,但是不适合同训练速度过快的算法联合使用,比如 trainlm 函数,所以本例中我们采用训练速度相对较慢的变学习速率算法 traingdx 函数作为训练函数。
    参考文献

    [1] HongZiquan.AlgbricFeatureExcaciofmftfoReonino[JPatteo Recognition. 1991. 22 (1) :43~44.
    [2] Yuille A L Detcction Templates for Face Recognitio[JCognitive Neuroscience , 1991. 191-200
    [3]卢春雨张长水局城区城特征的快速人脸检测法[D北京:清华大学学报.1999.96 (1) ;4-6.
    [4]陈刚,减飞虎实用人脸识别系统的本征脸法实现[D]2001年5月230():45-46.
    [
    5]杜平,徐大为,刘重庆,基F整体特征的人脸识别方法的研究[12003年6月49 (3) ;382-383.
    [6] Chow G, Li X. Towards A System for Automatic Facial Feature Detctio[U] 1993. 2903)2-3.
    [7]杨变若,王煎法,杨未来人脸全局特iE识别研究[Z]1997年11月3(5):; 871-875.
    [8]边肇棋,张学工阎平凡等模式识别D]北京:清华大学出版社2000 302)16-17.

    致 谢

      从毕业设计的选题到论文的指导到最后定稿,期间遇到了无数的困难和阻碍,也曾想过对自己降低要求,也曾想过放弃最初想要坚持的设计,但是最后在孙老师和同学的鼓励和陪伴下,努力克服了所有的困难,独立完成了毕业设计和论文的书写。尤其是要感射我的论文指导老师孙老师,不厌其烦的对我的设计进行指导修改,耐心的帮助我改进设计帮助我搜集相关的资料,感谢孙老师如母亲--般的关怀,在孙老师身上不仅学习到了对学术严谨的态度,更被孙老师亲切无私的个人魅力所感染。
    
      还要感谢我的同学和其他所有的老师,他们严谨的学术态度,宽容待人严于律己的处世风范都使我受益良多。
    
    展开全文
  • 软件测试面试题汇总

    万次阅读 多人点赞 2018-09-27 12:31:09
    请试着分别比较这些不同的测试类型的区别与联系(如功能测试、性能测试……)? ................................................................................................................................
  • 区块链

    千次阅读 多人点赞 2019-11-14 10:34:47
    区块链是一种密码学方式保证的不可篡改不可伪造的分布式账本。 区块链开发 1、区块链的产生 2008-01中本聪提出里区块链的概念,2009-01-03创世区块链出现,2009-01-09出现序号为1的区块链,并与创世区块连接形成...
  • 用turtle实现用正方形画圆

    千次阅读 多人点赞 2018-11-19 13:34:54
    每次都用乌龟(turtle)来画出一个正方形,然后通过旋转3°后,继续画一样的正方形,在通过120次循环后就实现了完整的圆,这里当然也可以用其他的角度和次数,只要能完成360度就可以了。 先完成的图形代码。 ...
  • 足式机器人较传统的四轮式履带式有着无与伦比的优势,其在复杂环境中具有更高的机动性,在军事任务抢险任务中能够发挥出比传统轮式更大的作用。要想让机器人更智能,首先要做到的是让机器人能够像人或动物一样...
  • 如果要给人脸识别下个定义,它是利用人的生物特征实现个体区分的一种技术,一般包括图像采集、特征定位、身份的确认查找三个环节。简单来说,人脸识别就是从图像中提取面部特征关键点,比如骨骼特征、眉毛高度等,...
  • © 野比 2012 [美]VCSKicks著,野比译 ...Adobe Photoshop有两个非常专业的用来设置如投影、斜面与浮雕等特效的控件:一个是角度选择器,另一个是角度高度选择器(如上图所示)。 本文将带领读者创建两个自定义控
  • EAST算法详解

    万次阅读 多人点赞 2018-06-18 14:54:54
    EAST:高效而准确的场景文本检测 1. 摘要 以前的场景文本检测方法已经在各种基准测试中取得了良好的效果...这是因为文本检测的整体性能取决于pipelines中多个阶段各部分的相互作用,而简单的pipeline能够集中精...
  • 树的高度,节点的深度和高度

    千次阅读 2020-07-22 14:45:36
    节点深度高度以及树的高度不同的教材可能定义不同,本文是参考的《数据结构与算法python》第八章201页的定义 1 节/结点的深度和高度 1.1 深度depth 假定p是树T中的一个节点,那么p的深度就是节点p的祖先的个数,不...
  • 物联网是新一代信息技术的高度集成综合运用,全球各国尤其是发达国家对发展物联网均加以高度重视,并积极进行战略布局,以期把握未来国际经济与科技的竞争主动权。埃森哲预计,到2024年连接设备的数量将超过400亿...
  • 同时,她所教的很多学生也都成绩优异,让同事朋友们都感到不可思议。 在一次采访中,她向记者透露了她教学与教子的秘诀:不要指望别人都你的见识一样! 接着,她向记者讲述了这样一个故事:十多年以前,她的小...
  • 基于matlab的车牌识别系统设计

    万次阅读 多人点赞 2018-06-01 16:00:14
    红、绿、蓝三个通道的缩略图,都是灰度显示的,用不同的灰度色阶来表示“ 红,绿,蓝”在图像中的比重。通道中的纯白,代表了该色光在此处为最高亮度,亮度级别是255,0表示亮度最低,255表示亮度最亮。只有三个...
  • 深度学习常见算法的介绍比较

    万次阅读 多人点赞 2018-02-08 22:00:06
    很多人都有误解,以为深度...关于深度学习的理论推导,太大太复杂,一些常见的深度学习算法本人也是模模糊糊的,过好多次的,隔断时间就会忘记,现在对其系统的整理一下(从历史,致命问题出发,再具体算法的思想,
  • 机器视觉基础知识汇总

    千次阅读 多人点赞 2018-05-11 14:10:45
    【机器视觉的优势】机器视觉系统具有高效率、高度自动化的特点,可以实现很高的分辨率精度速度。机器视觉系统与被检测对象无接触,安全可靠。人工检测与机器视觉自动检测的主要区别有: 【系统组成】一个典型的...
  • 透视相机的视野范围是一个锥体,虽然可以控制Field of View大小去调整视野范围,但会影响画面效果,所以使用调整相机的高度的方式去适配 using UnityEngine; /// <summary> /// 透视相机分辨率适配 /// <...
  • 常用的阵列信号定位算法主要有三大类:基于高分辨率谱估计的定位技术、基于可控波束形成(Beamforming)的定位技术基于TDOA的定位技术,以上三种算法在阵列信号处理中,尤其是移动通信的阵列信号处理中都...
  • python深度学习库系列教程——python调用opencv库教程

    万次阅读 多人点赞 2018-03-17 15:47:33
    全栈工程师开发手册 (作者:栾鹏) python教程全解 OpenCV安装pip install --...pip install opencv-pythonOpenCV的结构Python一样,当前的OpenCV也有两个大版本,OpenCV2OpenCV3。相比OpenCV2,OpenCV3提供了
  • 从数学的角度看高度图是一个二维数组v,例如采样点(x, y, z),则其灰度 g = z * 255 / MAX_HEIGHT,v[x][y]的颜色就为(g, g, g)。 法线贴图 法线贴图的出现,是为了低面数的模型模拟出高面数的模型的”光照...
  • osgEarth编辑器SXEarth案例:距离、面积、角度高度测量
  • 不同浏览器jsp开发兼容问题

    千次阅读 2017-06-21 10:36:52
    所谓的浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况。在大多数情况下,我们的需求是,无论用户用什么浏览器来查看我们的网站或者登陆我们的系统,都应该是统一的...
  • 该函数已知角度和半径,利用三角函数,我们算出XY值,然后在加上给定的原点初始坐标即可。 还应看到,函数代码中用到的是Y分量的负值,这是因为计算机显示器上网格是上下颠倒的(向下为正)。 第二个函数的功能...
  • 从技术角度告诉你,区块链到底有哪些特点运作机制 王思宇 • 2016-06-28 13:18 摘要: 区块链技术的核心是实现了沿时间轴记录数据与合约,并且一旦写入,就只能读取,不能修改删除。 自从今年1月20日,...
  • 本文在互联网虚拟大脑结构图的基础上,分析了互联网与物联网,云计算大数据的关系,标识出物联网,云计算,大数据传统互联网在互联网虚拟大脑结构图的位置。说明基于神经学建立的互联网虚拟大脑架构可以有效的...
  • UE4学习笔记-自动地貌地形材质之自动高度材质 一.先添加Layer Blend,添加需要的地表层的材质 二.添加材质混合节点MatLayerBlend_StanderdWithDisplacement 三.分别给到底层材质表层材质 四.制作沿z轴投射贴图...
  • 如何提升思维广度、深度、高度和远度,从而完善自己的思维体系? 如果你足够强大,你就不会把幸福押在别人身上,你会自己创造幸福或者给别人带来幸福。而变得强大的途径就是学习,就是读书,学一切东西,读任何想...
  • 太阳高度角/方位角计算公式

    万次阅读 多人点赞 2016-05-01 16:07:13
    作者经查阅相关理论教程,在此整理了下太阳高度角、方位角等的计算公式,并根据此公式做出了相关产品,通过了检验。如有错误,请各位指正。太阳高度角/方位角在线计算太阳高度角计算公式一般情况下,地理纬度ϕ\...
  • 换个角度思考大数据

    万次阅读 多人点赞 2012-07-15 21:16:05
    IDC对大数据技术的定位为:通过高速捕捉、发现/或分析,从大容量数据中获取价值的一种新的技术架构。大数据主要涉及两个不同的技术领域:一项致力于研发可以扩展至PB甚至EB级别的大数据存储平台;另一项则是大数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,073
精华内容 52,029
关键字:

以不同的角度和高度看问题