首页> 搜索结果页
"JS获取后台Cookies值的小例子" 检索
共 10 条结果
小白学Django第八天| 登录案例实战
小白学Django系列:小白学Django第一天| MVC、MVT以及Django的那些事小白学Django第二天| Django原来是这么玩的!小白学Django第三天| 一文带你快速理解模型Model小白学Django第四天| Django后台管理及配置MySQL数据库小白学Django第五天| 视图View的初步使用小白学Django第六天| 一文快速搞懂模板的使用Django实战小型图书人物信息网页(MVT的综合运用)小白学Django第七天| 模型类Model进阶学习持续更新中...前言hello,各位小伙伴。学习web知识是少不了登录小案例的,这次我将带着大家一起学习Django的登录案例,尽量把涉及的知识都讲到。这里的登录主要分为两种,一种是普通的表单登录,另一种是ajax登录。在登录案例中,我们也会设计到HTTPrequest,POST,GET等知识。普通登录其实学过web的朋友可能已经知道思路了,在前端写好form表单,然后从后端的HTTPrequest对象里拿到传过来的数据。讲具体案例之前,大家先搞懂POST,GET请求有啥区别(这里我们只说最大的区别):POST所传的信息是保存在请求头当中(适合安全性较高的数据)GET则是显示在url当中的, 简单举个例子:www.xxxxx.com/login?user=xxxx&&password=xxxxx理解完这个就好办,因为我们这里只讲post方法,get方法大家可以自己动手去试试。那我们的代码就正式开始了。1.新建login.html并写好表单<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> <head> <meta charset="UTF-8"> <title>登录界面</title> </head> <body> <form method="post" action="/login_submit/"> 账号:<input type="text" name="username"></br> 密码:<input type="password" name="password"></br> <input type="submit" value="登录"> </form> </body> </html>大家需要注意的是底下这一行代码<form method="post" action="/login_submit/">首先method参数是选用何种方式传送数据,这里显然是post方法。action所对应的就是检查表单中的数据是否正确的视图函数, 例如这里我们就是检查账号密码是否正确。这里我还得说下为什么需要两个斜线,前面那根斜线是必须得,只是后面这根...如果你不输,那你会报一下错误:RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and you have APPEND_SLASH set.解决的办法有两个: 第一种就是像我上面那样在最后一个字母后加上一根斜线,第二种方法需要在setting文件当中设置APPEND_SLASH=False。2.在views中编写相应的视图函数首先我们需要创建login.html所对应的视图函数logindef login(request): return render(request, "Book/login.html")因为这里我们只需要显示login.html,这个界面所以直接返回这个界面就行了。然后我们来创建检测账号密码是否正确的视图函数login_submitdef login_submit(request): # 使用request.POST.get来获取相关的参数 username = request.POST.get("username") password = request.POST.get("password") # 模拟判断账号密码是否正确 if"kuls" == username and"123" == password: # 如果账号密码正确,重定向至首页 return redirect("/index") else: # 如果错误重定向到登录页面 return redirect("/login")大家可能注意到获取post过来的参数,使用的是如下语句# 使用request.POST.get来获取相关的参数 username = request.POST.get("username") password = request.POST.get("password")这里需要说一下,HttpRequest对象的属性GET、POST都是QueryDict类型的对象,与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况,如果一个键同时拥有多个值将获取最后一个值,如果键不存在则返回None值,可以设置默认值进行后续处理。如果想要获取同一个键的所有值,可以通过方法getlist()获取。HTTPrequest对象的属性下面给大家补充一下相关的属性,大家可以依次去尝试。path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。在浏览器中给出地址发出请求采用get方式,如超链接。在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。encoding:一个字符串,表示提交的数据的编码方式。如果为None则表示使用浏览器的默认设置,一般为utf-8。这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。GET:QueryDict类型对象,类似于字典,包含get请求方式的所有参数。POST:QueryDict类型对象,类似于字典,包含post请求方式的所有参数。FILES:一个类似于字典的对象,包含所有的上传文件。COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串。session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见"状态保持"。ajax登录这里我先来简单介绍一下ajax是什么?Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。(来自百度百科)在我们上面的表单登录时,会发现每次提交账号密码,都会重新刷新一遍页面(如果账号密码错误),其实我们可以通过ajax来避免这种事情。在Django中ajax的运行原理跟上图差不多,从浏览器发送ajax请求至服务器,服务器进行处理并且返回一个JsonResponse对象,然后返回json数据,执行回调函数。在浏览器中使用javascript发起ajax请求时,返回json格式的数据。类JsonResponse继承自HttpResponse对象,被定义在django.http模块中,创建对象时接收字典作为参数。接下来我们就正式讲解ajax的登录:1.导入jQuery的文件,并写好html界面及ajax代码jQuery文件我推荐个网站,大家自行下载:http://www.jq22.com/jquery-info122随后导入到static中的js文件中(需要在setting配置static文件)login_ajax.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax登录</title> <script src="/static/js/jquery-3.4.1.min.js"></script> <script> $(function () { $('#ajaxbtn').click(function () { username = $('#username').val(); password = $('#password').val(); $.ajax({ url:'/login_ajax_handle/', type:'post', data:{'username':username, 'password':password}, dataType:'json', //回调函数 success:function (data) { //如果返回是1,则表示登录成功,跳转至首页 //如果返回是0,则表示登录失败 if (data.res == 0){ $('#errmsg').show().html('账号或密码错误') }else{ location.href = '/index' }}})})}) </script> <style> #errmsg{ display: none; color: red; } </style> </head> <body> <div> 账号:<input type="text" id="username"></br> 密码:<input type="password" id="password"></br> <input type="button" id="ajaxbtn" value="ajax登录"> <div id="errmsg"></div> </div> </body> </html>上述html代码中id为errmsg的div是用来提示我们账号密码错误的。2.编写视图函数视图函数login_ajax_handler:def login_ajax_handle(request): # 使用request.POST.get来获取相关的参数 username = request.POST.get("username") password = request.POST.get("password") # 模拟判断账号密码是否正确 if"kuls" == username and"123" == password: return JsonResponse({"res": 1}) else: return JsonResponse({"res": 0})3.结果密码错误提示密码正确,跳转至indexDjango系列文章:小白学Django第一天| MVC、MVT以及Django的那些事小白学Django第二天| Django原来是这么玩的!小白学Django第三天| 一文带你快速理解模型Model小白学Django第四天| Django后台管理及配置MySQL数据库小白学Django第五天| 视图View的初步使用小白学Django第六天| 一文快速搞懂模板的使用Django实战小型图书人物信息网页(MVT的综合运用)小白学Django第七天| 模型类Model进阶学习持续更新中...
文章
XML  ·  JSON  ·  前端开发  ·  JavaScript  ·  关系型数据库  ·  MySQL  ·  数据库  ·  数据安全/隐私保护  ·  数据格式  ·  Python
2022-02-18
【转】ASP.NET页面乱码问题分析
  写在前面 在Web开发中,乱码应该算一个常客了。今天还好好的一个页面,第二天过来打开一看,中文字符全变“外星文”了。有时为了解决这样的问题,需要花上很长的时间去调试,直至抓狂,笔者也曾经历过这样的时期。有时虽然是“侥幸”解决了,但对其中的原理却一知半解。 为了弄清楚这个问题,今天查了大半天的资料、测试。现把这些点滴记录下来,以激励自己重视基础,同时和大家分享一下,望大家不吝批评指正。 预备知识 先介绍一些字符编码方面的基本知识,如果你对这些已经比较了解了,请直接跳过此节。 1.       字符集与字符编码概述 简单来说,字符集就是与特定区域相关的一系列有效字符的有序集合,比如字母、数字、标点符号等。注意关键字“有序”,表明集合中的每一个字符都是具有唯一数字编号(码值)的。不同国家使用的语言文字、符号不一样,相应的字符集必定也不一样。比如中国使用汉字,美国使用英语,韩国使用韩文,等等。 字符集是为了信息交互而设计的,最终还是要转化成计算机的表示法。我们知道,计算机只认识0和1,它对字符集符号不感冒。所以,我们必须想办法把字符转化为0和1的序列。我们知道,计算机最小的存储单位是位(bit),程序中一般使用的最小单位是字节(byte)。为了把字符存储到计算机中,我们就要考虑用几个byte几个bit,考虑每一个bit上是0还是1,考虑存储和读取效率,并且必须兼顾整个字符集,这就是字符编码。 一句话,字符集只关心字符的定义,而字符编码负责字符的存储和读取细节。用三层模式来打比喻的话,字符集是模型层,而字符编码是业务层。注意:一般常说的GB2312、GBK等其实同时包含了这两方面的定义 2.       常用中文字符编码简介 GB2312 GB2312的全称是《信息交换用汉字编码字符集-基本集》,由国家标准总局于1980发布,1981年5月1日施行,中国大陆、新加坡使用此编码。基本集收录了6763个汉字,只能显示简体汉字。 GBK 1995颁布,全称是《汉字编码扩展规范》。在GB2312的其他上,增加了繁体汉字,支持ISO/IEC 10646-1 和GB-13000-1的全部中、日、韩(CJK)字符,共20902个。向下兼容GB2312。 GB18030 全称是《信息交换用汉字编码字符集基本集的扩充》,目前两个版本,分别于2000年和20005年颁布。该字符集收录了70000多个汉字,包括了藏、蒙古、维吾文等少数民族字符,是我国计算机系统必须遵循的基础性标准之一。向下兼容GBK和GB2312。 BIG5 台湾和港台地区使用的汉字编码,俗称“大五码”,共收录了13060个汉字。 UTF-8 这是目前使用最多的一种Unicode编码,是Visual Studio内置的编码,相信大家一定都不陌生。根据字符码值的不同,可能用1、2、3个字节表示。 注意,编码之间一般都不是兼容的。其它编码在此不作介绍,若想进一步了解字符编码,请看我收藏的一篇文章:http://blog.csdn.net/tomysea/article/details/6712344 3.       字符串、字符数组和字节数组 C#中的字符串(string)和字符(char)其实都是对象,他们有相应的类String和Char,string和char只是这两个类的一别名而已,内部都是采用Unicode码值表示。请注意我说的是码值,不是编码。 我们已经知道,Unicode的字符大多是多字节表示的,那么一个char就得用几个byte来表示。这里我要说的重点是,使用不同的编码表示字符串,其对应的byte可能是不一样的。请看下面的代码,注意输出字节数部分。UTF-8编码的字节数是22,而GB2312编码的字节数是16。     string title = "2012真的来了吗?";      //字符串  char[] chars = title.ToCharArray();     //字符数组  byte[] bytes = System.Text.Encoding.UTF8.GetBytes(title);  Response.Write(chars.Length + " ");     //10  (字符数)  Response.Write(bytes.Length + " ");     //22  (UTF-8编码的字节数)    bytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(title);  Response.Write(bytes.Length + " ");     //16  (GB2312编码的字节数)      从http请求响应模型说起 http是一个请求/响应的模型,这个我们大家都知道。http请求可以分为请求头和请求实体两部分,相应地http响应也可以分为响应头和响应实体。请求头或响应头是浏览器与Web服务器通信用的(假定用浏览器访问Web服务器),而实体则是实际发送的数据,比如Form表单的数据、Ajax提交的数据、传回来的html代码等。不管是浏览器还是Web服务器,在发送实体前都会把它转换为字节流。明白这一点很重要,因为涉及字节流就一定会与字符编码有关。 从上面的请求响应模型中我们可以得出一个结论:请求和响应编码必须严格保持一致!为什么呢?这很好理解,浏览器和Web服务器是要通信的,如果编码不一样的话,势必会造成许多“误解”。假设浏览器是中国人(不懂E文),而Web服务器是美国人,他们两个的“编码”(语言)不一致,悲催的结局不言而喻。 ASP.NET中请求响应编码的设置 你可以在machine.config或web.config文件指定全局配置,也可以在页面级特别指定。如果你未手动指定且machine.config中也为空,则默认会读取计算机上“区域选项”中的设置。 1.       全局配置 在machine.config或web.config文件(根目录或者子目录都有效)中的system.web节点中配置globalization节点。如果在根目录下的web.config配置,则会响应整个网站,若只是在子目录下配置,则只会响应该目录及其子目录。 详细配置如下:       <system.web>      <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8"/>  <!--按顺序是:文件编码 请求编码 响应编码-->  <!—-fileEncoding会在后面说到-->   <!--后面还有其它配置-->     2.       页面级的配置 在aspx页面的Page指令中设置响应编码       <%@ Page Language="C#" AutoEventWireup="true" ResponseEncoding="utf-8"   CodeBehind="byte.aspx.cs" Inherits="DevKit.Web.test.charset._byte" %>   在aspx页面中手动指定meta标签     <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />  在后台cs文件中配置     Request.ContentEncoding = System.Text.Encoding.UTF8;    //请求编码  Response.ContentEncoding = System.Text.Encoding.UTF8;   //响应编码   接下来,我们从几个示例中去体验乱码,从而总结出解决乱码的一般方法。 测试环境 操作系统:Windows XP Professional SP3 雨林木风版 开发环境:Visual Studio 2008 专业版 + SP1(.NET 3.5) Web容器:VS集成的Development Server 浏览器:IE8 、FireFox 5 实例分析与研究 实例1  aspx页面提示意外的字符“XXX”,引号里面是乱码 背景 网站配置了在根目录配置了文件、请求、响应编码都为utf-8,页面成功编译,没有任务错误。详细错误见下图: html代码     <div>      aspx页面中的中文      <br />后台的中文变量:<em><%=汽车%></em>  </div>  后台代码   view plain public partial class _byte : System.Web.UI.Page  {      protected string 汽车= "我是凯迪拉克"; //别怀疑,中文变量是可以的:)      protected void Page_Load(object sender, EventArgs e)      {          //...      }  }        分析与解决 既然web.config已经配置了一样的请求响应编码,而且页面级别也没设置,可以排除这方面的问题了。注意到文件编码是UTF-8,会不是会文件编码引起的呢?(提示:这里的文件编码指的是保存文件时指定的编码,点击“另存为…”,在弹出的窗口中选择“编码保存”可以看到)。果然,此aspx页面的保存编码为GB2312,与web.config文件不一样,把它修改为UTF-8。 小提示:UTF-8有两种编码:UTF-8(带签名)和UTF-8(无签名)。带签名的UTF-8会在文件的开头写入“EF BB BF”(16进制),以标示自己采用的编码格式,这个标志称为BOM(Byte Order Mark),即字节序。打个比方,UTF-8(带签名)戴了校徽的学生,就算不认识他的人,一看校徽就明白了;而UTF-8(无签名)则是没戴校徽的。这里的校徽就是我们说的BOM,一个能够表明自己身份的标志。 小结 这是因为文件的保存编码与当前网站指定的文件编码不一致引起的,所以最佳实践是:手动在web.config中指定文件编码,并确保所有页面的保存编码与web.config一致。 其实最容易出这种问题的是js和css文件,如果你用其它工具(比如DreamWeaver)来编写这些文件却采用不同的编码保存,一旦文件包含中文就可能出这样的错误,导致js脚本错误,css无效!   实例2    跨页post提交时接收的Form数据变成了乱码 背景 有两个页面,注册页面(register.html)和处理注册的页面(handle.aspx),注册页面的表单信息以post方式提交到handle.aspx。根目录的配置的文件编码、请求编码和响应编码都是UTF-8。 register.html页面的关键html     <head>      <title></title>      <meta http-equiv="Content-Type" content="text/html;charset=gb2312" />  </head>  <body>  <form id="form1" name="form1" action="handle.aspx" method="post">      <input type="text" id="txtName" name="txtName" />      <input type="submit" id="btnSubmit" value="Post" />  </form>  handle.aspx页面关键后台代码   view plain protected void Page_Load(object sender, EventArgs e)  {      string name = Request.Form["txtName"];      Response.Write(name);  }        错误信息如下 分析与解决 这是在提交表单信息过程产生的乱码,这里就涉及http请求和http响应的编码问题。我们上面说过,在请求时浏览器会把表单信息按指定编码转化成字节流发向Web服务器,在服务器ASP.NET会把这些字节流按指定的编码解码,以取得表单信息。那么我们就要检查这两个页面的编码了。仔细检查之后,发现register.html有这么一行“<meta http-equiv="Content-Type" content="text/html;charset=gb2312" />”,这里手动指定了页面编码为GB2312。问题很有可能就出在这里了,把本行删除之后,handle.aspx页面成功接收到表单信息。 没错,这就是由于两个页面的编码不一样引起。让我们再深入一点,仔细看看问题是怎么一步一步产生的吧。register.html的编码为GB2312,当我们点击了“Post”按钮时,浏览器会把“我是中文”这几个字按GB2312的方式编码成字节流,然后提到到handle.aspx页面。handle.aspx没有手动指定编码,那么他将会采用web.config里面的配置,为UTF-8。它收到请求后,用UTF-8编码解码字符流。由于请求用的是GB2312,而接收用的却是UTF-8,这样就导致乱码的产生。通过下面这幅图可以看到这个过程。 小结 所有的页面(不管是aspx,还是html,或其它)都必须使用相同的编码。如果涉及跨页提交,不管是get还是post,更应该严格保持相关页面编码的一致性。特别是跨站点提交时,更应该注意! 实例3  cookie存取发生乱码 背景 这是一个旧项目,现在决定增加一个自动登录的功能。详细过程是这样的: 在登录页面,用户登录成功后把用户名写到cookie中。这样,当用户再次访问时,就可以根据cookie判定用户是否已登录,从而实现自动登录。 登录成功后cookie是这样保存的       view plain string userName = "cookie大侠";     //待保存的用户名  userName = HttpUtility.UrlEncode(userName);     //编码特殊字符,如中文  HttpCookie cookie = new HttpCookie("userName", userName);  Response.Cookies.Add(cookie);  判断用户是否已登录时,代码是这样的   view plain string userName = Request.Cookies["userName"].Value;  userName = Server.UrlDecode(userName);  Response.Write(userName);    //总是获取不到cookie,所以决定打印出来看看   结果在测试读取cookie的时候,页面输出了乱码,如下图: 分析与解决 全球化信息是这样配置的 <globalization fileEncoding="utf-8" requestEncoding="gb2312" responseEncoding="gb2312"/> 所有页面的保存编码都为UTF-8,请求响应编码是GB2312。再次声明,这是一个旧项目,任何改动都必须向后兼容。 首先从全球化配置里看到三种编码不一致,初步怀疑是这里引发的问题。尝试把请求、响应编码都修改为UTF-8,再次运行页面,乱码消失了。窃喜,小样,原来问题就在这里。但是,这样一来,在其它很多页面中却莫名其妙出现了乱码。这…,心里好不容易生起的一股小火,却被这样无情的浇灭了。冷静地回忆了下,自己只改了请求响应编码,其它地方没动过啊。于是改回来原来的GB2312,其它页面运行也正常了。如果把编码改为UTF-8的话,就不能兼容以前的页面,且会导致一连串的问题,全部修改将是一个非常艰巨的任务。 仔细检查了几遍所有页面的编码,都没有手动设置过,那应该都是读取配置文件的GB2312。新功能急于上线,交期一秒一秒狠狠地砸着绷紧的神经。怎么办呢?难道是GB2312不支持cookie存取吗?搜索了大量资料后,也没有发现什么端倪,感觉这也不太可能,毕竟中国这么多GB2312的网站…。 现在可以确定的是编码没有任何问题!那问题会出现在哪里呢?是自己写的代码有问题吗?仔细检查了之后,就发现了一点: userName = HttpUtility.UrlEncode(userName);     //编码特殊字符,如中文 userName = Server.UrlDecode(userName);  红色部分不一样,从智能提示中可以看到这样的说明。 原来,两个调用的是不同类的方法。一个是HttpUtility的方法,另一个是HttpServerUtility的方法,不小心还真看不出来。于是把Server.UrlEncode()换成了HttpUtility.UrlEncode(),重新运行测试页面,页面正常显示。既然都已经到这里了,我们不防看看这两个方法的实现细节有哪些差异吧。打开Reflector,找到System.Web.HttpUtility中的UrlEecode方法。嘿嘿,终于被我发现了这样一个片段(我把反射后的代码加上了注释):   //这是HttpUtility的UrlEncode方法  public static string UrlEncode(string str)  {      if (str == null)      {          return null;      }      return UrlEncode(str, Encoding.UTF8);   //默认采用UTF-8编码  }  接着看看HttpServerUtility.UrlDecode()方法,Page.Server其实是HttpServerUtility的一个实例,但它并不是在Page类中实例化的,而是在HttpContext中。   view plain //HttpServerUtility中的UrlDecode方法  public string UrlDecode(string s)  {      //注意这里的差异,会优先使用context中的编码,      //也就是我们配置了的GB2312      Encoding e = (this._context != null) ?           this._context.Request.ContentEncoding : Encoding.UTF8;      return HttpUtility.UrlDecode(s, e);  }  这下总算明白为什么了,存cookie时调用的是HttpUtility.Encode()方法,将以UTF-8编码。而读取时调用的是HttpServerUtility的Decode()方法,它会根据当前上下文采用GB2312方法,自然无法正确解析UTF-8编码的字符串了。   小结   在调用方法时,要成对调用。比如编码时调用的是HttpUtility.UrlEncode(),那么在解码时你就必须调用HttpUtility.UrlDecode(),保持这种一致性,有利于减少错误的发生。   必须充分考虑代码的向后兼容性。   如果你有兴趣,去看看微软是怎么实现这些方法的吧,这样对你的帮助会很大。   实例4   jQuery Ajax请求传中文参数导致乱码   背景   老项目(实例3提到的)的需求又来了,大致要求是这样的:在前台页面中,要根据当前商品的名称去异步获取它的详细说明(当然了,一般是按id等主键获取的,这里我只是做一个假设),当用户点击时就显示。于是决定用jQuery 的Ajax去做,简单方便且功能强大。由于jQuery的易用性,代码一下子就写好了,后台采用ashx处理ajax请求,先看看是怎么实现的吧。   前台页面的代码   view plain <head runat="server">      <title>产品列表页</title>      <script src="http://www.cnblogs.com/js/jquery-1.4.2.js" type="text/javascript"></script>      <script type="text/javascript">          $(function() {              $('#product').click(function() {                  var productName = this.innerHTML;   //产品名称                  $.get('getInfo.ashx', { name: productName }, function(description) {                      alert(description); //显示详细说明                  });              });          });      </script>  </head>  <body>      <form id="form1" runat="server">      <div>          <a id="product" href="javascript:void(0);">奋斗牌牙膏</a>      </div>      </form>  </body>  ashx的关键处理代码   view plain string name = context.Request.QueryString["name"];  context.Response.Write(name + ": ");   //调试用,看参数传递是否正确  if (name != null && name.Trim() == "奋斗牌牙膏")  {      context.Response.Write("奋斗牌,你懂的!\n每天一点点,强身健体,天气再冷,牙也不颤!");  }      但不幸的是,运行页面时又出乱码了,无法正确获取产品名称。 分析与解决 项目的所有配置还是和例3一样,请求响应编码都是GB2312。首先也是尝试把web.config文件的请求编码改为UTF-8,运行页面,可以正常显示。但这样改肯定是不行的,必须考虑其它页面的兼容性。有了例3的经验,现在已经知道问题出现在哪个部分了。必定是请求的编码和解析请求的编码不一致产生的!现在的重点是找出产生这个不一致的原因。 仔细检查了产品页面的编码,没任何任何与编码相关的设置,所以这个页面肯定也是用web.config中的请求编码GB2312。在ashx中也没有设置,它肯定也是用GB2312来解析请求。理论上应该不会出现乱码的啊。 为了能看清楚细节,打开抓包工具Fiddler,监测Ajax请求,看到的请求头是这样的。 可以看到,$.get()方法自动把请求参数附加到url里,并且实施了url编码。所以我们就得$.get()这个方法入手,看看请求参数是如何被附加到url中的。打开jquery.1.4.2.js,一步一步查找,发现了这样一个方法:       function add( key, value ) {      // If value is a function, invoke it and return its value      value = jQuery.isFunction(value) ? value() : value;      s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);  )   原来是对参数调用了encodeURIComponent()方法来进行url编码的,但这个方法的实现细节是看不到的,不像.NET里可以反编译。在网上搜索了很多资料,但很少有资料提到它的工作细节。 好吧,我们就自己实践一下吧。还是用“奋斗牌牙膏”这几个字来测试,先看看用不同的字符编码来对它实行url编码后产生的字符串是什么吧。下面是我的测试结果: 把这些结果和Fiddler的抓包结果对比一下(看url中的参数),发现当采用UTF-8进行UrlEncode时,两者的结果是一致的。 可以确定encodeURIComponent()是采用UTF-8编码来进行url编码的。不仅仅是get方法,jQuery实现的所有ajax方法都是一样的,采用UTF-8字符编码对参数进行url编码。到这里,问题产生的原因已经很明朗了,请求的字节流采用了UTF-8编码,而服务器端的ASP.NET却采用GB2312来解析,肯定解析不到了。 因此,我们可以在ASP.NET中手动指明解析请求的编码。修改后的ashx代码如下:       context.Request.ContentEncoding = System.Text.Encoding.UTF8; //指明Request使用的编码是UTF-8  string name = context.Request.QueryString["name"];  context.Response.Write(name + ": ");   //调试用,看参数传递是否正确  if (name != null && name.Trim() == "奋斗牌牙膏")  {      context.Response.Write("奋斗牌,你懂的!\n每天一点点,强身健体,天气再冷,牙也不颤!");  }  再次点击页面,成功返回所需的内容。 总结 使用jQuery的ajax方法时,一定要记得它是采用UTF-8编码数据的。 把http的请求响应过程弄清楚。   通过上面4个例子,你应该对乱码产生的原因有所了解了吧。记住一点,最根本的原因是字符编码不一致产生的。然后顺着这条线索,顺藤摸瓜,一步一步把确切的原因找出来。方法很重要,你不应该为了得到了答案而高兴,而应该真正弄懂问题产生的原因,这样你才能真正成长。这时体会一下“授人以鱼不如授人以渔”这句话的魅力吧。 后记     其实问题真的不可怕,适当地来些问题,来些压力,会让你更好地成长。不要只是想得到答案,更重要的是积累获得答案的方法。 写这篇文章的过程中,遇到了不少问题,感谢那么多的前辈们分享了他们的经验,让我得以站在他们的肩膀上。   参考资料: 字符集与字符编码简介:http://www.2cto.com/kf/201110/109312.html HTTP 请求报头详解:http://www.2cto.com/kf/201110/109311.html encodeURIComponent()导致乱码解决:http://www.2cto.com/kf/201110/109310.html unicode编码 http://baike.baidu.com/view/40801.htm 转载请注明出处[http://samlin.cnblogs.com/]  作者赞赏  当当计算书籍 5-8折 刚做的招标网:八爪鱼招标网 请大家多意见 本文转自Sam Lin博客博客园博客,原文链接:http://www.cnblogs.com/samlin/archive/2011/12/22/2297513.html,如需转载请自行联系原作者
文章
Web App开发  ·  存储  ·  前端开发  ·  JavaScript  ·  .NET
2017-01-24
api日常总结:前端常用js函数和CSS常用技巧
我的移动端media html{font-size:10px} @media screen and (min-width:321px) and (max-width:375px){html{font-size:11px}} @media screen and (min-width:376px) and (max-width:414px){html{font-size:12px}} @media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}} @media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}} @media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}} @media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}} @media screen and (min-width:800px){html{font-size:25px}} forEach()与map()方法 一个数组组成最大的数: 对localStorage的封装,使用更简单 //在get时,如果是JSON格式,那么将其转换为JSON,而不是字符串。以下是基础代码: var Store = { get: function(key) { var value = localStorage.getItem(key); if (value) { try { var value_json = JSON.parse(value); if (typeof value_json === 'object') { return value_json; } else if (typeof value_json === 'number') { return value_json; } } catch(e) { return value; } } else { return false; } }, set: function(key, value) { localStorage.setItem(key, value); }, remove: function(key) { localStorage.removeItem(key); }, clear: function() { localStorage.clear(); } }; 在此基础之上,可以扩展很多方法,比如批量保存或删除一些数据: // 批量保存,data是一个字典 Store.setList = function(data) { for (var i in data) { localStorage.setItem(i, data[i]); } }; // 批量删除,list是一个数组 Store.removeList = function(list) { for (var i = 0, len = list.length; i < len; i++) { localStorage.removeItem(list[i]); } }; js判断滚动条是否到底部: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title> <script src=""></script> <style type="text/css"> * { padding: 0px; margin: 0px; } #main { width: 100%; height: 2000px; background: pink; } </style> <script type="text/javascript"> $(window).scroll(function() {   var scrollTop = $(this).scrollTop();   var docHeight = $(document).height();   var windowHeight = $(this).height(); var scrollHeight=document.body.scrollHeight; console.log("scrollTop:"+scrollTop); console.log("scrollbottom:"+(docHeight-scrollTop-windowHeight)); if(scrollTop + windowHeight == docHeight) {     alert("已经到最底部了!");   } }); </script> </head> <body> <div id="main"></div> </body> </html> js操作cookie JS设置cookie: 假设在A页面中要保存变量username的值("jack")到cookie中,key值为name,则相应的JS代码为: document.cookie="name="+username; JS读取cookie: 假设cookie中存储的内容为:name=jack;password=123 则在B页面中获取变量username的值的JS代码如下: var username=document.cookie.split(";")[0].split("=")[1]; //JS操作cookies方法! //写cookies function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } //读取cookies function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; } //删除cookies function delCookie(name) { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval=getCookie(name); if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString(); } //使用示例 setCookie("name","hayden"); alert(getCookie("name")); //如果需要设定自定义过期时间 //那么把上面的setCookie 函数换成下面两个函数就ok; //程序代码 function setCookie(name,value,time) { var strsec = getsec(time); var exp = new Date(); exp.setTime(exp.getTime() + strsec*1); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } function getsec(str) { alert(str); var str1=str.substring(1,str.length)*1; var str2=str.substring(0,1); if (str2=="s") { return str1*1000; } else if (str2=="h") { return str1*60*60*1000; } else if (str2=="d") { return str1*24*60*60*1000; } } //这是有设定过期时间的使用示例: //s20是代表20秒 //h是指小时,如12小时则是:h12 //d是天数,30天则:d30 setCookie("name","hayden","s20"); /***************************************/ function getCookie(name){ if(name){ var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return (decodeURIComponent(arr[2])); else return null; } return null; }; function setCookie(name,value,Days){ if(!Days)Days=3000; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000000); document.cookie = name + "="+ encodeURIComponent(value) + ";domain=weshare.com.cn;expires=" + exp.toGMTString() + ";path=/"; }; 获取URL参数: function GetURLlist(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r != null) return unescape(r[2]); return null; }; IOS和安卓判断: var u = navigator.userAgent, app = navigator.appVersion; var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器 var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 if(isAndroid){ $(".down0").css('display','none') }else if(isiOS){ $(".down").css('display','none') } else{ return false; } 判断微信: function isWeiXin(){ var ua = window.navigator.userAgent.toLowerCase(); if(ua.match(/MicroMessenger/i) == 'micromessenger'){ return true; }else{ return false; } } var u = navigator.userAgent; var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1|| u.indexOf('MI') > -1|| <br>u.indexOf('XiaoMi') > -1; //android终端或者uc,小米等奇葩浏览器 if(!isAndroid) {} if(isAndroid) {} 判断页面滚动方向: <script type="text/javascript"> $(function() { function scroll(fn) { var beforeScrollTop = document.body.scrollTop, fn = fn || function() {}; window.addEventListener("scroll", function() { var afterScrollTop = document.body.scrollTop, delta = afterScrollTop - beforeScrollTop; if(delta === 0) return false; fn(delta > 0 ? "down" : "up"); beforeScrollTop = afterScrollTop; }, false); } scroll(function(direction) { if(direction == "down") { console.log("向下滚"); } else { console.log("向上滚"); } }); }); </script> <script type="text/javascript"> var windowHeight = $(window).height(); $("body").css("height", windowHeight); var startX, startY, moveEndX, moveEndY, X, Y; $("body").on("touchstart", function(e) { e.preventDefault(); startX = e.originalEvent.changedTouches[0].pageX, startY = e.originalEvent.changedTouches[0].pageY; }); $("body").on("touchmove", function(e) { e.preventDefault(); moveEndX = e.originalEvent.changedTouches[0].pageX, moveEndY = e.originalEvent.changedTouches[0].pageY, X = moveEndX - startX, Y = moveEndY - startY; if (Math.abs(X) > Math.abs(Y) && X > 0) { alert("left to right"); } else if (Math.abs(X) > Math.abs(Y) && X < 0) { alert("right to left"); } else if (Math.abs(Y) > Math.abs(X) && Y > 0) { alert("top to bottom"); } else if (Math.abs(Y) > Math.abs(X) && Y < 0) { alert("bottom to top"); } else { alert("just touch"); } }); </script> 排序 <script type="text/javascript"> var a = [1, 18, 23, 9, 16, 10, 29, 17]; var t = 0; for(var i = 0; i < a.length; i++) { for(var j = i + 1; j < a.length; j++) { if(a[i] > a[j]) { t = a[i]; a[i] = a[j]; a[j] = t; } } } console.log(a); //[1, 9, 10, 16, 17, 18, 23, 29] </script> 倒计时: <!Doctype html> <html> <head> <meta charset="utf-8"> <title>下班倒计时</title> <style> * { margin: 0; padding: 0; } body { font-size: 16px; text-align: center; font-family: arial; } .time { margin-top: 10px; border: 1px solid red; height: 30px; padding: 2px; line-height: 30px; } </style> </head> <body> <div class="time"> <span id="t_d">00天</span> <span id="t_h">00时</span> <span id="t_m">00分</span> <span id="t_s">00秒</span> </div> <script> setInterval(function() { var EndTime = new Date('2016/06/13 00:00:00'); var NowTime = new Date(); var t = EndTime.getTime() - NowTime.getTime(); var d = 0; var h = 0; var m = 0; var s = 0; if (t >= 0) { d = Math.floor(t / 1000 / 60 / 60 / 24); h = Math.floor(t / 1000 / 60 / 60 % 24); m = Math.floor(t / 1000 / 60 % 60); s = Math.floor(t / 1000 % 60); } document.getElementById("t_d").innerHTML = d + "天"; document.getElementById("t_h").innerHTML = h + "时"; document.getElementById("t_m").innerHTML = m + "分"; document.getElementById("t_s").innerHTML = s + "秒"; }, 10); </script> </body> </html> 类型判断: function _typeOf(obj) { return Object.prototype.toString.call(obj).toLowerCase().slice(8, -1); // } 判断undefined: <span style="font-size: small;"> var tmp = undefined; if (typeof(tmp) == "undefined"){ alert("undefined"); } </span> 判断null: <span style="font-size: small;"> var tmp = null; if (!tmp && typeof(tmp)!="undefined" && tmp!=0){ alert("null"); }  </span> 判断NaN: var tmp = 0/0; if(isNaN(tmp)){ alert("NaN"); } 判断undefined和null: <span style="font-size: small;"> var tmp = undefined; if (tmp== undefined) { alert("null or undefined"); } </span> <span style="font-size: small;"> var tmp = undefined; if (tmp== null) { alert("null or undefined"); } </span> 判断undefined、null与NaN: <span style="font-size: small;"> var tmp = null; if (!tmp) { alert("null or undefined or NaN"); } </span> Ajax jquery ajax函数 我自己封装了一个ajax的函数,代码如下: var Ajax = function(url, type success, error) { $.ajax({ url: url, type: type, dataType: 'json', timeout: 10000, success: function(d) { var data = d.data; success && success(data); }, error: function(e) { error && error(e); } }); }; // 使用方法: Ajax('/data.json', 'get', function(data) { console.log(data); }); jsonp方式 有时候我们为了跨域,要使用jsonp的方法,我也封装了一个函数: function jsonp(config) { var options = config || {}; // 需要配置url, success, time, fail四个属性 var callbackName = ('jsonp_' + Math.random()).replace(".", ""); var oHead = document.getElementsByTagName('head')[0]; var oScript = document.createElement('script'); oHead.appendChild(oScript); window[callbackName] = function(json) { //创建jsonp回调函数 oHead.removeChild(oScript); clearTimeout(oScript.timer); window[callbackName] = null; options.success && options.success(json); //先删除script标签,实际上执行的是success函数 }; oScript.src = options.url + '?' + callbackName; //发送请求 if (options.time) { //设置超时处理 oScript.timer = setTimeout(function () { window[callbackName] = null; oHead.removeChild(oScript); options.fail && options.fail({ message: "超时" }); }, options.time); } }; // 使用方法: jsonp({ url: '/b.com/b.json', success: function(d){ //数据处理 }, time: 5000, fail: function(){ //错误处理 } }); JS生成随机字符串的最佳实践 var random_str = function() { var len = 32; var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; var max = chars.length; var str = ''; for (var i = 0; i < len; i++) {     str += chars.charAt(Math.floor(Math.random() * max)); } return str; }; //这样生成一个32位的随机字符串,相同的概率低到不可能。 常用正则表达式 JavaScript过滤Emoji的最佳实践 name = name.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, ""); 手机号验证: var validate = function(num) { var reg = /^1[3-9]\d{9}$/; return reg.test(num); }; ip验证: var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/ 常用js函数 返回顶部: $(window).scroll(function() { var a = $(window).scrollTop(); if(a > 100) { $('.go-top').fadeIn(); }else { $('.go-top').fadeOut(); } }); $(".go-top").click(function(){ $("html,body").animate({scrollTop:"0px"},'600'); }); 阻止冒泡: function stopBubble(e){ e = e || window.event; if(e.stopPropagation){ e.stopPropagation(); //W3C阻止冒泡方法 }else { e.cancelBubble = true; //IE阻止冒泡方法 } } 全部替换replaceAll: var replaceAll = function(bigStr, str1, str2) { //把bigStr中的所有str1替换为str2 var reg = new RegExp(str1, 'gm'); return bigStr.replace(reg, str2); } 获取浏览器url中的参数值: var getURLParam = function(name) { return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)', "ig").exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null; }; 深度拷贝对象: function cloneObj(obj) { var o = obj.constructor == Object ? new obj.constructor() : new obj.constructor(obj.valueOf()); for(var key in obj){ if(o[key] != obj[key] ){ if(typeof(obj[key]) == 'object' ){ o[key] = mods.cloneObj(obj[key]); }else{ o[key] = obj[key]; } } } return o; } 数组去重: var unique = function(arr) { var result = [], json = {}; for (var i = 0, len = arr.length; i < len; i++){ if (!json[arr[i]]) { json[arr[i]] = 1; result.push(arr[i]); //返回没被删除的元素 } } return result; }; 判断数组元素是否重复: var isRepeat = function(arr) { //arr是否有重复元素 var hash = {}; for (var i in arr) { if (hash[arr[i]]) return true; hash[arr[i]] = true; } return false; }; 生成随机数: function randombetween(min, max){ return min + (Math.random() * (max-min +1)); } 操作cookie: own.setCookie = function(cname, cvalue, exdays){ var d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000)); var expires = 'expires='+d.toUTCString(); document.cookie = cname + '=' + cvalue + '; ' + expires; }; own.getCookie = function(cname) { var name = cname + '='; var ca = document.cookie.split(';'); for(var i=0; i< ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1); if (c.indexOf(name) != -1) return c.substring(name.length, c.length); } return ''; }; 数据类型: underfined、null、0、false、NaN、空字符串。他们的逻辑非结果均为true。 闭包格式: 好处:避免命名冲突(全局变量污染)。 (function(a, b) { console.log(a+b); //30 })(10, 20); 截取和清空数组: var arr = [12, 222, 44, 88]; arr.length = 2; //截取,arr = [12, 222]; arr.length = 0; //清空,arr will be equal to []. 获取数组的最大最小值: var numbers = [5, 45822, 120, -215]; var maxInNumbers = Math.max.apply(Math, numbers); //45822 var minInNumbers = Math.min.apply(Math, numbers); //-215 浮点数计算问题: 0.1 + 0.2 == 0.3 //false 为什么呢?因为0.1+0.2等于0.30000000000000004。JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示。可以通过使用toFixed()来解决这个问题。 数组排序sort函数: var arr = [1, 5, 6, 3]; //数字数组 arr.sort(function(a, b) { return a - b; //从小到大排 return b - a; //从大到小排 return Math.random() - 0.5; //数组洗牌 }); var arr = [{ //对象数组 num: 1, text: 'num1' }, { num: 5, text: 'num2' }, { num: 6, text: 'num3' }, { num: 3, text: 'num4' }]; arr.sort(function(a, b) { return a.num - b.num; //从小到大排 return b.num - a.num; //从大到小排 }); 对象和字符串的转换: var obj = {a: 'aaa', b: 'bbb'}; var objStr = JSON.stringify(obj); // "{"a":"aaa","b":"bbb"}" var newObj = JSON.parse(objStr); // {a: "aaa", b: "bbb"} 对象拷贝与赋值 var obj = { name: 'xiaoming', age: 23 }; var newObj = obj; newObj.name = 'xiaohua'; console.log(obj.name); // 'xiaohua' console.log(newObj.name); // 'xiaohua' 上方我们将obj对象赋值给了newObj对象,从而改变newObj的name属性,但是obj对象的name属性也被篡改,这是因为实际上newObj对象获得的只是一个内存地址,而不是真正 的拷贝,所以obj对象被篡改。 var obj2 = { name: 'xiaoming', age: 23 }; var newObj2 = Object.assign({}, obj2, {color: 'blue'}); newObj2.name = 'xiaohua'; console.log(obj2.name); // 'xiaoming' console.log(newObj2.name); // 'xiaohua' console.log(newObj2.color); // 'blue' 上方利用Object.assign()方法进行对象的深拷贝可以避免源对象被篡改的可能。因为Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。 var obj3 = { name: 'xiaoming', age: 23 }; var newObj3 = Object.create(obj3); newObj3.name = 'xiaohua'; console.log(obj3.name); // 'xiaoming' console.log(newObj3.name); // 'xiaohua' 我们也可以使用Object.create()方法进行对象的拷贝,Object.create()方法可以创建一个具有指定原型对象和属性的新对象。 git笔记 git使用之前的配置: 1.git config --global user.email xxx@163.com 2.git config --global user.name xxx 3.ssh-keygen -t rsa -C xxx@163.com(邮箱地址) // 生成ssh 4.找到.ssh文件夹打开,使用cat id_rsa.pub //打开公钥ssh串 5.登陆github,settings - SSH keys - add ssh keys (把上面的内容全部添加进去即可) 说明:然后这个邮箱(xxxxx@gmail.com)对应的账号在github上就有权限对仓库进行操作了。可以尽情的进行下面的git命令了。 git常用命令: 1、git config user.name / user.email //查看当前git的用户名称、邮箱 2、git clone https://github.com/jarson7426/javascript.git project //clone仓库到本地。 3、修改本地代码,提交到分支: git add file / git commit -m “新增文件” 4、把本地库推送到远程库: git push origin master 5、查看提交日志:git log -5 6、返回某一个版本:git reset --hard 123 7、分支:git branch / git checkout name / git checkout -b dev 8、合并name分支到当前分支:git merge name / git pull origin 9、删除本地分支:git branch -D name 10、删除远程分支: git push origin :daily/x.x.x 11、git checkout -b mydev origin/daily/1.0.0 //把远程daily分支映射到本地mydev分支进行开发 12、合并远程分支到当前分支 git pull origin daily/1.1.1 13、发布到线上: git tag publish/0.1.5 git push origin publish/0.1.5:publish/0.1.5 14、线上代码覆盖到本地: git checkout --theirs build/scripts/ddos git checkout --theirs src/app/ddos 判断是否有中文: var reg = /.*[\u4e00-\u9fa5]+.*$/; reg.test('123792739测试') //true 判断是对象还是数组: function isArray = function(o) { return toString.apply(o) === '[object Array]'; } function isObject = function(o) { return toString.apply(o) === '[object Object]'; } CSS修改滚动条样式: ::-webkit-scrollbar { width: 10px; background-color: #ccc; } ::-webkit-scrollbar-track { background-color: #ccc; border-radius: 10px; } ::-webkit-scrollbar-thumb { background-color: rgb(255, 255, 255); background-image: -webkit-gradient(linear, 40% 0%, 75% 84%, from(rgb(77, 156, 65)), color-stop(0.6, rgb(84, 222, 93)), to(rgb(25, 145, 29))); border-radius: 10px; } 单行多行省略号: <style type="text/css"> .inaline { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; /*clip 修剪文本。*/ } .intwoline { display: -webkit-box !important; overflow: hidden; text-overflow: ellipsis; word-break: break-all; -webkit-box-orient: vertical; -webkit-line-clamp: 3; } </style> 遮罩: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>RGBA 遮罩</title> <style type="text/css"> * { padding: 0px; margin: 0px; } html, body { width: 100%; min-height: 100%; background: white; } div.mask { display: none; position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); } div.masks-body { width: 300px; height: 300px; position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; background: green; margin: auto; } p { position: absolute; width: 30px; height: 30px; background: red; right: 0px; top: -30px; } </style> <script type="text/javascript"> window.onload = function() { document.querySelector("#main").onclick = function() { document.querySelector(".mask").style.display = "block"; } document.querySelector("p#close").onclick=function(){ document.querySelector(".mask").style.display = "none"; } } </script> </head> <body> <button id="main">点我</button> <div class="mask"> <div class="masks-body"> <p id="close"></p> </div> </div> </body> </html> 常见页面flex布局: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title></title> <style type="text/css"> * { padding: 0px; margin: 0px; } html, body { width: 100%; min-height: 100%; min-width: 1200px; overflow-x: hidden; } h1 { color: red; text-align: center; } #main0 { height: 400px; background: black; display: flex; flex-flow: row wrap; justify-content: flex-start; align-items: flex-start; } #main0 div:nth-child(2n) { flex: 1; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: red; } #main0 div:nth-child(2n+1) { flex: 1; height: 200px; line-height: 200px; font-size: 100px; text-align: center; background: blue; } #main1 { height: 400px; background: pink; display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: flex-start; } #main1 div:nth-child(2n) { flex: 1; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: red; } #main1 div:nth-child(2n+1) { width: 300px; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: blue; } #main2 { height: 400px; background: yellow; display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: flex-start; } #main2 div:nth-child(2n) { flex: 1; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: red; } #main2 div:nth-child(2n+1) { width: 300px; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: blue; } #main3 { height: 400px; background: fuchsia; display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: flex-start; } #main3 div.div1 { flex: 1; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: blue; } #main3 div.div2 { flex: 2; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: red; } #main3 div.div3 { flex: 3; height: 200px; font-size: 100px; line-height: 200px; text-align: center; background: orange; } </style> </head> <body> <h1>等分布局</h1> <div id="main0"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </div> <h1>左边固定右边自适应布局</h1> <div id="main1"> <div>1</div> <div>2</div> </div> <h1>左右固定中间自适应布局</h1> <div id="main2"> <div>1</div> <div>2</div> <div>3</div> </div> <h1>宽度等差布局</h1> <div id="main3"> <div class="div1">1</div> <div class="div2">2</div> <div class="div3">3</div> </div> </body> </html> flex: 1的使用: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style type="text/css"> * { padding: 0px; margin: 0px; } #main { display: flex; align-items: center; } h1 { background: red; flex: 1; text-align: center; } </style> </head> <body> <div id="main"> <p>哈哈哈</p> <h1>啊啊啊</h1> <div>呜呜呜</div> </div> </body> </html> 单行超出省略字 .div{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } placeholder颜色 input::-webkit-input-placeholder{ color: #666; } 禁止文本选择 .div{ -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; -khtml-user-select:none; user-select:none; } iOS惯性滚动 .div{ -webkit-overflow-scrolling:touch !important; } 表单100%宽,但是有padding input{ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } 字体细长 .div{ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 横向滚动 .div{ white-space: nowrap; overflow-x: auto; overflow-y: hidden; } IOS开关: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div#main { width: 208px; height: 108px; border-radius: 60px; background: pink; overflow: hidden; transition: all 300ms linear 0s; } div#main.bk { background: red; } div.ios { width: 100px; height: 100px; border-radius: 50px; background: blue; margin-left: 4px; margin-top: 4px; transition: all 300ms linear 0s; } div.ios.sb { margin-left: 104px; } </style> <script type="text/javascript"> window.onload = function() { document.getElementById("main").onclick = function() { if(document.querySelector("div.ios").classList.contains("sb")) { document.querySelector("div.ios").classList.remove("sb"); this.classList.remove("bk"); return false; } document.querySelector("div.ios").classList.add("sb"); this.classList.add("bk"); } } </script> </head> <body> <div id="main"> <div class="ios"></div> </div> </body> </html> 一个高度自适应的DIV <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>一个高度自适应的DIV</title> <style type="text/css"> * { padding: 0px; margin: 0px; } div { width: 100%; position: absolute; /*relative 不可以*/ top: 100px; bottom: 100px; left: 0px; right: 0px; background: red; } </style> </head> <body> <div></div> </body> </html> 浅拷贝与深拷贝 ------------- 浅拷贝 ------------- var obj = { name: 'name' } var a = obj; a.name = 'new name'; console.log(a.name); // 'new name' console.log(obj.name); // 'new name' 这里就是一个浅拷贝的例子。a只是通过赋值符号得到了obj的引用。 --------------- 深拷贝 --------------- function object(parent, child) { var i, tostring = Object.prototype.toString, aStr = "[object Array]"; child = child || {}; for(i in parent) { if(parent.hasOwnProperty(i)) { //这时候还要判断它的值是不是对象 if(typeof parent[i] === 'object') { child[i] = tostring.call(parent[i]) === aStr ? [] : {}; object(parent[i], child[i]); } else { child[i] = parent[i]; } } } return child; } var obj = { tags: ['js','css'], s1: { name: 'dai', age: 21 }, flag: true } var some = object(obj); some.tags = [1,2]; console.log(some.tags); //[1, 2] console.log(obj.tags); //['js', 'css'] placeholder是H5的一个新属性,但是在IE9以下是不支持的,为此我们会封装一个函数进行能力检测。 $(function() { // 如果不支持placeholder,用jQuery来完成 if(!isSupportPlaceholder()) { // 遍历所有input对象, 除了密码框 $('input').not("input[type='password']").each( function() { var self = $(this); var val = self.attr("placeholder"); input(self, val); } ); /** * 对password框的特殊处理 * 1.创建一个text框 * 2.获取焦点和失去焦点的时候切换 */ $('input[type="password"]').each( function() { var pwdField = $(this); var pwdVal = pwdField.attr('placeholder'); var pwdId = pwdField.attr('id'); // 重命名该input的id为原id后跟1 pwdField.after('<input id="' + pwdId +'1" type="text" value='+pwdVal+' autocomplete="off" />'); var pwdPlaceholder = $('#' + pwdId + '1'); pwdPlaceholder.show(); pwdField.hide(); pwdPlaceholder.focus(function(){ pwdPlaceholder.hide(); pwdField.show(); pwdField.focus(); }); pwdField.blur(function(){ if(pwdField.val() == '') { pwdPlaceholder.show(); pwdField.hide(); } }); } ); } }); // 判断浏览器是否支持placeholder属性 function isSupportPlaceholder() { var input = document.createElement('input'); return 'placeholder' in input; } // jQuery替换placeholder的处理 function input(obj, val) { var $input = obj; var val = val; $input.attr({value:val}); $input.focus(function() { if ($input.val() == val) { $(this).attr({value:""}); } }).blur(function() { if ($input.val() == "") { $(this).attr({value:val}); } }); } 苹果浏览器和uc浏览器在移动端的坑(日常积累,随时更新) 1 . 移动端uc浏览器不兼容css3 calc() 2 . ie8下a标签没有内容给宽高也不能触发点击跳转 3 . safari输入框加上readOnly="ture"属性仍然可以触发获取焦点,可再加上onfocus="this.blur()“解决 日期格式化: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) // 例子: // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } 调用: var time1 = new Date().Format("yyyy-MM-dd"); var time2 = new Date().Format("yyyy-MM-dd HH:mm:ss"); js中不存在自带的sleep方法,要想休眠要自己定义个方法: function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } } 将 Date 转化为指定格式的String // 对Date的扩展,将 Date 转化为指定格式的String // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) // 例子: // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 Date.prototype.Format = function (fmt) { //author: zouqj var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; } 获取当前时间,格式:yyyy-MM-dd hh:mm:ss //获取当前时间,格式:yyyy-MM-dd hh:mm:ss function getNowFormatDate() { var date = new Date(); var seperator1 = "-"; var seperator2 = ":"; var month = date.getMonth() + 1; var strDate = date.getDate(); if (month >= 1 && month <= 9) { month = "0" + month; } if (strDate >= 0 && strDate <= 9) { strDate = "0" + strDate; } var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate + " " + date.getHours() + seperator2 + date.getMinutes() + seperator2 + date.getSeconds(); return currentdate; } 生成一个由随机数组成的伪Guid(32位Guid字符串) //方式一 function newPseudoGuid () { var guid = ""; for (var i = 1; i <= 32; i++) { var n = Math.floor(Math.random() * 16.0).toString(16); guid += n; if ((i == 8) || (i == 12) || (i == 16) || (i == 20)) guid += "-"; } return guid; } //方式二 function S4() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); } //生成guid function guid() { return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); } 判断js是否加载完毕: 在正常的加载过程中,js文件的加载是同步的,也就是说在js加载的过程中,浏览器会阻塞接下来的内容的解析。这时候,动态加载便显得尤为重要了,由于它是异步加载,因此,它可以在后台自动下载,并不会妨碍其它内容的正常解析,由此,便可以提高页面首次加载的速度。 在IE或一些基于IE内核的浏览器中(如Maxthon),它是通过script节点的readystatechange方法来判断的,而其它的一些浏览器中,往往是通过load事件来决定的。 function dynamicLoad() { var _doc=document.getElementsByTagName('head')[0]; var script=document.createElement('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src','jquery-1.4.4.js'); _doc.appendChild(script); script.onload=script.onreadystatechange=function(){ if(!this.readyState||this.readyState=='loaded'||this.readyState=='complete'){ alert('done'); } script.onload=script.onreadystatechange=null; } } <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> function dynamicLoad() { var _doc = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', 'js/a.js'); _doc.appendChild(script); script.onload = script.onreadystatechange = function() { if(!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') { alert('下载完成!'); } script.onload = script.onreadystatechange = null; } } dynamicLoad(); </script> </head> <body> </body> </html> 递归排列组合: <!DOCTYPE html> <html> <head> <title>demo</title> <script type="text/javascript"> var str = [1, 2, 3, 4, 5]; var count = 0; function arrange(s) { for(var i = 0, length = str.length; i < length; i++) { if(s.length == length - 1) { if(s.indexOf(str[i]) < 0) { count++; document.writeln("组合" + count + ":" + s + str[i] + '<br />'); } continue; } if(s.indexOf(str[i]) < 0) { arrange(s + str[i]); } } } arrange(""); </script> </head> <body> </body> </html> js获取页面url: 设置或获取对象指定的文件名或路径。 window.location.pathname 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.pathname); 则输出:/topic/index 设置或获取整个 URL 为字符串。 window.location.href 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.href); 则输出:http://localhost:8086/topic/index?topicId=361 设置或获取与 URL 关联的端口号码。 window.location.port 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.port); 则输出:8086 设置或获取 URL 的协议部分。 window.location.protocol 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.protocol); 则输出:http: 设置或获取 href 属性中在井号“#”后面的分段。 window.location.hash 设置或获取 location 或 URL 的 hostname 和 port 号码。 window.location.host 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.host); 则输出:http:localhost:8086 设置或获取 href 属性中跟在问号后面的部分。 window.location.search 例:http://localhost:8086/topic/index?topicId=361 alert(window.location.search); 则输出:?topicId=361 window.location 属性 描述 hash 设置或获取 href 属性中在井号“#”后面的分段。 host 设置或获取 location 或 URL 的 hostname 和 port 号码。 hostname 设置或获取 location 或 URL 的主机名称部分。 href 设置或获取整个 URL 为字符串。 pathname 设置或获取对象指定的文件名或路径。 port 设置或获取与 URL 关联的端口号码。 protocol 设置或获取 URL 的协议部分。 search 设置或获取 href 属性中跟在问号后面的部分。 css不常用选择器 ele:nth-of-type为什么要叫:nth-of-type?因为它是以"type"来区分的。 也就是说:ele:nth-of-type(n)是指父元素下第n个ele元素, 而ele:nth-child(n)是指父元素下第n个元素且这个元素为ele,若不是,则选择失败。 h4~p h4后面的p标签 h4+p h4相邻的p标签 p[id] 包含id属性的p标签 p[class~="b"] class类名为b且b前面有空格的p标签 p[class|="b"] class类名为b且b后面有横杠的p标签 a[href^="http"] a标签下的href以http开头 a[href$="rar"] a标签下的href以rar结尾 a[href*="o"] a标签下的href有o p::first-line 选择p标签下第一行 a:before(a::before),a:after(a::after) 伪元素 p::selection 选择被选中的文字 p::first-letter 选择p标签下第一个字 div:not(#container) 选择除id为container之外的所有div标签 p:first-child 找到P,然后找P的父级 再找父级下第一个元素是P(匹配的是某父元素的第一个子元素,可以说是结构上的第一个子元素。) p:first-of-type 找到P,然后找P的父级 再找父级下第一个元素是P(匹配的是该类型的第一个,这里不再限制是第一个子元素了,只要是该类型元素的第一个就行了,当然这些元素的范围都是属于同一级的,也就是同辈的。) p:last-child 找到P 然后找P的父级 再找父级下最后一个元素是P p:last-of-type 找到P 然后找P的父级 再找父级下最后一个元素是P li:nth-child(2) 找到li 然后找li的父级 再找父级下第二个元素是li li:nth-of-type(2) li:nth-last-child(2) 找到li 然后找li的父级 再找父级下倒数第二元素个是li li:nth-last-of-type(2) li:nth-child(even) 找到li的所有偶数位(2N) li:nth-last-child(even) li:nth-last-child(odd) 找到li的所有奇数位(2N-1 或 2n+1) li:nth-last-child(odd) li:only-child 找到li是父级的唯一子元素(选择器选择的是父元素中只有一个子元素,而且只有唯一的一个子元素) li:only-of-type 表示一个元素他有很多个子元素,而其中只有一种类型的子元素是唯一的,使用“:only-of-type”选择器就可以选中这个元素中的唯一一个类型子元素。 对 Select 的各种操作(JQuery) <select id="relationship" name="relationship" required="true"> <option value="1">父母</option> <option value="2">夫妻</option> <option value="3">子女</option> <option value="4">朋友</option> <option value="5">其他</option> </select> $(document).ready(function() { //获取下拉框选中项的index属性值 var selectIndex = $("#relationship").get(0).selectedIndex; alert(selectIndex); //绑定下拉框change事件,当下来框改变时调用 SelectChange()方法 $("#relationship").change(function() { //todo }); //获取下拉框选中项的value属性值 var selectValue = $("#relationship").val(); alert(selectValue); //获取下拉框选中项的text属性值 var selectText = $("#relationship").find("option:selected").text(); alert(selectText); //设置下拉框index属性为5的选项 选中 $("#relationship").get(0).selectedIndex = 5; //设置下拉框value属性为4的选项 选中 $("#relationship").val(4); //设置下拉框text属性为5的选项 选中 $("#relationship option[text=5]").attr("selected", "selected"); $("#yyt option:contains('5')").attr("selected", true); ////获取下拉框最大的index属性值 var selectMaxIndex = $("#relationship option:last").attr("index"); alert(selectMaxIndex); //在下拉框最前添加一个选项 $("#relationship").prepend("<option value='0'>领导</option>"); //在下拉框最后添加一个选项 $("#relationship").append("<option value='6'>同事</option>"); //移除下拉框最后一个选项 $("#relationship option:last").remove(); //移除下拉框 index属性为1的选项 $("#relationship option[index=1]").remove(); //移除下拉框 value属性为4的选项 $("#relationship option[value=4]").remove(); //移除下拉框 text属性为5的选项 $("#relationship option[text=5]").remove(); }); JavaScript利用闭包实现模块化 var foo = (function CoolModule() { var something = "cool"; var another = [1, 2, 3]; function doSomething() { alert( something ); } function doAnother() { alert( another.join( " ! " ) ); } return { doSomething: doSomething, doAnother: doAnother }; })(); foo.doSomething(); // cool foo.doAnother(); // 1 ! 2 ! 3 javascript中如何把一个数组的内容全部赋值给另外一个数组: 一、 错误实现 var array1 = new Array("1","2","3"); var array2; array2 = array1; array1.length = 0; alert(array2); //返回为空 这种做法是错的,因为javascript分原始类型与引用类型(与java、c#类似)。Array是引用类 型。array2得到的是引用,所以对array1的修改会影响到array2。 二、 使用slice() 可使用slice()进行复制,因为slice()返回也是数组。 var array1 = new Array("1","2","3"); var array2; array2 = array1.slice(0); array1.length = 0; alert(array2); //返回1、2、3 三、 使用concat() 注意concat()返回的并不是调用函数的Array,而是一个新的Array,所以可以利用这一点进行复制。 var array1 = new Array("1","2","3"); var array2; array2 = array1.concat(); array1.length = 0; alert(array2); //返回1、2、3 var b = [].concat(a); 事件委派: //利用事件委派可以写出更加优雅的 (function(){ var resources = document.getElementById('resources'); resources.addEventListener('click',handler,false); function handler(e){ var x = e.target; // get the link tha if(x.nodeName.toLowerCase() === 'a'){ alert(x); e.preventDefault(); } }; })(); 把字符串的首字母大写返回一个新的字符串 1.1简单写法,把一个单词的首字母大写 String.prototype.firstUpperCase = function(){ return this[0].toUpperCase()+this.slice(1); } 1.2字符串中所有单词首字母大写,非首字母小写 String.prototype.firstUpperCase = function(){ return this.replace( /\b(\w)(\w*)/g, function($0, $1, $2) {// \b代表定界符 // 第一个形参$0代表所有子字符串(所有单词) // 第二个形参$1代表第一个括号内匹配到的字符串(首字母) // 第三个形参$2代表第二个括号内匹配到的字符串(除首字母外的字母) return $1.toUpperCase() + $2.toLowerCase()}); } 另一种写法 String.prototype.firstUpperCase = function(){ return this.toLowerCase().replace(/( |^)[a-z]/g, function(U){return U.toUpperCase()}); } 随机数: 由js生成一切随机数的基础都是Math.random(),这个方法比较特别,生成的随机数落在的区间是[0,1); 全闭区间[n,m] 这种的最常见,大家都知道的那一长串公式:Math.floor(Math.random()*(m-n+1))+n; 就是生成这个全闭区间的方法。说到这个公式很多人都知道,但真正想明白的人估计很少。先生成一个[0,m-n+1)这样左闭右开的区间,然后用Math.floor()取到[0,m-n]之间内的任意整数(看明白这一步很关键),之后加上区间左端点变成[n,m]内的任意整数,达到目的。 说到这个地方,有一点必须提一下,随便搜一下js生成随机数,有很多文章都会用Math.ceil()或Math.round()这两个方法,比如生成全闭的[n,m]区间内的任意整数,Math.ceil(Math.random()*(m-n))+n;或者Math.round(Math.random()*(m-n))+n;我感觉随机数,最重要的就是随机两个字,每个值取到的概率一定要相等,这一点对于一些特定的场合非常重要,比如抽奖(年会都有抽奖的吧)。Math.ceil()的毛病是n<<m≈x,x为除端点之外的数,区间足够大的话n几乎取不到,m和x的概率几乎相等,因为m这个点取不到所以概率相对来说小了一点。Math.round()的毛病是n≈m=x/2,原因和前面的差不多,不明白的可以自己画个坐标轴,很明了。 全开区间(x,y) 其实只要记住上面的全闭区间,其它所有区间的开闭,都可以由其推到,过程如下: (x,y) ==[x+1,y-1];也就是说n=x+1; m=y-1;将其代入上面的公式就可以得到:Math.floor(Math.random()*(y-x-1))+x+1; 左闭右开[x,y) 同理,[x,y) == [x,y-1];代入得到:Math.floor(Math.random()*(y-x))+x; 左开右闭(x,y] (x,y]==[x+1,y];代入得到:Math.floor(Math.random()*(y-x))+x+1; js 小数取整,js 小数向上取整,js小数向下取整 /** * 数字,数字(包括正整数、0、浮点数),也可以判断是否金额 * @param z_check_value 要检查的值 * @return 符合返回true,否false * @author lqy * @since 2017-01-07 */ function isFloat(z_check_value){ var z_reg = /^((([0-9])|([1-9][0-9]+))(\.([0-9]+))?)$/;//.是特殊字符,需要转义 return z_reg.test($.trim(z_check_value)); }; /** * js小数向下取整:浮点数转换成整数,小数点后去掉 * @param floatNumber */ function floatToInteger(floatNumber){ if(!isFloat(floatNumber)){ error("请输入正确的数字"); return; } return parseInt(floatNumber); }; /** * js 小数向上取整:浮点数转换成整数,如果有小数(1.00不算有小数),整数加1 * @param floatNumber */ function floatToIntegerUp(floatNumber){ var integerNumber = floatToInteger(floatNumber); if(floatNumber > integerNumber){ integerNumber += 1; } return integerNumber; }; CSS多行文本溢出省略显示 文本溢出我们经常用到的应该就是text-overflow:ellipsis了,相信大家也很熟悉,但是对于多行文本的溢出处理确接触的不是很多,最近在公司群里面有同事问到,并且自己也遇到过这个问题,所以专门研究过这个问题。 首先我们回顾一下以前实现单行缩略是可以通过下面的代码实现的(部分浏览器需要设置宽度): overflow: hidden; text-overflow: ellipsis; white-space: nowrap; WebKit内核浏览器解决办法 首先,WebKit内核的浏览器实现起来比较简单,可以通过添加一个-webkit-line-clamp的私有属性来实现,-webkit-line-clamp是用来限制在一个块元素显示的文本的行数。 为了实现这个效果,它需要组合其他的WebKit属性: display: -webkit-box 将对象作为弹性伸缩盒子模型显示; -webkit-box-orient 设置或检索伸缩盒对象的子元素的排列方式; text-overflow: ellipsis 用省略号“…”隐藏超出范围的文本。 具体代码参考如下: overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; 这个方法合适WebKit浏览器或移动端(绝大部分是WebKit内核的)浏览器,效果可以查看: 其他浏览器的解决方案 目前没有什么CSS的属性可以直接控制多行文本的省略显示,比较靠谱的办法应该就是利用相对定位在最后面加上一个省略号了,代码可以参考下面: p { position:relative; line-height:1.5em; /* 高度为需要显示的行数*行高,比如这里我们显示两行,则为3 */ height:3em; overflow:hidden; } p:after { content:"..."; position:absolute; bottom:0; right:0; padding: 0 5px; background-color: #fff; } 效果如下: 不过这样会有一点问题: 需要知道显示的行数并设置行高才行; IE6/7不支持after和content,需要添加一个标签来代替; 省略号的背景颜色跟文本背景颜色一样,并且可能会遮住部分文字,建议可以使用渐变的png背景图片代替。 一行居中多行居左: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .ps { width: 600px; border: 1px solid red; text-align: center; } .ps span { display: inline-block; text-align: left; } .tab-cell { display: table; margin: 0 auto; text-align: left; } </style> </head> <body> <p class="ps"><span>文字文文字文字文字文字</span></p> <p class="ps"><span>文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字<文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字</span></p> <p class="tab-cell">文字文文字文字文字文字</p> <p class="tab-cell">文字文文字文字文字文字文字文文字文字文字文字文字文文字文字文字文字</p> </body> </html> 判断返回js数据类型 function judgeType(arg){//判断返回js数据类型 return Object.prototype.toString.call(arg).slice(8,-1); } clone function deepCloneNick(obj){//深克隆 var result; //确定result的类型 if(judgeType(obj)==="Object"){ result={}; }else if(judgeType(obj)==="Array"){ result=[]; }else{ return obj; } for(var key in obj){ var copy=obj[key]; if(judgeType(copy)==="Object"||"Array"){ //result[key]=deepCloneNick(copy);//递归调用 避免函数名改变 改成下面一句 result[key]=arguments.callee(copy); }else{ result[key]=obj[key]; } } return result; } var obj={a:[1,2],b:3},arr=[{a:'a'},2]; var obj1=deepCloneNick(obj),arr1=deepCloneNick(arr); console.log(obj); console.log(obj1); console.log(arr); console.log(arr1); let person = { getGreeting() { return "Hello"; } }; // 原型为 person let friend = { getGreeting() { return super.getGreeting() + ", hi!"; } }; Object.setPrototypeOf(friend, person); console.log(friend.getGreeting()); // "Hello, hi!" 学习z-index,整理转述 前言:这是笔者第一次写博客,主要是学习之后自己的理解。如果有错误或者疑问的地方,请大家指正,我会持续更新! z-index属性描述元素的堆叠顺序(层级),意思是A元素可以覆盖B元素,但是B元素并没有消失(display:none) z-index属性可以为负值,默认为auto(可以理解为0),值最大的处于最上层. 一些元素设置z-index无效,可能的原因: z-index属性必须和position属性(absolute/relative/fixed)配合使用,否则无效. z-index属性应该继承父元素的z-idnex值,意思就是祖先元素优先,如果两个父元素层级已决高下,那么他们两个的子元素之间再设层级就不会起作用了. 额,先就这么多了,原本想画个图来解释的,发现不会画图,还是要继续学习。 网页上添加一个input file HTML控件: 1   默认是这样的,所有文件类型都会显示出来,如果想限制它只显示我们设定的文件类型呢,比如“word“,”excel“,”pdf“文件  解决办法是可以给它添加一个accept属性,比如: <input type="file" id="userImage" name="userImage" accept="image/x-png,image/gif,image/jpeg,image/bmp"/> WebSocket : WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持。 WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。 Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。 二、WebSocket API的用法 只专注于客户端的API,因为每个服务器端语言有自己的API。下面的代码片段是打开一个连接,为连接创建事件监听器,断开连接,消息时间,发送消息返回到服务器,关闭连接。 // 创建一个Socket实例 var socket = new WebSocket('ws://localhost:8080'); // 打开Socket socket.onopen = function(event) { // 发送一个初始化消息 socket.send('I am the client and I\'m listening!'); // 监听消息 socket.onmessage = function(event) { console.log('Client received a message',event); }; // 监听Socket的关闭 socket.onclose = function(event) { console.log('Client notified socket has closed',event); }; // 关闭Socket.... //socket.close() }; 让我们来看看上面的初始化片段。参数为URL,ws表示WebSocket协议。onopen、onclose和onmessage方法把事件连接到Socket实例上。每个方法都提供了一个事件,以表示Socket的状态。 onmessage事件提供了一个data属性,它可以包含消息的Body部分。消息的Body部分必须是一个字符串,可以进行序列化/反序列化操作,以便传递更多的数据。 WebSocket的语法非常简单,使用WebSockets是难以置信的容易……除非客户端不支持WebSocket。 Websocket 1.websocket是什么? WebSocket是为解决客户端与服务端实时通信而产生的技术。其本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接, 此后服务端与客户端通过此TCP连接进行实时通信。 2.websocket的优点 以前我们实现推送技术,用的都是轮询,在特点的时间间隔有浏览器自动发出请求,将服务器的消息主动的拉回来,在这种情况下,我们需要不断的向服务器 发送请求,然而HTTP request 的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。会占用大量的带宽和服务器资源。 WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。在建立连接之后,服务器可以主动传送数据给客户端。 此外,服务器与客户端之间交换的标头信息很小。 WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息; 关于ajax,comet,websocket的详细介绍,和websocket报文的介绍,大家可以参看www.shaoqun.com/a/54588.asp… 网页设计]Ajax、Comet与Websocket, 3.如何使用websocket 客户端 在支持WebSocket的浏览器中,在创建socket之后。可以通过onopen,onmessage,onclose即onerror四个事件实现对socket进行响应 一个简单是示例 var ws = new WebSocket(“ws://localhost:8080”); ws.onopen = function() { console.log(“open”); ws.send(“hello”); }; ws.onmessage = function(evt) { console.log(evt.data) }; ws.onclose = function(evt) { console.log(“WebSocketClosed!”); }; ws.onerror = function(evt) { console.log(“WebSocketError!”); }; 1.var ws = new WebSocket(“ws://localhost:8080”); 申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。 ws.send(“hello”); 用于叫消息发送到服务端 2.ws.onopen = function() { console.log(“open”)}; 当websocket创建成功时,即会触发onopen事件 3.ws.onmessage = function(evt) { console.log(evt.data) }; 当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据 4.ws.onclose = function(evt) { console.log(“WebSocketClosed!”); }; 当客户端收到服务端发送的关闭连接的请求时,触发onclose事件 5.ws.onerror = function(evt) { console.log(“WebSocketError!”); }; 如果出现连接,处理,接收,发送数据失败的时候就会触发onerror事件 我们可以看出所有的操作都是采用事件的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。 服务端: 现在有很多的服务器软件支持websocket,比如node.js,jetty,tomcat等 原文发布时间为:2017年10月21日原文作者:掘金本文来源:掘金 如需转载请联系原作者  
文章
Web App开发  ·  前端开发  ·  JavaScript  ·  API  ·  数据格式
2018-07-16
提高 PHP 代码质量的 36 计
1.不要使用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会检查过多路径. 如果该脚本被另一目录的脚本包含, 它的基本目录变成了另一脚本所在的目录. 另一问题, 当定时任务运行该脚本, 它的上级目录可能就不是工作目录了. 因此最佳选择是使用绝对路径: define('ROOT' , '/var/www/project/'); require_once(ROOT . '../../lib/some_class.php'); //rest of the code 我们定义了一个绝对路径, 值被写死了. 我们还可以改进它. 路径 /var/www/project 也可能会改变, 那么我们每次都要改变它吗? 不是的, 我们可以使用__FILE__常量, 如: //suppose your script is /var/www/project/index.php //Then __FILE__ will always have that full path. define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME)); require_once(ROOT . '../../lib/some_class.php'); //rest of the code 现在, 无论你移到哪个目录, 如移到一个外网的服务器上, 代码无须更改便可正确运行. 不要直接使用 require, include, include_once, required_once 可以在脚本头部引入多个文件, 像类库, 工具文件和助手函数等, 如: require_once('lib/Database.php'); require_once('lib/Mail.php'); require_once('helpers/utitlity_functions.php'); 这种用法相当原始. 应该更灵活点. 应编写个助手函数包含文件. 例如: function load_class($class_name) { //path to the class file $path = ROOT . '/lib/' . $class_name . '.php'); require_once( $path ); } load_class('Database'); load_class('Mail'); 有什么不一样吗? 该代码更具可读性. 將来你可以按需扩展该函数, 如: function load_class($class_name) { //path to the class file $path = ROOT . '/lib/' . $class_name . '.php'); if(file_exists($path)) { require_once( $path ); } } 还可做得更多: 为同样文件查找多个目录 能很容易的改变放置类文件的目录, 无须在代码各处一一修改 可使用类似的函数加载文件, 如html内容. 为应用保留调试代码 在开发环境中, 我们打印数据库查询语句, 转存有问题的变量值, 而一旦问题解决, 我们注释或删除它们. 然而更好的做法是保留调试代码. 在开发环境中, 你可以: define('ENVIRONMENT' , 'development'); if(! $db->query( $query ) { if(ENVIRONMENT == 'development') { echo "$query failed"; } else { echo "Database error. Please contact administrator"; } } 在服务器中, 你可以: define('ENVIRONMENT' , 'production'); if(! $db->query( $query ) { if(ENVIRONMENT == 'development') { echo "$query failed"; } else { echo "Database error. Please contact administrator"; } } 使用可跨平台的函数执行命令 system, exec, passthru, shell_exec 这4个函数可用于执行系统命令. 每个的行为都有细微差别. 问题在于, 当在共享主机中, 某些函数可能被选择性的禁用. 大多数新手趋于每次首先检查哪个函数可用, 然而再使用它. 更好的方案是封成函数一个可跨平台的函数. /** Method to execute a command in the terminal Uses : 1. system 2. passthru 3. exec 4. shell_exec */ function terminal($command) { //system if(function_exists('system')) { ob_start(); system($command , $return_var); $output = ob_get_contents(); ob_end_clean(); } //passthru else if(function_exists('passthru')) { ob_start(); passthru($command , $return_var); $output = ob_get_contents(); ob_end_clean(); } //exec else if(function_exists('exec')) { exec($command , $output , $return_var); $output = implode("n" , $output); } //shell_exec else if(function_exists('shell_exec')) { $output = shell_exec($command) ; } else { $output = 'Command execution not possible on this system'; $return_var = 1; } return array('output' => $output , 'status' => $return_var); } terminal('ls'); 上面的函数將运行shell命令, 只要有一个系统函数可用, 这保持了代码的一致性. 灵活编写函数 function add_to_cart($item_id , $qty) { $_SESSION['cart']['item_id'] = $qty; } add_to_cart( 'IPHONE3' , 2 ); 使用上面的函数添加单个项目. 而当添加项列表的时候,你要创建另一个函数吗? 不用, 只要稍加留意不同类型的参数, 就会更灵活. 如: function add_to_cart($item_id , $qty) { if(!is_array($item_id)) { $_SESSION['cart']['item_id'] = $qty; } else { foreach($item_id as $i_id => $qty) { $_SESSION['cart']['i_id'] = $qty; } } } add_to_cart( 'IPHONE3' , 2 ); add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) ); 现在, 同个函数可以处理不同类型的输入参数了. 可以参照上面的例子重构你的多处代码, 使其更智能. 有意忽略php关闭标签 我很想知道为什么这么多关于php建议的博客文章都没提到这点. <?php echo "Hello"; //Now dont close this tag 这將节约你很多时间. 我们举个例子: 一个 super_class.php 文件 //super extra character after the closing tag index.php require_once('super_class.php'); //echo an image or pdf , or set the cookies or session data 这样, 你將会得到一个 Headers already send error. 为什么? 因为 “super extra character” 已经被输出了. 现在你得开始调试啦. 这会花费大量时间寻找 super extra 的位置. 因此, 养成省略关闭符的习惯: <!--?php class super_class { function super_function() { //super code } } //No closing tag</pre--> 这会更好. 在某地方收集所有输入, 一次输出给浏览器 这称为输出缓冲, 假如说你已在不同的函数输出内容: function print_header() { echo "Site Log and Login links"; } function print_footer() { echo "Site was made by me"; } print_header(); for($i = 0 ; $i '; } print_footer(); 替代方案, 在某地方集中收集输出. 你可以存储在函数的局部变量中, 也可以使用ob_start和ob_end_clean. 如下: function print_header() { $o = "Site Log and Login links"; return $o; } function print_footer() { $o = "Site was made by me"; return $o; } echo print_header(); for($i = 0 ; $i '; } echo print_footer(); 为什么需要输出缓冲: >>可以在发送给浏览器前更改输出. 如 str_replaces 函数或可能是 preg_replaces 或添加些监控/调试的html内容. >>输出给浏览器的同时又做php的处理很糟糕. 你应该看到过有些站点的侧边栏或中间出现错误信息. 知道为什么会发生吗? 因为处理和输出混合了. 发送正确的mime类型头信息, 如果输出非html内容的话. 输出一些xml. $xml = ''; $xml = "0 "; //Send xml data echo $xml; 工作得不错. 但需要一些改进. $xml = ''; $xml = "0 "; //Send xml data header("content-type: text/xml"); echo $xml; 注意header行. 该行告知浏览器发送的是xml类型的内容. 所以浏览器能正确的处理. 很多的javascript库也依赖头信息. 类似的有 javascript , css, jpg image, png image: JavaScript header("content-type: application/x-javascript"); echo "var a = 10"; CSS header("content-type: text/css"); echo "#div id { background:#000; }"; 为mysql连接设置正确的字符编码 曾经遇到过在mysql表中设置了unicode/utf-8编码, phpadmin也能正确显示, 但当你获取内容并在页面输出的时候,会出现乱码. 这里的问题出在mysql连接的字符编码. //Attempt to connect to database $c = mysqli_connect($this->host , $this->username, $this->password); //Check connection validity if (!$c) { die ("Could not connect to the database host: ". mysqli_connect_error()); } //Set the character set of the connection if(!mysqli_set_charset ( $c , 'UTF8' )) { die('mysqli_set_charset() failed'); } 一旦连接数据库, 最好设置连接的 characterset. 你的应用如果要支持多语言, 这么做是必须的. 使用 htmlentities 设置正确的编码选项 php5.4前, 字符的默认编码是ISO-8859-1, 不能直接输出如À â等. $value = htmlentities($this->value , ENT_QUOTES , CHARSET); php5.4以后, 默认编码为UTF-8, 这將解决很多问题. 但如果你的应用是多语言的, 仍然要留意编码问题,. 不要在应用中使用gzip压缩输出, 让apache处理 考虑过使用 ob_gzhandler 吗? 不要那样做. 毫无意义. php只应用来编写应用. 不应操心服务器和浏览器的数据传输优化问题. 使用apache的mod_gzip/mod_deflate 模块压缩内容. 使用json_encode输出动态javascript内容 时常会用php输出动态javascript内容: $images = array( 'myself.png' , 'friends.png' , 'colleagues.png' ); $js_code = ''; foreach($images as $image) { $js_code .= "'$image' ,"; } $js_code = 'var images = [' . $js_code . ']; '; echo $js_code; //Output is var images = ['myself.png' ,'friends.png' ,'colleagues.png' ,]; 更聪明的做法, 使用 json_encode: $images = array( 'myself.png' , 'friends.png' , 'colleagues.png' ); $js_code = 'var images = ' . json_encode($images); echo $js_code; //Output is : var images = ["myself.png","friends.png","colleagues.png"] 优雅乎? 写文件前, 检查目录写权限 写或保存文件前, 确保目录是可写的, 假如不可写, 输出错误信息. 这会节约你很多调试时间. linux系统中, 需要处理权限, 目录权限不当会导致很多很多的问题, 文件也有可能无法读取等等. 确保你的应用足够智能, 输出某些重要信息. $contents = "All the content"; $file_path = "/var/www/project/content.txt"; file_put_contents($file_path , $contents); 这大体上正确. 但有些间接的问题. file_put_contents 可能会由于几个原因失败: >>父目录不存在 >>目录存在, 但不可写 >>文件被写锁住? 所以写文件前做明确的检查更好. $contents = "All the content"; $dir = '/var/www/project'; $file_path = $dir . "/content.txt"; if(is_writable($dir)) { file_put_contents($file_path , $contents); } else { die("Directory $dir is not writable, or does not exist. Please check"); } 这么做后, 你会得到一个文件在何处写及为什么失败的明确信息. 更改应用创建的文件权限 在linux环境中, 权限问题可能会浪费你很多时间. 从今往后, 无论何时, 当你创建一些文件后, 确保使用chmod设置正确权限. 否则的话, 可能文件先是由”php”用户创建, 但你用其它的用户登录工作, 系统將会拒绝访问或打开文件, 你不得不奋力获取root权限, 更改文件的权限等等. // Read and write for owner, read for everybody else chmod("/somedir/somefile", 0644); // Everything for owner, read and execute for others chmod("/somedir/somefile", 0755); 不要依赖submit按钮值来检查表单提交行为 if($_POST['submit'] == 'Save') { //Save the things } 上面大多数情况正确, 除了应用是多语言的. ‘Save’ 可能代表其它含义. 你怎么区分它们呢. 因此, 不要依赖于submit按钮的值. if( $_SERVER['REQUEST_METHOD'] == 'POST' and isset($_POST['submit']) ) { //Save the things } 现在你从submit按钮值中解脱出来了. 为函数内总具有相同值的变量定义成静态变量 //Delay for some time function delay() { $sync_delay = get_option('sync_delay'); echo "Delaying for $sync_delay seconds..."; sleep($sync_delay); echo "Done "; } 用静态变量取代: //Delay for some time function delay() { static $sync_delay = null; if($sync_delay == null) { $sync_delay = get_option('sync_delay'); } echo "Delaying for $sync_delay seconds..."; sleep($sync_delay); echo "Done "; } 不要直接使用 $_SESSION 变量 某些简单例子: $_SESSION['username'] = $username; $username = $_SESSION['username']; 这会导致某些问题. 如果在同个域名中运行了多个应用, session 变量可能会冲突. 两个不同的应用可能使用同一个session key. 例如, 一个前端门户, 和一个后台管理系统使用同一域名. 从现在开始, 使用应用相关的key和一个包装函数: define('APP_ID' , 'abc_corp_ecommerce'); //Function to get a session variable function session_get($key) { $k = APP_ID . '.' . $key; if(isset($_SESSION[$k])) { return $_SESSION[$k]; } return false; } //Function set the session variable function session_set($key , $value) { $k = APP_ID . '.' . $key; $_SESSION[$k] = $value; return true; } 將工具函数封装到类中 假如你在某文件中定义了很多工具函数: function utility_a() { //This function does a utility thing like string processing } function utility_b() { //This function does nother utility thing like database processing } function utility_c() { //This function is ... } 这些函数的使用分散到应用各处. 你可能想將他们封装到某个类中: class Utility { public static function utility_a() { } public static function utility_b() { } public static function utility_c() { } } //and call them as $a = Utility::utility_a(); $b = Utility::utility_b(); 显而易见的好处是, 如果php内建有同名的函数, 这样可以避免冲突. 另一种看法是, 你可以在同个应用中为同个类维护多个版本, 而不导致冲突. 这是封装的基本好处, 无它. Bunch of silly tips >>使用echo取代print >>使用str_replace取代preg_replace, 除非你绝对需要 >>不要使用 short tag >>简单字符串用单引号取代双引号 >>head重定向后记得使用exit >>不要在循环中调用函数 >>isset比strlen快 >>始中如一的格式化代码 >>不要删除循环或者if-else的括号 不要这样写代码: if($a == true) $a_count++; 这绝对WASTE. 写成: if($a == true) { $a_count++; } 不要尝试省略一些语法来缩短代码. 而是让你的逻辑简短. >>使用有高亮语法显示的文本编辑器. 高亮语法能让你减少错误. 使用array_map快速处理数组 比如说你想 trim 数组中的所有元素. 新手可能会: foreach($arr as $c => $v) { $arr[$c] = trim($v); } 但使用 array_map 更简单: $arr = array_map('trim' , $arr); 这会为$arr数组的每个元素都申请调用trim. 另一个类似的函数是 array_walk. 请查阅文档学习更多技巧. 使用 php filter 验证数据 你肯定曾使用过正则表达式验证 email , ip地址等. 是的,每个人都这么使用. 现在, 我们想做不同的尝试, 称为filter. php的filter扩展提供了简单的方式验证和检查输入. 强制类型检查 $amount = intval( $_GET['amount'] ); $rate = (int) $_GET['rate']; 这是个好习惯. 如果需要,使用profiler如xdebug 如果你使用php开发大型的应用, php承担了很多运算量, 速度会是一个很重要的指标. 使用profile帮助优化代码. 可使用 xdebug和webgrid. 小心处理大数组 对于大的数组和字符串, 必须小心处理. 常见错误是发生数组拷贝导致内存溢出,抛出Fatal Error of Memory size 信息: $db_records_in_array_format; //This is a big array holding 1000 rows from a table each having 20 columns , every row is atleast 100 bytes , so total 1000 * 20 * 100 = 2MB $cc = $db_records_in_array_format; //2MB more some_function($cc); //Another 2MB ? 当导入或导出csv文件时, 常常会这么做. 不要认为上面的代码会经常因内存限制导致脚本崩溃. 对于小的变量是没问题的, 但处理大数组的时候就必须避免. 确保通过引用传递, 或存储在类变量中: $a = get_large_array(); pass_to_function(&$a); 这么做后, 向函数传递变量引用(而不是拷贝数组). 查看文档. class A { function first() { $this->a = get_large_array(); $this->pass_to_function(); } function pass_to_function() { //process $this->a } } 尽快的 unset 它们, 让内存得以释放,减轻脚本负担. 由始至终使用单一数据库连接 确保你的脚本由始至终都使用单一的数据库连接. 在开始处正确的打开连接, 使用它直到结束, 最后关闭它. 不要像下面这样在函数中打开连接: function add_to_cart() { $db = new Database(); $db->query("INSERT INTO cart ....."); } function empty_cart() { $db = new Database(); $db->query("DELETE FROM cart ....."); } 使用多个连接是个糟糕的, 它们会拖慢应用, 因为创建连接需要时间和占用内存. 特定情况使用单例模式, 如数据库连接. 避免直接写SQL, 抽象之 不厌其烦的写了太多如下的语句: $query = "INSERT INTO users(name , email , address , phone) VALUES('$name' , '$email' , '$address' , '$phone')"; $db->query($query); //call to mysqli_query() 这不是个建壮的方案. 它有些缺点: >>每次都手动转义值 >>验证查询是否正确 >>查询的错误会花很长时间识别(除非每次都用if-else检查) >>很难维护复杂的查询 因此使用函数封装: function insert_record($table_name , $data) { foreach($data as $key => $value) { //mysqli_real_escape_string $data[$key] = $db->mres($value); } $fields = implode(',' , array_keys($data)); $values = "'" . implode("','" , array_values($data)) . "'"; //Final query $query = "INSERT INTO {$table}($fields) VALUES($values)"; return $db->query($query); } $data = array('name' => $name , 'email' => $email , 'address' => $address , 'phone' => $phone); insert_record('users' , $data); 看到了吗? 这样会更易读和扩展. record_data 函数小心的处理了转义. 最大的优点是数据被预处理为一个数组, 任何语法错误都会被捕获. 该函数应该定义在某个database类中, 你可以像 $db->insert_record这样调用. 查看本文, 看看怎样让你处理数据库更容易. 类似的也可以编写update,select,delete方法. 试试吧. 將数据库生成的内容缓存到静态文件中 如果所有的内容都是从数据库获取的, 它们应该被缓存. 一旦生成了, 就將它们保存在临时文件中. 下次请求该页面时, 可直接从缓存中取, 不用再查数据库. 好处: >>节约php处理页面的时间, 执行更快 >>更少的数据库查询意味着更少的mysql连接开销 在数据库中保存session 基于文件的session策略会有很多限制. 使用基于文件的session不能扩展到集群中, 因为session保存在单个服务器中. 但数据库可被多个服务器访问, 这样就可以解决问题. 在数据库中保存session数据, 还有更多好处: >>处理username重复登录问题. 同个username不能在两个地方同时登录. >>能更准备的查询在线用户状态. 避免使用全局变量 >>使用 defines/constants >>使用函数获取值 >>使用类并通过$this访问 在head中使用base标签 没听说过? 请看下面: <img alt="" data-original="happy.jpg" /> base 标签非常有用. 假设你的应用分成几个子目录, 它们都要包括相同的导航菜单. www.domain.com/store/home.php www.domain.com/store/products/ipad.php 在首页中, 可以写: <a href="home.php">Home</a> <a href="products/ipad.php">Ipad</a> 但在你的ipad.php不得不写成: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><a href="../home.php">Home</a> <a href="ipad.php">Ipad</a></span> 因为目录不一样. 有这么多不同版本的导航菜单要维护, 很糟糕啊. 因此, 请使用base标签. <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><head> <base href="http://www.domain.com/store/"> </head> <body> <a href="home.php">Home</a> <a href="products/ipad.php">Ipad</a> </body> </html></span> 现在, 这段代码放在应用的各个目录文件中行为都一致. 永远不要將 error_reporting 设为 0 关闭不相的错误报告. E_FATAL 错误是很重要的. ini_set('display_errors', 1); error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT); 注意平台体系结构 integer在32位和64位体系结构中长度是不同的. 因此某些函数如 strtotime 的行为会不同. 在64位的机器中, 你会看到如下的输出. $ php -a Interactive shell php > echo strtotime("0000-00-00 00:00:00"); -62170005200 php > echo strtotime('1000-01-30'); -30607739600 php > echo strtotime('2100-01-30'); 4104930600 但在32位机器中, 它们將是bool(false). 不要过分依赖 set_time_limit 如果你想限制最小时间, 可以使用下面的脚本: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">set_time_limit(30); //Rest of the code</span> 高枕无忧吗? 注意任何外部的执行, 如系统调用,socket操作, 数据库操作等, 就不在set_time_limits的控制之下. 因此, 就算数据库花费了很多时间查询, 脚本也不会停止执行. 视情况而定. 使用扩展库 一些例子: >>mPDF — 能通过html生成pdf文档 >>PHPExcel — 读写excel >>PhpMailer — 轻松处理发送包含附近的邮件 >>pChart — 使用php生成报表 使用开源库完成复杂任务, 如生成pdf, ms-excel文件, 报表等. 使用MVC框架 是时候使用像 codeigniter 这样的MVC框架了. MVC框架并不强迫你写面向对象的代码. 它们仅將php代码与html分离. >>明确区分php和html代码. 在团队协作中有好处, 设计师和程序员可以同时工作. >>面向对象设计的函数能让你更容易维护 >>内建函数完成了很多工作, 你不需要重复编写 >>开发大的应用是必须的 >>很多建议, 技巧和hack已被框架实现了 时常看看 phpbench phpbench 提供了些php基本操作的基准测试结果, 它展示了一些徽小的语法变化是怎样导致巨大差异的. 查看php站点的评论, 有问题到IRC提问, 时常阅读开源代码, 使用Linux开发. ====================================分割线================================文章转载自 开源中国社区[http://www.oschina.net]
文章
PHP  ·  数据库
2017-06-06
前端学习资料整理
前端思维导图js变量js运算符js数组js流程语句js字符串函数js函数基础jsdom操作js正则表达式js数据类型前端技术点总结:基础篇布局、自适应布局webpack、gulp了解的程度,平时怎么使用的,常用的属性css3动画padding 和 margin 的百分比是按照父元素的宽度来计算的(其实是看word-model,文字横向或竖向设置);git的使用情况 git checkout -b dev origin/dev前端的性能优化处理兼容性遇见过的问题如何居中div固定宽度 margin:0 auto绝对定位的div居中 transform利用 flex 布局调试技巧charles 抓包chrome://inspect如何解决跨域问题jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面Zepto的点透问题如何解决pointer-eventsfastclick其他的框架vue 什么是mvvm框架路由 vue-routerdisplay:none和visibility:hidden的区别display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间如果设计中使用了非标准的字体,你该如何去实现? 图片替代web : fonts在线字库@font-face 解释下浏览器是如何判断元素是否匹配某个 CSS 选择器?浏览器先产生一个元素集合,这个集合往往由最后一个部分的索引产生(如果没有索引就是所有元素的集合)。然后向上匹配,如果不符合上一个部分,就把元素从集合中删除,直到真个选择器都匹配完,还在集合中的元素就匹配这个选择器了 大体就是这样,不过浏览器还会有一些奇怪的优化。   * 为什么从后往前匹配因为效率和文档流的解析方向。效率不必说,找元素的父亲和之前的兄弟比遍历所有儿子快而且方便。关于文档流的解析方向,是因为现在的 CSS,一个元素只要确定了这个元素在文档流之前出现过的所有元素,就能确定他的匹配情况。应用在即使 html 没有载入完成,浏览器也能根据已经载入的这一部分信息完全确定出现过的元素的属性。   为什么是用集合主要也还是效率。基于 CSS Rule 数量远远小于元素数量的假设和索引的运用,遍历每一条 CSS Rule 通过集合筛选,比遍历每一个元素再遍历每一条 Rule 匹配要快得多。解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。从前端角度出发谈谈做好seo需要考虑什么?语义化html标签合理的title, description, keywords;重要的html代码放前面少用iframe, 搜索引擎不会抓取iframe中的内容图片加上alt请描述一下 cookies,sessionStorage 和 localStorage 的区别?cookiecookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。存储大小4kb;sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。存储大小cookie数据大小不能超过4k。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。有期时间 localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据sessionStorage 数据在当前浏览器窗口关闭后自动删除。cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭作用域不同sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。解释下事件代理事件委托利用了事件冒泡, 只指定一个事件处理程序, 就可以管理某一类型的所有事件.解释下js中this是怎么工作的?this 在 JavaScript 中主要由以下五种使用场景。作为函数调用,this 绑定全局对象,浏览器环境全局对象为 window 。内部函数内部函数的 this 也绑定全局对象,应该绑定到其外层函数对应的对象上,这是 JavaScript的缺陷,用that替换。作为构造函数使用,this 绑定到新创建的对象。作为对象方法使用,this 绑定到该对象。使用apply或call调用 this 将会被显式设置为函数调用的第一个参数。-webkit-tap-highlight-color: rgba(0, 0, 0, 0);取消掉手机端webkit浏览器 点击按钮或超链接之类的 默认灰色背景色设置css属性 -webkit-user-select:none; 控制用户不可选择文字js内存泄漏全局变量内存泄漏闭包引起内存泄漏dom清空或删除,事件未清除导致内存泄露原型及原型链每个函数里面都包含一个prototype属性,通过该属性可访问函数原型中的属性及方法,原型主要用于封装公有属性及方法。作用域及作用域链函数外部不能访问内部属性,函数内部未找到对应属性会逐层往外找。变量提升变量定义在后使用在前,会被自动定义到使用者之前,但是赋值不会提升。闭包是什么?为什么要使用闭包?有什么优缺点?js垃圾回收机制在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因事件绑定方法on,bind区别在于前者增加了代理绑定方法http的了解post与get 方式的区别post 用于数据提交,数据是放于包体内更安全;get 用于数据请求,数据是暴露在url后边的,不安全。https 协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。ES6新特性定义变量let(替换var),const(定义常量,不能改变值的变量),块级作用域,无变量提升;箭头函数,前边是参数,后边为函数处理逻辑;函数定义方法;类定义方法;继承实现extends;模块导入与导出;字符串模版;解构;默认参数(如果没有传这个参数,才会有默认值);代理proxy;import,export,export default(默认输出,一个模块只能有一个默认输出);symbol(独一无二的值),第7种数据类型(前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object));Generator 函数除了状态机,还是一个遍历器对象生成函数,框架篇是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield语句,定义不同的内部状态(yield在英语里的意思就是“产出”);promise 三个状态Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败);async 函数,使得异步操作变得更加方便;Decorator 修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。 在修饰器的基础上,可以实现Mixin模式。所谓Mixin模式,就是对象继承的一种替代方案,中文译为“混入”(mix in),意为在一个对象之中混入另外一个对象的方法vue框架vue 是一个轻量级的前端框架,其特性:双向绑定;模块化;虚拟dom;响应式;组件化;将注意力集中保持在核心库,有配套的路由和负责处理全局状态管理的库vue 生命周期钩子生命周期钩子包括created、beforeCompile、compiled、ready、beforeDestroy、destroyedvue 指令v-model 双向数据绑定v-on 事件绑定v-if 或者 v-show 条件判定v-for 输出列表该框架的特点:与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计 其它框架要解决的问题体现的思想同其他类型框架区别生命周期数据管理路由 reactReact(创建虚拟dom、给数据,挂载(生成真实dom),中间有数据更新,然后 销毁()、整个流程就是生命周期)React 的核心思想是:封装组件 各个组件维护自己的状态和 UI,当状态变更,自动重新渲染整个组件 基于这种方式的一个直观感受就是我们不再需要不厌其烦地来回查找某个 DOM 元素,然后操作 DOM 去更改 UIReact 大体包含下面这些概念组件React 应用都是构建在组件之上props 是组件包含的两个核心概念之一,另一个是 state(这个组件没用到)。可以把 props 看作是组件的配置属性,在组件内部是不变的,只是在调用这个组 件的时候传入不同的属性(比如这里的 name)来定制显示这个组件。生命周期函数装载组件触发componentWillMount(只会在装载之前调用一次,在 render 之前调用,你可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render)componentDidMount(只会在装载完成之后调用一次,在 render 之后调用,从这里开始可以通过 ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点)更新组件触发这些方法不会在首次 render 组件的周期调用componentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdate卸载组件触发componentWillUnmountDOM 操作当组件加载到页面上之后(mounted),你都可以通过 react-dom 提供的 findDOMNode() 方法拿到组件对应的 DOM 元素另外一种方式就是通过在要引用的 DOM 元素上面设置一个 ref 属性指定一个名称,然后通过 this.refs.name 来访问对应的 DOM 元素JSXReact 发明了 JSX 让 JS 支持嵌入 HTML 不得不说是一种非常聪明的做法,让前端实现真正意义上的组件化 成为了可能。JSX 是可选的可以直接用 React 提供的这些 DOM 构建方法来写模板在 JSX 里使用注释也很简单,就是沿用 JavaScript,唯一要注意的是在一个组件的子元素位置使用注释要 用 {} 包起来HTML 转义(React 会将所有要显示到 DOM 的字符串转义,防止 XSS。所以如果 JSX 中含有转义后的实体字符比如 © (©) 最后显示到 DOM 中不会正确显示,因为 React 自动把 © 中的特殊字符转义了。有几种解决办法)直接使用 UTF-8 字符 ©使用对应字符的 Unicode 编码,查询编码使用数组组装 {['cc ', ©, ' 2015']} 直接插入原始的 HTMLVirtual DOM当组件状态 state 有更改的时候,React 会自动调用组件的 render 方法重新渲染整个组件的 UI当然如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个Virtual DOM,组件 DOM 结构就是映射到这个 Virtual DOM 上,React 在这个 Virtual DOM 上实现了一个 diff 算法,当要重新渲染组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的 DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个 Virtual DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多。Data Flow“单向数据绑定”是 React 推崇的一种应用架构的方式。当应用足够复杂时才能体会到它的好处,虽然在一般应用场景下你可能不会意识到它的存在,也不会影响你开始使用 React,你只要先知道有这么个概念。nodejsnode即是一个运行环境又是一个组件库。angularMVC:Model(数据模型)-Control(业务逻辑和控制逻辑)-View(视图层),好处:将代码职责切分得很清晰,代码实现模块化,便于复用,像Model和View可以到处复用。 * 模块化:代码都挂载到module下 。指令系统:如ng-app\ng-model….就是指令,有自有指令,也可以自定义指令,如可以将一堆html标签定义为一个指令。双向数据绑定:当view视图上的数据发生变化时,它希望Model数据模型上的数据也立刻发生改变;当Model发生变化时,View视图会自动更新。前端开发知识点:HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:布局、盒子模型、选择器优先级、 HTML5、CSS3、FlexboxJavaScript: 数据类型、运算、对象、Function、继承、闭包、作用域、原型链、事件、RegExp、JSON、Ajax、 DOM、BOM、内存泄漏、跨域、异步装载、模板引擎、前端MVC、路由、模块化、Canvas、ECMAScript 6、Nodejs其他: 移动端、响应式、自动化构建、HTTP、离线存储、WEB安全、优化、重构、团队协作、可维护、易用性、SEO、UED、架构、职业生涯、快速学习能力作为一名前端工程师,无论工作年头长短都应该掌握的知识点:此条由 王子墨 发表在 攻城师的实验室1、DOM结构 —— 两个节点之间可能存在哪些关系以及如何在节点之间任意移动。2、DOM操作 ——如何添加、移除、移动、复制、创建和查找节点等。3、事件 —— 如何使用事件,以及IE和标准DOM事件模型之间存在的差别。4、XMLHttpRequest —— 这是什么、怎样完整地执行一次GET请求、怎样检测错误。5、严格模式与混杂模式 —— 如何触发这两种模式,区分它们有何意义。6、盒模型 —— 外边距、内边距和边框之间的关系,及IE8以下版本的浏览器中的盒模型7、块级元素与行内元素 —— 怎么用CSS控制它们、以及如何合理的使用它们8、浮动元素 ——怎么使用它们、它们有什么问题以及怎么解决这些问题。9、HTML与XHTML ——二者有什么区别,你觉得应该使用哪一个并说出理由。10、JSON —— 作用、用途、设计结构。备注:根据自己需要选择性阅读,面试题是对理论知识的总结,让自己学会应该如何表达。资料答案不够正确和全面,欢迎欢迎Star和提交issues。格式不断修改更新中。更新时间: 2015-10-9HTMLDoctype作用?标准模式与兼容模式各有什么区别?(1)、<!DOCTYPE>声明位于位于HTML文档中的第一行,处于 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。(2)、标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。HTML5 为什么只需要写 <!DOCTYPE HTML>?HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行);而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。行内元素有哪些?块级元素有哪些? 空(void)元素有那些?首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,如div的display默认值为“block”,则为“块级”元素;span默认display属性值为“inline”,是“行内”元素。(1)行内元素有:a b span img input select strong(强调的语气) (2)块级元素有:div ul ol li dl dt dd h1 h2 h3 h4…p(3)常见的空元素:   鲜为人知的是: 页面导入样式时,使用link和@import有什么区别?(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;介绍一下你对浏览器内核的理解?主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然 后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。 所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。JS引擎则:解析和执行javascript来实现网页的动态效果。最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。常见的浏览器内核有哪些?rident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML] Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等 Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;] Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]详细文章:浏览器内核的解析和对比html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?\HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。 绘画 canvas; 用于媒介回放的 video 和 audio 元素; 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失; sessionStorage 的数据在浏览器关闭后自动删除; 语意化更好的内容元素,比如 article、footer、header、nav、section; 表单控件,calendar、date、time、email、url、search; 新的技术webworker, websockt, Geolocation;移除的元素: 纯表现的元素:basefont,big,center,font, s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframes;支持HTML5新标签: IE8/IE7/IE6支持通过document.createElement方法产生的标签, 可以利用这一特性让这些浏览器支持HTML5新标签, 浏览器支持新标签后,还需要添加标签默认的样式。当然最好的方式是直接使用成熟的框架、比如html5shim;如何区分HTML5: DOCTYPE声明\新增的结构元素\功能元素简述一下你对HTML语义化的理解?用正确的标签做正确的事情。 html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析; 及时在没有样式CCS情况下也以一种文档格式显示,并且是容易阅读的; 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO; 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。HTML5的离线储存怎么使用,工作原理能不能解释一下?在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。 原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。如何使用: 1、页面头部像下面一样加入一个manifest的属性; 2、在cache.manifest文件的编写离线存储的资源; CACHE MANIFESTv0.11CACHE: js/app.js css/style.css NETWORK: resourse/logo.png FALLBACK: / /offline.html 3、在离线状态时,操作window.applicationCache进行需求实现。详细的使用请参考:有趣的HTML5:离线存储浏览器是怎么对HTML5的离线储存资源进行管理和加载的呢?在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。 离线的情况下,浏览器就直接使用离线存储的资源。 详细的使用请参考:有趣的HTML5:离线存储请描述一下 cookies,sessionStorage 和 localStorage 的区别?cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。 cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。 sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。存储大小: cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。有期时间: localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage 数据在当前浏览器窗口关闭后自动删除。 cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭iframe有那些缺点?*iframe会阻塞主页面的Onload事件; *搜索引擎的检索程序无法解读这种页面,不利于SEO;*iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript 动态给iframe添加src属性值,这样可以绕开以上两个问题。Label的作用是什么?是怎么用的?label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。Number: Date:HTML5的form如何关闭自动完成功能?给不想要提示的 form 或下某个input 设置为 autocomplete=off。如何实现浏览器内多个标签页之间的通信? (阿里)调用localstorge、cookies等本地存储方式webSocket如何兼容低浏览器?(阿里)Adobe Flash Socket 、 ActiveX HTMLFile (IE) 、 基于 multipart 编码发送 XHR 、 基于长轮询的 XHR页面可见性(Page Visibility)API 可以有哪些用途?在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放;如何在页面上实现一个圆形的可点击区域?1、map+area或者svg 2、border-radius 3、纯js实现 需要求一个点在不在圆上简单算法、获取鼠标坐标等等实现不使用 border 画出1px高的线,在不同浏览器的标准模式与怪异模式下都能保持一致的效果。网页验证码是干嘛的,是为了解决什么安全问题。区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水; 有效防止黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试;CSS介绍一下CSS的盒子模型?(1)有两种, IE 盒子模型、标准 W3C 盒子模型;IE的content部分包含了 border 和 pading;(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border).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 ;CSS优先级算法如何计算?优先级就近原则,同权重情况下样式定义最近者为准;载入样式以最后载入的定位为准;优先级为: !important > id > class > tag important 比 内联优先级高CSS3新增伪类有那些?CSS3新增伪类举例: p:first-of-type 选择属于其父元素的首个 元素的每个 元素。 p:last-of-type 选择属于其父元素的最后 元素的每个 元素。 p:only-of-type 选择属于其父元素唯一的 元素的每个 元素。 p:only-child 选择属于其父元素的唯一子元素的每个 元素。 p:nth-child(2) 选择属于其父元素的第二个子元素的每个 元素。 :enabled :disabled 控制表单控件的禁用状态。 :checked 单选框或复选框被选中。如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?给div设置一个宽度,然后添加margin:0 auto属性div{ width:200px; margin:0 auto; }居中一个浮动元素确定容器的宽高 宽500 高 300 的层 设置层的外边距.div { width:500px ; height:300px;//高度可以不设 margin: -150px 0 0 -250px; position:relative; //相对定位 //方便看效果 left:50%; top:50%; }让绝对定位的div居中position: absolute; width: 1200px; background: none; margin: 0 auto; top: 0; left: 0; bottom: 0; right: 0;display有哪些值?说明他们的作用。block 象块类型元素一样显示。 none 缺省值。象行内元素类型一样显示。 inline-block 象行内元素一样显示,但其内容象块类型元素一样显示。 list-item 象块类型元素一样显示,并添加样式列表标记。position的值relative和absolute定位原点是?absolute 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。fixed (老IE不支持) 生成绝对定位的元素,相对于浏览器窗口进行定位。relative 生成相对定位的元素,相对于其正常位置进行定位。static 默认值。没有定位,元素出现在正常的流中 (忽略 top, bottom, left, right z-index 声明)。inherit 规定从父元素继承 position 属性的值。CSS3有哪些新特性?CSS3实现圆角(border-radius:8px), 阴影(box-shadow:10px), 文字特效(text-shadow、), 线性渐变(gradient), 旋转(transform) transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,定位,倾斜 增加了更多的CSS选择器 多背景 rgba请解释一下CSS3的Flexbox(弹性盒布局模型),以及适用场景? 布局用来确定页面上不同组件和元素的尺寸和位置。随着响应式用户界面的流行,Web 应用一般都要求适配不同的设备尺寸和浏览器分辨率。 需要根据窗口尺寸来调整布局,从而改变组件的尺寸和位置,以达到最佳的显示效果用纯CSS创建一个三角形的原理是什么?把上、左、右三条边隐藏掉(颜色设为 transparent)demo {undefinedwidth: 0; height: 0; border-width: 20px; border-style: solid; border-color: transparent transparent red transparent; } - HTML如何获取浏览器的宽度? 目前来讲html不具备获取浏览器宽度的能力。可以采用js的方式来获取,具体示例JS代码如下: // 获取窗口宽度 if (window.innerWidth) winWidth = window.innerWidth; else if ((document.body) && (document.body.clientWidth)) winWidth = document.body.clientWidth; // 获取窗口高度 if (window.innerHeight) winHeight = window.innerHeight; else if ((document.body) && (document.body.clientHeight)) winHeight = document.body.clientHeight; // 通过深入 Document 内部对 body 进行检测,获取窗口大小 if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) { winHeight = document.documentElement.clientHeight; winWidth = document.documentElement.clientWidth; } jQuery 获取屏幕高度、宽度 做手机Web开发做浏览器兼容用到了,所以在网上找了些汇总下。 alert($(window).height()); //浏览器当前窗口可视区域高度 alert($(document).height()); //浏览器当前窗口文档的高度 alert($(document.body).height());//浏览器当前窗口文档body的高度 alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin alert($(window).width()); //浏览器当前窗口可视区域宽度 alert($(document).width());//浏览器当前窗口文档对象宽度 alert($(document.body).width());//浏览器当前窗口文档body的高度 alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin // 获取页面的高度、宽度 function getPageSize() { var xScroll, yScroll; if (window.innerHeight && window.scrollMaxY) { xScroll = window.innerWidth + window.scrollMaxX; yScroll = window.innerHeight + window.scrollMaxY; } else { if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac xScroll = document.body.scrollWidth; yScroll = document.body.scrollHeight; } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari xScroll = document.body.offsetWidth; yScroll = document.body.offsetHeight; } } var windowWidth, windowHeight; if (self.innerHeight) { // all except Explorer if (document.documentElement.clientWidth) { windowWidth = document.documentElement.clientWidth; } else { windowWidth = self.innerWidth; } windowHeight = self.innerHeight; } else { if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode windowWidth = document.documentElement.clientWidth; windowHeight = document.documentElement.clientHeight; } else { if (document.body) { // other Explorers windowWidth = document.body.clientWidth; windowHeight = document.body.clientHeight; } } } // for small pages with total height less then height of the viewport if (yScroll < windowHeight) { pageHeight = windowHeight; } else { pageHeight = yScroll; } // for small pages with total width less then width of the viewport if (xScroll < windowWidth) { pageWidth = xScroll; } else { pageWidth = windowWidth; } arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight); return arrayPageSize; }// 滚动条 document.body.scrollTop; $(document).scrollTop();一个满屏 品 字布局 如何设计?简单的方式: 上面的div宽100%, 下面的两个div分别宽50%, 然后用float或者inline使其不换行即可常见兼容性问题?png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。浮动ie产生的双倍距离 #box{ float:left; width:10px; margin:0 0 0 100px;}这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——display:inline;将其转化为行内属性。(这个符号只有ie6会识别)渐进识别的方式,从总体中逐渐排除局部。首先,巧妙的使用“\9”这一标记,将IE游览器从所有情况中分离出来。 接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。css .bb{ /所有识别/ .background-color:#00deff\9; /IE6、7、8识别/ +/IE6、7识别/ _background-color:#1e0bd1;/IE6识别/ }IE下,可以使用获取常规属性的方法来获取自定义属性, 也可以使用getAttribute()获取自定义属性; Firefox下,只能使用getAttribute()获取自定义属性。 解决方法:统一通过getAttribute()获取自定义属性。IE下,even对象有x,y属性,但是没有pageX,pageY属性; Firefox下,event对象有pageX,pageY属性,但是没有x,y属性。解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决。超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序: L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?li与li之间有看不见的空白。解决办法,可以设置浮动,不想浮动的话在ul用font-size:0去掉空白,像chrome不支持font-size:0的用letter-spacing:-3px这样的方式去掉li间的空白。经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用hack的技巧 ? http://www.cnblogs.com/lgmcolin/archive/2013/02/12/2910179.html http://www.duitang.com/static/csshack.html为什么要初始化CSS样式。因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。当然,初始化样式会对SEO有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。最简单的初始化方法: * {padding: 0; margin: 0;} (强烈不建议)淘宝的样式初始化代码: body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; } body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; } h1, h2, h3, h4, h5, h6{ font-size:100%; } address, cite, dfn, em, var { font-style:normal; } code, kbd, pre, samp { font-family:couriernew, courier, monospace; } small{ font-size:12px; } ul, ol { list-style:none; } a { text-decoration:none; } a:hover { text-decoration:underline; } sup { vertical-align:text-top; } sub{ vertical-align:text-bottom; } legend { color:#000; } fieldset, img { border:0; } button, input, select, textarea { font-size:100%; } table { border-collapse:collapse; border-spacing:0; }absolute的containing block(容器块)计算方式跟正常流有什么不同?无论属于哪种,都要先找到其祖先元素中最近的 position 值不为 static 的元素,然后再判断: 1、若此元素为 inline 元素,则 containing block 为能够包含这个元素生成的第一个和最后一个 inline box 的 padding box (除 margin, border 外的区域) 的最小矩形; 2、否则,则由这个祖先元素的 padding box 构成。 如果都找不到,则为 initial containing block。补充: 1. static(默认的)/relative:简单说就是它的父元素的内容框(即去掉padding的部分) 2. absolute: 向上找最近的定位为absolute/relative的元素 3. fixed: 它的containing block一律为根元素(html/body),根元素也是initial containing blockCSS里的visibility属性有个collapse属性值是干嘛用的?在不同浏览器下以后什么区别? visible: 设置对象可视 hidden: 设置对象隐藏 collapse: 主要用来隐藏表格的行或列。隐藏的行或列能够被其他内容使用。对于表格外的其他对象,其作用等同于hidden。IE6及以下不支持此参数值position跟display、margin collapse、overflow、float这些特性相互叠加后会怎么样? http://www.cnblogs.com/jackyWHJ/p/3756087.html对BFC规范(块级格式化上下文:block formatting context)的理解?(W3C CSS 2.1 规范中的一个概念,它是一个独立容器,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。) 一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染,也就是说BFC内部的元素和外部的元素不会互相影响。 - css定义的权重以下是权重的规则:标签的权重为1,class的权重为10,id的权重为100,以下例子是演示各种定义的权重值:/权重为1/ div{ } /权重为10/ .class1{ } /权重为100/id1{undefined} /权重为100+1=101/id1 div{undefined} /权重为10+1=11/ .class1 div{ } /权重为10+10+1=21/ .class1 .class2 div{ }如果权重相同,则最后定义的样式会起作用,但是应该避免这种情况出现请解释一下为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式移动端的布局用过媒体查询吗?使用 CSS 预处理器吗?喜欢那个?SASS (SASS、LESS没有本质区别,只因为团队前端都是用的SASS)CSS优化、提高性能的方法有哪些?浏览器是怎样解析CSS选择器的?在网页中的应该使用奇数还是偶数的字体?为什么呢? 偶数 更容易去其他设计构成比例margin和padding分别适合什么场景使用? 外边距 内间距抽离样式模块怎么写,说出思路,有无实践经验?[阿里航旅的面试题]元素竖向的百分比设定是相对于容器的高度吗? 这是一个很让人困惑的CSS特征,我之前也谈到过它。我们大家都知道,当按百分比设定一个元素的宽度时,它是相对于父容器的宽度计算的,但是,对于一些表示竖向距离的属性,例如padding-top,padding-bottom,margin-top,margin-bottom等,当按百分比设定它们时,依据的也是父容器的宽度,而不是高度。全屏滚动的原理是什么?用到了CSS的那些属性? 图片轮播原理,只不过图片宽高100%、超出隐藏、调整比例适应屏幕大小什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的IE?//- 视差滚动效果,如何给每页做不同的动画?(回到顶部,向下滑动要再次出现,和只出现一次分别怎么做?)::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个伪元素的作用。 单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。如何修改chrome记住密码后自动填充表单的黄色背景 ? 可以对input:-webkit-autofill使用足够大的纯色内阴影来覆盖input输入框的黄色背景;如:input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset; border: 1px solid #CCC!important; } 如果你有使用圆角等属性,或者发现输入框的长度高度不太对,可以对其进行调整,除了chrome默认定义的background-color,background-image,color不能用!important提升其优先级以外,其他的属性均可使用!important提升其优先级,如:input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset; border: 1px solid #CCC!important; height: 27px!important; line-height: 27px!important; border-radius: 0 4px 4px 0; }你对line-height是如何理解的? 基线位置是由字体确定的,css的line-height指的是一行字的高度,包含了字间距,实际上就是下一行的基线到上一行的基线距离。设置元素浮动后,该元素的display值是多少?(自动变成display:block)怎么让Chrome支持小于12px 的文字? .shrink{-webkit-transform:scale(0.8);-o-transform:scale(1); display:inline-block}让页面里的字体变清晰,变细用CSS怎么做?(-webkit-font-smoothing: antialiased;)font-style属性可以让它赋值为“oblique” oblique是什么意思? 可以理解成Italic是使用文字的斜体,Oblique是让没有斜体属性的文字倾斜position:fixed;在android下无效怎么处理?如果需要手动写动画,你认为最小时间间隔是多久,为什么?(阿里) 多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7msdisplay:inline-block 什么时候会显示间隙?(携程)移除空格、使用margin负值、使用font-size:0、letter-spacing、word-spacingoverflow: scroll时不能平滑滚动的问题怎么处理?有一个高度自适应的div,里面有两个div,一个高度100px,希望另一个填满剩下的高度。html, body { height: 100%; padding: 0; margin: 0; } .outer { height: 100%; padding: 100px 0 0; box-sizing: border-box ; position: relative; } .A { height: 100px; background: #BBE8F2; position: absolute; top: 0 ; left: 0 ; width: 100%; } .B { height: 100%; background: #D9C666; }png、jpg、gif 这些图片格式解释一下,分别什么时候用。有没有了解过webp? http://www.tuicool.com/articles/AbUvI3A什么是Cookie 隔离?(或者说:请求资源的时候不要让它带cookie怎么做)如果静态文件都放在主域名下,那静态文件请求的时候都带有的cookie的数据提交给server的,非常浪费流量, 所以不如隔离开。因为cookie有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有cookie数据, 这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。同时这种方式不会将cookie传入Web Server,也减少了Web Server对cookie的处理分析环节, 提高了webserver的http请求的解析速度。JavaScript介绍js的基本数据类型。Undefined、Null、Boolean、Number、String介绍js有哪些内置对象?Object 是 JavaScript 中所有对象的父对象数据封装类对象:Object、Array、Boolean、Number 和 String 其他对象:Function、Arguments、Math、Date、RegExp、Error说几条写JavaScript的基本规范?1.不要在同一行声明多个变量。 2.请使用 ===/!==来比较true/false或者数值 3.使用对象字面量替代new Array这种形式 4.不要使用全局函数。 5.Switch语句必须带有default分支 6.函数不应该有时候有返回值,有时候没有返回值。 7.For循环必须使用大括号 8.If语句必须使用大括号 9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。JavaScript原型,原型链 ? 有什么特点?每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时, 如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype, 于是就这样一直找下去,也就是我们平时所说的原型链的概念。 关系:instance.constructor.prototype = instance.proto特点: JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话, 就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。 function Func(){} Func.prototype.name = "Sean"; Func.prototype.getInfo = function() { return this.name; } var person = new Func();//现在可以参考var person = Object.create(oldObject); console.log(person.getInfo());//它拥有了Func的属性和方法 //"Sean" console.log(Func.prototype); // Func { name="Sean", getInfo=function()}JavaScript有几种类型的值?,你能画一下他们的内存图吗?堆:原始数据类型(Undefined,Null,Boolean,Number、String) 栈:引用数据类型(对象、数组和函数)两种类型的区别是:存储位置不同; 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储; 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其 在栈中的地址,取得地址后从堆中获得实体​Javascript如何实现继承?1、构造继承 2、原型继承 3、实例继承 4、拷贝继承原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。function Parent(){ this.name = 'wang'; }function Child(){ this.age = 28; } Child.prototype = new Parent();//继承了Parent,通过原型var demo = new Child(); alert(demo.age); alert(demo.name);//得到被继承的属性 }javascript创建对象的几种方式?javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON;但写法有很多种,也能混合使用。1、对象字面量的方式person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};2、用function来模拟无参的构造函数function Person(){} var person=new Person();//定义一个function,如果使用new"实例化",该function可以看作是一个Class person.name="Mark"; person.age="25"; person.work=function(){ alert(person.name+" hello..."); } person.work();3、用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性)function Pet(name,age,hobby){ this.name=name;//this作用域:当前对象 this.age=age; this.hobby=hobby; this.eat=function(){ alert("我叫"+this.name+",我喜欢"+this.hobby+",是个程序员"); } } var maidou =new Pet("麦兜",25,"coding");//实例化、创建对象 maidou.eat();//调用eat方法4、用工厂方式来创建(内置对象)var wcDog =new Object(); wcDog.name="旺财"; wcDog.age=3; wcDog.work=function(){ alert("我是"+wcDog.name+",汪汪汪......"); } wcDog.work();5、用原型方式来创建function Dog(){undefined} Dog.prototype.name="旺财"; Dog.prototype.eat=function(){ alert(this.name+"是个吃货"); } var wangcai =new Dog(); wangcai.eat();5、用混合方式来创建function Car(name,price){ this.name=name; this.price=price; } Car.prototype.sell=function(){ alert("我是"+this.name+",我现在卖"+this.price+"万元"); } var camry =new Car("凯美瑞",27); camry.sell();Javascript作用链域?全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。 当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找, 直至全局函数,这种组织形式就是作用域链。谈谈This对象的理解。http://www.jb51.net/article/71155.htm不像C#,this一定是指向当前对象。 js的this指向是不确定的,也就是说是可以动态改变的。call/apply 就是用于改变this指向的函数,这样设计可以让代码更加灵活,复用性更高。this 一般情况下,都是指向函数的拥有者。在函数自执行里,this 指向的是 window 对象eval是做什么的?它的功能是把对应的字符串解析成JS代码并运行; 应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。什么是window对象? 什么是document对象?http://www.jb51.net/article/25826.htm [document对象]   该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。  属性   alinkColor 活动链接的颜色(ALINK)   anchor 一个HTMI锚点,使用标记创建(该属性本身也是一个对象)   anchors array 列出文档锚点对象的数组()(该属性本身也是一个对象)   bgColor 文档的背景颜色(BGCOLOR)   cookie 存储于cookie.txt文件内的一段信息,它是该文档对象的一个属性   fgColor 文档的文本颜色(标记里的TEXT特性)   form 文档中的一个窗体()(该属性本身也是一个对象)   forms anay 按照其出现在文档中的顺序列出窗体对象的一个数组(该属性本身也是一个对象)   lastModified 文档最后的修改日期   linkColor 文档的链接的颜色,即标记中的LINK特性(链接到用户没有观察到的文档)   link 文档中的一个 标记(该属性本身也是一个对象)   links array 文档中link对象的一个数组,按照它们出现在文档中的顺序排列(该属性本身也是一个对象)   location 当前显示文档的URL。用户不能改变document.location(因为这是当前显示文档的位置)。但是,可以改变window.location (用其它文档取代当前文档)window.location本身也是一个对象,而document.location不是对象   referrer 包含链接的文档的URL,用户单击该链接可到达当前文档   title 文档的标题((TITLE>)   vlinkColor 指向用户已观察过的文档的链接文本颜色,即标记的VLINK特性  方法   clear 清除指定文档的内容   close 关闭文档流   open 打开文档流   write 把文本写入文档   writeln 把文本写入文档,并以换行符结尾 [window对象]   它是一个顶层对象,而不是另一个对象的属性即浏览器的窗口。   属性  defaultStatus 缺省的状态条消息   document 当前显示的文档(该属性本身也是一个对象)   frame 窗口里的一个框架((FRAME>)(该属性本身也是一个对象)   frames array 列举窗口的框架对象的数组,按照这些对象在文档中出现的顺序列出(该属性本身也是一个对象)   history 窗口的历史列表(该属性本身也是一个对象)   length 窗口内的框架数   location 窗口所显示文档的完整(绝对)URL(该属性本身也是一个对象)不要把它与如document.location混淆,后者是当前显示文档的URL。用户可以改变window.location(用另一个文档取代当前文档),但却不能改变document.location(因为这是当前显示文档的位置)   name 窗口打开时,赋予该窗口的名字   opener 代表使用window.open打开当前窗口的脚本所在的窗口(这是Netscape Navigator 3.0beta 3所引入的一个新属性)   parent 包含当前框架的窗口的同义词。frame和window对象的一个属性   self 当前窗口或框架的同义词   status 状态条中的消息   top 包含当前框架的最顶层浏览器窗口的同义词   window 当前窗口或框架的同义词,与self相同   方法  alert() 打开一个Alert消息框   clearTimeout() 用来终止setTimeout方法的工作   close() 关闭窗口   confirm() 打开一个Confirm消息框,用户可以选择OK或Cancel,如果用户单击OK,该方法返回true,单击Cancel返回false   blur() 把焦点从指定窗口移开(这是Netscape Navigator 3.0 beta 3引入的新方法)   focus() 把指定的窗口带到前台(另一个新方法)   open() 打开一个新窗口   prompt() 打开一个Prompt对话框,用户可向该框键入文本,并把键入的文本返回到脚本   setTimeout() 等待一段指定的毫秒数时间,然后运行指令事件处理程序   事件处理程序   Onload() 页面载入时触发   Onunload() 页面关闭时触发null,undefined 的区别?null 表示一个对象被定义了,值为“空值”; undefined 表示不存在这个值。typeof undefined //"undefined" undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined; 例如变量被声明了,但没有赋值时,就等于undefinedtypeof null //"object" null : 是一个对象(空对象, 没有任何属性和方法); 例如作为函数的参数,表示该函数的参数不是对象;注意: 在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined再来一个例子:null Q:有张三这个人么? A:有! Q:张三有房子么? A:没有!undefined Q:有张三这个人么? A:没有!写一个通用的事件侦听器函数。// event(事件)工具集,来源:github.com/markyun markyun.Event = { // 页面加载完成后 readyEvent : function(fn) { if (fn==null) { fn=document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; } else { window.onload = function() { oldonload(); fn(); }; } }, // 视能力分别使用dom0||dom2||IE方式 来绑定事件 // 参数: 操作的元素,事件名称 ,事件处理程序 addEvent : function(element, type, handler) { if (element.addEventListener) { //事件类型、需要执行的函数、是否捕捉 element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); } else { element['on' + type] = handler; } }, // 移除事件 removeEvent : function(element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.datachEvent) { element.detachEvent('on' + type, handler); } else { element['on' + type] = null; } }, // 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获) stopPropagation : function(ev) { if (ev.stopPropagation) { ev.stopPropagation(); } else { ev.cancelBubble = true; } }, // 取消事件的默认行为 preventDefault : function(event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } }, // 获取事件目标 getTarget : function(event) { return event.target || event.srcElement; }, // 获取event对象的引用,取到事件的所有信息,确保随时能使用event; getEvent : function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while (c) { ev = c.arguments[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } return ev; } };["1", "2", "3"].map(parseInt) 答案是多少?[1, NaN, NaN] 因为 parseInt 需要两个参数 (val, radix), 其中 radix 表示解析时用的基数。 map 传了 3 个 (element, index, array),对应的 radix 不合法导致解析失败。事件是?IE与火狐的事件机制有什么区别? 如何阻止冒泡?我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。事件处理机制:IE是事件冒泡、Firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件;ev.stopPropagation();(旧ie的方法 ev.cancelBubble = true;)什么是闭包(closure),为什么要用它?闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。闭包的特性:1.函数内再嵌套函数 2.内部函数可以引用外层的参数和变量 3.参数和变量不会被垃圾回收机制回收//li节点的onclick事件都能正确的弹出当前被点击的li索引index = 0index = 1index = 2index = 3执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在 使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源 因为say667()的内部函数的执行需要依赖say667()中的变量 这是对闭包作用的非常直白的描述function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; }var sayAlert = say667(); sayAlert()//执行结果应该弹出的667javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。 默认支持的糟糕特性都会被禁用,比如不能用with,也不能在意外的情况下给全局变量赋值; 全局变量的显示声明,函数必须声明在顶层,不允许在非函数代码块内声明函数,arguments.callee也不允许使用; 消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改,严格模式下的eval函数的行为和非严格模式的也不相同;提高编译器效率,增加运行速度; 为未来新版本的Javascript标准化做铺垫。如何判断一个对象是否属于某个类?使用instanceof (待完善) if(a instanceof Person){ alert('yes'); }new操作符具体干了什么呢?1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。 2、属性和方法被加入到 this 引用的对象中。 3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。var obj = {}; obj.proto = Base.prototype; Base.call(obj);用原生JavaScript的实现过什么功能吗? http://www.cnblogs.com/lhb25/p/you-might-not-need-jquery.htmlJavascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?hasOwnPropertyjavaScript中hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。 使用方法: object.hasOwnProperty(proName) 其中参数object是必选项。一个对象的实例。 proName是必选项。一个属性名称的字符串值。如果 object 具有指定名称的属性,那么JavaScript中hasOwnProperty函数方法返回 true,反之则返回 false。JSON 的了解?JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小 如:{"age":"12", "name":"back"}[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})能解释一下这段代码的意思吗? 这段代码只是首先获取了所有的页面元素,然后使用一个不同的颜色为它们添加了一个1ps的边框 http://sentsin.com/web/881.htmljs延迟加载的方式有哪些?defer和async、动态创建DOM方式(用得最多)、按需异步载入jsAjax 是什么? 如何创建一个Ajax?ajax的全称:Asynchronous Javascript And XML。 异步传输+js+xml。 所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象 (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息 (3)设置响应HTTP请求状态变化的函数 (4)发送HTTP请求 (5)获取异步调用返回的数据 (6)使用JavaScript和DOM实现局部刷新同步和异步的区别?同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,j进行下一步操作。异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。(待完善)如何解决跨域问题?http://blog.csdn.net/joyhen/article/details/21631833jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面页面编码和被请求的资源编码如果不一致如何处理? String str1 = new String(str.getBytes("你的编码方式"),"它的编码方式");模块化开发怎么做?立即执行函数,不暴露私有成员var module1 = (function(){     var _count = 0;     var m1 = function(){       //...     };     var m2 = function(){       //...     };     return {       m1 : m1,       m2 : m2     };   })();(待完善)AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?Asynchronous Module Definition,异步模块定义,所有的模块将被异步加载,模块加载不影响后面语句运行。所有依赖某些模块的语句均放置在回调函数中。区别:对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:// CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.doSomething() // ... })// AMD 默认推荐 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() // ... })requireJS的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何 缓存的?)谈一谈你对ECMAScript6的了解? http://www.oschina.net/news/71566/es6-developers-will-have-to-knowECMAScript6 怎么写class么,为什么会出现class这种东西?异步加载JS的方式有哪些?(1) defer,只支持IE(2) async:(3) 创建script,插入到DOM中,加载完毕后callBackdocumen.write和 innerHTML的区别document.write只能重绘整个页面innerHTML可以重绘页面的一部分DOM操作——怎样添加、移除、移动、复制、创建和查找节点?(1)创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 (2)添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子节点前插入一个新的子节点 (3)查找 getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的) getElementById() //通过元素Id,唯一性.call() 和 .apply() 的区别?例子中用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4);注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。function add(a,b) { alert(a+b); }function sub(a,b) { alert(a-b); }add.call(sub,3,1);数组和对象有哪些原生方法,列举一下?JS 怎么实现一个类。怎么实例化这个类 function Users(obj) { var name = obj.name; var age = obj.age; var addr = obj.addr; function User(name, age, addr) { this.name = name; this.age = age; this.addr = addr;} return new User(name, age, addr); }var x = Users({name:"user1", age:25, addr:"china"}); alert(x.name);JavaScript中的作用域与变量声明提升? http://blog.csdn.net/sunxing007/article/details/9034253如何编写高性能的Javascript? http://developer.51cto.com/art/200906/131335.htm那些操作会造成内存泄漏?http://www.ibm.com/developerworks/cn/web/wa-jsmemory/ 闭包 控制台日志 循环JQuery的源码看过吗?能不能简单概况一下它的实现原理?jQuery.fn的init方法返回的this指的是什么对象?为什么要返回this?jquery中如何将数组转化为json字符串,然后再转化回来? JSON.stringify 把一个对象转换成json字符串, JSON.parse 把一个json字符串解析成对象。jQuery 的属性拷贝(extend)的实现原理是什么,如何实现深拷贝?http://www.jb51.net/article/60689.htmjquery.extend 与 jquery.fn.extend的区别?http://www.jb51.net/article/60689.htm 一个用来扩展静态方法,一个用来扩展实例方法。jQuery 的队列是如何实现的?队列可以用在哪些地方?谈一下Jquery中的bind(),live(),delegate(),on()的区别? bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数 live(type,[data],fn) 给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的 delegate(selector,[type],[data],fn) 指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数 on(events,[selector],[data],fn) 在选择元素上绑定一个或多个事件的事件处理函数 差别:.bind()是直接绑定在元素上.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。和.bind()的优势是支持动态数据。.delegate()则是更精确的小范围使用事件代理,性能优于.live().on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制JQuery一个对象可以同时绑定多个事件,这是如何实现的? .bind()是直接绑定在元素上.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。和.bind()的优势是支持动态数据。.delegate()则是更精确的小范围使用事件代理,性能优于.live().on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制是否知道自定义事件。jQuery里的fire函数是什么意思,什么时候用?jQuery 是通过哪个方法和 Sizzle 选择器结合的? (jQuery.fn.find()进入Sizzle)针对 jQuery性能的优化方法? 1,总是从ID选择器开始继承 2,在class前使用tag(标签名) 3,将jQuery对象缓存起来 4,对直接的DOM操作进行限制 5,冒泡 6,推迟到 $(window).load 7,压缩JavaScript 8,尽量使用ID代替Class。 9,给选择器一个上下文 10,慎用 .live()方法(应该说尽量不要使用)Jquery与jQuery UI 有啥区别?*jQuery是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。*jQuery UI则是在jQuery的基础上,利用jQuery的扩展性,设计的插件。 提供了一些常用的界面元素,诸如对话框、拖动行为、改变大小行为等等jquery 中如何将数组转化为json字符串,然后再转化回来?jQuery中没有提供这个功能,所以你需要先编写两个jQuery的扩展:$.fn.stringifyArray = function(array) { return JSON.stringify(array) }$.fn.parseArray = function(array) { return JSON.parse(array) }然后调用: $("").stringifyArray(array)jQuery和Zepto的区别?各自的使用场景? zepto主要用在移动设备上,只支持较新的浏览器,好处是代码量比较小,性能也较好。 jquery主要是兼容性好,可以跑在各种pc,移动上,好处是兼容各种浏览器,缺点是代码量大,同时考虑兼容,性能也不够好。jq自身也注意到了这个总是,所有它的2.x版本是不支持ie6 7 8的,大致就是这些。针对 jQuery 的优化方法?*基于Class的选择性的性能相对于Id选择器开销很大,因为需遍历所有DOM元素。*频繁操作的DOM,先缓存起来再操作。用Jquery的链式调用更好。 比如:var str=$("a").attr("href");*for (var i = size; i < arr.length; i++) {} for 循环每一次循环都查找了数组 (arr) 的.length 属性,在开始循环的时候设置一个变量来存储这个数字,可以让循环跑得更快: for (var i = size, length = arr.length; i < length; i++) {}Zepto的点透问题如何解决? http://www.bubuko.com/infodetail-649496.htmljQueryUI如何自定义组件? http://bbs.chinaunix.net/linux/jqueryui.shtml需求:实现一个页面操作不会整页刷新的网站,并且能在浏览器前进、后退时正确响应。给出你的技术实现方案?如何判断当前脚本运行在浏览器还是node环境中?(阿里)通过判断Global对象是否为window,如果不为window,当前脚本没有运行在浏览器中移动端最小触控区域是多大?jQuery 的 slideUp动画 ,如果目标元素是被外部事件驱动, 当鼠标快速地连续触发外部元素事件, 动画会滞后的反复执行,该如何处理呢?把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们? 如下的经验规则: 1.当JavaScript要在页面加载过程中动态建立一些Web页面的内容时,应将JavaScript放在body中。 2.定义为函数并用于页面事件的JavaScript应当放在head标记中,因为它会在body之前加载。 采用这种方法,页面就不会被脚本搞得一团糟,易于阅读,在每个页面中,总可以在同一个位置找到脚本。移动端的点击事件的有延迟,时间是多久,为什么会有? 怎么解决这个延时?(click 有 300ms 延迟,为了实现safari的双击事件的设计,浏览器要知道你是不是要双击操作。)知道各种JS框架(Angular, Backbone, Ember, React, Meteor, Knockout...)么? 能讲出他们各自的优点和缺点么?Underscore 对哪些 JS 原生对象进行了扩展以及提供了哪些好用的函数方法?那些操作会造成内存泄漏?内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。 闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)Node.js的适用场景?(如果会用node)知道route, middleware, cluster, nodemon, pm2, server-side rendering么?解释一下 Backbone 的 MVC 实现方式?什么是“前端路由”?什么时候适合使用“前端路由”? “前端路由”有哪些优点和缺点?知道什么是webkit么? 知道怎么用浏览器的各种工具来调试和debug代码么? http://www.infoq.com/cn/articles/webkit-for-developers/ fierbug如何测试前端代码么? 知道BDD, TDD, Unit Test么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?前端templating(Mustache, underscore, handlebars)是干嘛的, 怎么用?简述一下 Handlebars 的基本用法?简述一下 Handlerbars 的对模板的基本处理流程, 如何编译的?如何缓存的?用js实现千位分隔符?(来源:前端农民工,提示:正则+replace)function commafy(num) { num = num + ''; var reg = /(-?d+)(d{3})/;if(reg.test(num)){ num = num.replace(reg, '$1,$2'); } return num; }检测浏览器版本版本有哪些方式?功能检测、userAgent特征检测比如:navigator.userAgent //"Mozilla/5.0 (Macintosh; Intel Mac OS X 10102) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"其他问题原来公司工作流程是怎么样的,如何与其他人协作的?如何夸部门合作的?你遇到过比较难的技术问题是?你是如何解决的?设计模式 知道什么是singleton, factory, strategy, decrator么?常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?页面重构怎么操作?网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。 也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。对于传统的网站来说重构通常是:表格(table)布局改为DIV+CSS 使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的) 对于移动平台的优化 针对于SEO进行优化 深层次的网站重构应该考虑的方面减少代码间的耦合 让代码保持弹性 严格按规范编写代码 设计可扩展的API 代替旧有的框架、语言(如VB) 增强用户体验 通常来说对于速度的优化也包含在重构中压缩JS、CSS、image等前端资源(通常是由服务器来解决) 程序的性能优化(如数据读写) 采用CDN来加速资源加载 对于JS DOM的优化 HTTP服务器的文件缓存列举IE与其他浏览器不一样的特性?1、事件不同之处:触发事件的元素被认为是目标(target)。而在 IE 中,目标包含在 event 对象的 srcElement 属性;获取字符代码、如果按键代表一个字符(shift、ctrl、alt除外),IE 的 keyCode 会返回字符代码(Unicode),DOM 中按键的代码和字符是分离的,要获取字符代码,需要使用 charCode 属性;阻止某个事件的默认行为,IE 中阻止某个事件的默认行为,必须将 returnValue 属性设置为 false,Mozilla 中,需要调用 preventDefault() 方法;停止事件冒泡,IE 中阻止事件进一步冒泡,需要设置 cancelBubble 为 true,Mozzilla 中,需要调用 stopPropagation();99%的网站都需要被重构是那本书上写的?网站重构:应用web标准进行设计(第2版)什么叫优雅降级和渐进增强?优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会针对旧版本的IE进行降级处理了,使之在旧式浏览器上以某种形式降级体验却不至于完全不能用。 如:border-shadow渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新版本浏览器才支持的功能,向页面增加不影响基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。 如:默认使用flash上传,但如果浏览器支持 HTML5 的文件上传功能,则使用HTML5实现更好的体验;是否了解公钥加密和私钥加密。一般情况下是指私钥用于对数据进行签名,公钥用于对签名进行验证; HTTP网站在浏览器端用公钥加密敏感数据,然后在服务器端再用私钥解密。WEB应用从服务器主动推送Data到客户端有那些方式?html5提供的Websocket 不可见的iframe WebSocket通过Flash XHR长时间连接 XHR Multipart Streaming
文章
存储  ·  Web App开发  ·  移动开发  ·  JSON  ·  缓存  ·  JavaScript  ·  前端开发  ·  数据格式  ·  HTML5  ·  容器
2022-01-08
提高PHP代码质量36计
原文地址:http://developer.51cto.com/art/201204/327561.htm 1.不要使用相对路径 常常会看到:  require_once('../../lib/some_class.php');  该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会检查过多路径. 如果该脚本被另一目录的脚本包含, 它的基本目录变成了另一脚本所在的目录. 另一问题, 当定时任务运行该脚本, 它的上级目录可能就不是工作目录了. 因此最佳选择是使用绝对路径: define('ROOT' , '/var/www/project/');   require_once(ROOT . '../../lib/some_class.php');     //rest of the code  我们定义了一个绝对路径, 值被写死了. 我们还可以改进它. 路径 /var/www/project 也可能会改变, 那么我们每次都要改变它吗? 不是的, 我们可以使用__FILE__常量, 如:  //suppose your script is /var/www/project/index.php   //Then __FILE__ will always have that full path.     define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME));   require_once(ROOT . '../../lib/some_class.php');     //rest of the code  现在, 无论你移到哪个目录, 如移到一个外网的服务器上, 代码无须更改便可正确运行. 2. 不要直接使用 require, include, include_once, required_once 可以在脚本头部引入多个文件, 像类库, 工具文件和助手函数等, 如:  require_once('lib/Database.php');   require_once('lib/Mail.php');     require_once('helpers/utitlity_functions.php');  这种用法相当原始. 应该更灵活点. 应编写个助手函数包含文件. 例如: function load_class($class_name)   {       //path to the class file       $path = ROOT . '/lib/' . $class_name . '.php');       require_once( $path );   }     load_class('Database');   load_class('Mail');  有什么不一样吗? 该代码更具可读性. 將来你可以按需扩展该函数, 如: function load_class($class_name)   {       //path to the class file       $path = ROOT . '/lib/' . $class_name . '.php');         if(file_exists($path))       {           require_once( $path );       }   }  还可做得更多: 为同样文件查找多个目录 能很容易的改变放置类文件的目录, 无须在代码各处一一修改 可使用类似的函数加载文件, 如html内容. 3. 为应用保留调试代码 在开发环境中, 我们打印数据库查询语句, 转存有问题的变量值, 而一旦问题解决, 我们注释或删除它们. 然而更好的做法是保留调试代码. 在开发环境中, 你可以: define('ENVIRONMENT' , 'development');     if(! $db->query( $query )   {       if(ENVIRONMENT == 'development')       {           echo "$query failed";       }       else      {           echo "Database error. Please contact administrator";       }   }  在服务器中, 你可以: define('ENVIRONMENT' , 'production');     if(! $db->query( $query )   {       if(ENVIRONMENT == 'development')       {           echo "$query failed";       }       else      {           echo "Database error. Please contact administrator";       }   }  4. 使用可跨平台的函数执行命令 system, exec, passthru, shell_exec 这4个函数可用于执行系统命令. 每个的行为都有细微差别. 问题在于, 当在共享主机中, 某些函数可能被选择性的禁用. 大多数新手趋于每次首先检查哪个函数可用, 然而再使用它. 更好的方案是封成函数一个可跨平台的函数.  /**       Method to execute a command in the terminal       Uses :         1. system       2. passthru       3. exec       4. shell_exec     */  function terminal($command)   {       //system       if(function_exists('system'))       {           ob_start();           system($command , $return_var);           $output = ob_get_contents();           ob_end_clean();       }       //passthru       else if(function_exists('passthru'))       {           ob_start();           passthru($command , $return_var);           $output = ob_get_contents();           ob_end_clean();       }         //exec       else if(function_exists('exec'))       {           exec($command , $output , $return_var);           $output = implode("\n" , $output);       }         //shell_exec       else if(function_exists('shell_exec'))       {           $output = shell_exec($command) ;       }         else      {           $output = 'Command execution not possible on this system';           $return_var = 1;       }         return array('output' => $output , 'status' => $return_var);   }     terminal('ls');  上面的函数將运行shell命令, 只要有一个系统函数可用, 这保持了代码的一致性.  5. 灵活编写函数 function add_to_cart($item_id , $qty) { $_SESSION['cart']['item_id'] = $qty; } add_to_cart( 'IPHONE3' , 2 ); 使用上面的函数添加单个项目. 而当添加项列表的时候,你要创建另一个函数吗? 不用, 只要稍加留意不同类型的参数, 就会更灵活. 如: function add_to_cart($item_id , $qty)   {       if(!is_array($item_id))       {           $_SESSION['cart']['item_id'] = $qty;       }         else      {           foreach($item_id as $i_id => $qty)           {               $_SESSION['cart']['i_id'] = $qty;           }       }   }     add_to_cart( 'IPHONE3' , 2 );   add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) );  现在, 同个函数可以处理不同类型的输入参数了. 可以参照上面的例子重构你的多处代码, 使其更智能. 6. 有意忽略php关闭标签 我很想知道为什么这么多关于php建议的博客文章都没提到这点. <?php     echo "Hello";     //Now dont close this tag  这將节约你很多时间. 我们举个例子: 一个 super_class.php 文件 <?php   class super_class   {       function super_function()       {           //super code       }   }   ?>   //super extra character after the closing tag  index.php require_once('super_class.php');     //echo an image or pdf , or set the cookies or session data  这样, 你將会得到一个 Headers already send error. 为什么? 因为 “super extra character” 已经被输出了. 现在你得开始调试啦. 这会花费大量时间寻找 super extra 的位置. 因此, 养成省略关闭符的习惯: <?php   class super_class   {       function super_function()       {           //super code       }   }     //No closing tag  这会更好.  7. 在某地方收集所有输入, 一次输出给浏览器 这称为输出缓冲, 假如说你已在不同的函数输出内容: function print_header()   {       echo "<div id='header'>Site Log and Login links</div>";   }     function print_footer()   {       echo "<div id='footer'>Site was made by me</div>";   }     print_header();   for($i = 0 ; $i < 100; $i++)   {       echo "I is : $i <br />';   }   print_footer();  替代方案, 在某地方集中收集输出. 你可以存储在函数的局部变量中, 也可以使用ob_start和ob_end_clean. 如下: function print_header()   {       $o = "<div id='header'>Site Log and Login links</div>";       return $o;   }     function print_footer()   {       $o = "<div id='footer'>Site was made by me</div>";       return $o;   }     echo print_header();   for($i = 0 ; $i < 100; $i++)   {       echo "I is : $i <br />';   }   echo print_footer();  为什么需要输出缓冲: >>可以在发送给浏览器前更改输出. 如 str_replaces 函数或可能是 preg_replaces 或添加些监控/调试的html内容. >>输出给浏览器的同时又做php的处理很糟糕. 你应该看到过有些站点的侧边栏或中间出现错误信息. 知道为什么会发生吗? 因为处理和输出混合了. 8. 发送正确的mime类型头信息, 如果输出非html内容的话. 输出一些xml. $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';   $xml = "<response>     <code>0</code>   </response>";     //Send xml data   echo $xml;  工作得不错. 但需要一些改进. $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';   $xml = "<response>     <code>0</code>   </response>";     //Send xml data   header("content-type: text/xml");   echo $xml;  注意header行. 该行告知浏览器发送的是xml类型的内容. 所以浏览器能正确的处理. 很多的javascript库也依赖头信息. 类似的有 javascript , css, jpg image, png image: JavaScript header("content-type: application/x-javascript");   echo "var a = 10";  CSS header("content-type: text/css");   echo "#div id { background:#000; }";  9. 为mysql连接设置正确的字符编码 曾经遇到过在mysql表中设置了unicode/utf-8编码,  phpadmin也能正确显示, 但当你获取内容并在页面输出的时候,会出现乱码. 这里的问题出在mysql连接的字符编码. //Attempt to connect to database   $c = mysqli_connect($this->host , $this->username, $this->password);     //Check connection validity   if (!$c)    {       die ("Could not connect to the database host: <br />". mysqli_connect_error());   }     //Set the character set of the connection   if(!mysqli_set_charset ( $c , 'UTF8' ))   {       die('mysqli_set_charset() failed');   }  一旦连接数据库, 最好设置连接的 characterset. 你的应用如果要支持多语言, 这么做是必须的. 10. 使用 htmlentities 设置正确的编码选项 php5.4前, 字符的默认编码是ISO-8859-1, 不能直接输出如À â等. $value = htmlentities($this->value , ENT_QUOTES , CHARSET);  php5.4以后, 默认编码为UTF-8, 这將解决很多问题. 但如果你的应用是多语言的, 仍然要留意编码问题,. 11. 不要在应用中使用gzip压缩输出, 让apache处理 考虑过使用 ob_gzhandler 吗? 不要那样做. 毫无意义. php只应用来编写应用. 不应操心服务器和浏览器的数据传输优化问题. 使用apache的mod_gzip/mod_deflate 模块压缩内容. 12. 使用json_encode输出动态javascript内容 时常会用php输出动态javascript内容: $images = array(    'myself.png' , 'friends.png' , 'colleagues.png'  );     $js_code = '';     foreach($images as $image)   {   $js_code .= "'$image' ,";   }     $js_code = 'var images = [' . $js_code . ']; ';     echo $js_code;     //Output is var images = ['myself.png' ,'friends.png' ,'colleagues.png' ,];  更聪明的做法, 使用 json_encode: $images = array(    'myself.png' , 'friends.png' , 'colleagues.png'  );     $js_code = 'var images = ' . json_encode($images);     echo $js_code;     //Output is : var images = ["myself.png","friends.png","colleagues.png"]  优雅乎? 13. 写文件前, 检查目录写权限 写或保存文件前, 确保目录是可写的, 假如不可写, 输出错误信息. 这会节约你很多调试时间. linux系统中, 需要处理权限, 目录权限不当会导致很多很多的问题, 文件也有可能无法读取等等. 确保你的应用足够智能, 输出某些重要信息. $contents = "All the content";   $file_path = "/var/www/project/content.txt";     file_put_contents($file_path , $contents);  这大体上正确. 但有些间接的问题. file_put_contents 可能会由于几个原因失败: >>父目录不存在 >>目录存在, 但不可写 >>文件被写锁住? 所以写文件前做明确的检查更好. $contents = "All the content";   $dir = '/var/www/project';   $file_path = $dir . "/content.txt";     if(is_writable($dir))   {       file_put_contents($file_path , $contents);   }   else  {       die("Directory $dir is not writable, or does not exist. Please check");   }  这么做后, 你会得到一个文件在何处写及为什么失败的明确信息. 14. 更改应用创建的文件权限 在 linux环境中, 权限问题可能会浪费你很多时间. 从今往后, 无论何时, 当你创建一些文件后, 确保使用chmod设置正确权限. 否则的话, 可能文件先是由"php"用户创建, 但你用其它的用户登录工作, 系统將会拒绝访问或打开文件, 你不得不奋力获取root权限,  更改文件的权限等等. // Read and write for owner, read for everybody else   chmod("/somedir/somefile", 0644);     // Everything for owner, read and execute for others   chmod("/somedir/somefile", 0755);  15. 不要依赖submit按钮值来检查表单提交行为 if($_POST['submit'] == 'Save')   {       //Save the things   }  上面大多数情况正确, 除了应用是多语言的. 'Save' 可能代表其它含义. 你怎么区分它们呢. 因此, 不要依赖于submit按钮的值. if( $_SERVER['REQUEST_METHOD'] == 'POST' and isset($_POST['submit']) )   {       //Save the things   }  现在你从submit按钮值中解脱出来了. 16. 为函数内总具有相同值的变量定义成静态变量 //Delay for some time   function delay()   {       $sync_delay = get_option('sync_delay');         echo "<br />Delaying for $sync_delay seconds...";       sleep($sync_delay);       echo "Done <br />";   }  用静态变量取代: //Delay for some time   function delay()   {       static $sync_delay = null;         if($sync_delay == null)       {       $sync_delay = get_option('sync_delay');       }         echo "<br />Delaying for $sync_delay seconds...";       sleep($sync_delay);       echo "Done <br />";   }  17. 不要直接使用 $_SESSION 变量 $_SESSION['username'] = $username;   $username = $_SESSION['username'];  这会导致某些问题. 如果在同个域名中运行了多个应用, session 变量可能会冲突. 两个不同的应用可能使用同一个session key. 例如, 一个前端门户, 和一个后台管理系统使用同一域名. 从现在开始, 使用应用相关的key和一个包装函数: define('APP_ID' , 'abc_corp_ecommerce');     //Function to get a session variable   function session_get($key)   {       $k = APP_ID . '.' . $key;         if(isset($_SESSION[$k]))       {           return $_SESSION[$k];       }         return false;   }     //Function set the session variable   function session_set($key , $value)   {       $k = APP_ID . '.' . $key;       $_SESSION[$k] = $value;         return true;   }  18. 將工具函数封装到类中 假如你在某文件中定义了很多工具函数: function utility_a()   {       //This function does a utility thing like string processing   }     function utility_b()   {       //This function does nother utility thing like database processing   }     function utility_c()   {       //This function is ...   }  这些函数的使用分散到应用各处. 你可能想將他们封装到某个类中: class Utility   {       public static function utility_a()       {         }         public static function utility_b()       {         }         public static function utility_c()       {         }   }     //and call them as      $a = Utility::utility_a();   $b = Utility::utility_b();  显而易见的好处是, 如果php内建有同名的函数, 这样可以避免冲突. 另一种看法是, 你可以在同个应用中为同个类维护多个版本, 而不导致冲突. 这是封装的基本好处, 无它. 19. Bunch of silly tips  >>使用echo取代print >>使用str_replace取代preg_replace, 除非你绝对需要 >>不要使用 short tag >>简单字符串用单引号取代双引号 >>head重定向后记得使用exit >>不要在循环中调用函数 >>isset比strlen快 >>始中如一的格式化代码 >>不要删除循环或者if-else的括号 不要这样写代码: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">if($a == true) $a_count++;</span>  这绝对WASTE. 写成: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">if($a == true)   {       $a_count++;   }</span>  不要尝试省略一些语法来缩短代码. 而是让你的逻辑简短. >>使用有高亮语法显示的文本编辑器. 高亮语法能让你减少错误. 20. 使用array_map快速处理数组 比如说你想 trim 数组中的所有元素. 新手可能会: foreach($arr as $c => $v)   {       $arr[$c] = trim($v);   }  但使用 array_map 更简单: $arr = array_map('trim' , $arr);  这会为$arr数组的每个元素都申请调用trim. 另一个类似的函数是 array_walk. 请查阅文档学习更多技巧. 21. 使用 php filter 验证数据 你肯定曾使用过正则表达式验证 email , ip地址等. 是的,每个人都这么使用. 现在, 我们想做不同的尝试, 称为filter. php的filter扩展提供了简单的方式验证和检查输入. 22. 强制类型检查 $amount = intval( $_GET['amount'] );   $rate = (int) $_GET['rate'];  这是个好习惯. 23. 如果需要,使用profiler如xdebug 如果你使用php开发大型的应用, php承担了很多运算量, 速度会是一个很重要的指标. 使用profile帮助优化代码. 可使用 xdebug和webgrid. 24. 小心处理大数组 对于大的数组和字符串, 必须小心处理. 常见错误是发生数组拷贝导致内存溢出,抛出Fat $db_records_in_array_format; //This is a big array holding 1000 rows from a table each having 20 columns , every row is atleast 100 bytes , so total 1000 * 20 * 100 = 2MB     $cc = $db_records_in_array_format; //2MB more     some_function($cc); //Another 2MB ?  当导入或导出csv文件时, 常常会这么做. 不要认为上面的代码会经常因内存限制导致脚本崩溃. 对于小的变量是没问题的, 但处理大数组的时候就必须避免. 确保通过引用传递, 或存储在类变量中: $a = get_large_array();   pass_to_function(&$a);  这么做后,向函数传递变量引用(而不是拷贝数组). 查看文档. class A   {       function first()       {           $this->a = get_large_array();           $this->pass_to_function();       }         function pass_to_function()       {           //process $this->a       }   }  尽快的 unset 它们, 让内存得以释放,减轻脚本负担. 25.  由始至终使用单一数据库连接 确保你的脚本由始至终都使用单一的数据库连接. 在开始处正确的打开连接, 使用它直到结束, 最后关闭它. 不要像下面这样在函数中打开连接: function add_to_cart()   {       $db = new Database();       $db->query("INSERT INTO cart .....");   }     function empty_cart()   {       $db = new Database();       $db->query("DELETE FROM cart .....");   }  使用多个连接是个糟糕的, 它们会拖慢应用, 因为创建连接需要时间和占用内存. 特定情况使用单例模式, 如数据库连接. 26. 避免直接写SQL, 抽象之 不厌其烦的写了太多如下的语句: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">$query = "INSERT INTO users(name , email , address , phone) VALUES('$name' , '$email' , '$address' , '$phone')";   $db->query($query); //call to mysqli_query()</span>  这不是个建壮的方案. 它有些缺点: >>每次都手动转义值 >>验证查询是否正确 >>查询的错误会花很长时间识别(除非每次都用if-else检查) >>很难维护复杂的查询 因此使用函数封装: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">function insert_record($table_name , $data)   {       foreach($data as $key => $value)       {       //mysqli_real_escape_string           $data[$key] = $db->mres($value);       }         $fields = implode(',' , array_keys($data));       $values = "'" . implode("','" , array_values($data)) . "'";         //Final query       $query = "INSERT INTO {$table}($fields) VALUES($values)";         return $db->query($query);   }     $data = array('name' => $name , 'email' => $email  , 'address' => $address , 'phone' => $phone);     insert_record('users' , $data);</span>  看到了吗? 这样会更易读和扩展. record_data 函数小心的处理了转义.  最大的优点是数据被预处理为一个数组, 任何语法错误都会被捕获. 该函数应该定义在某个database类中, 你可以像 $db->insert_record这样调用. 查看本文, 看看怎样让你处理数据库更容易. 类似的也可以编写update,select,delete方法. 试试吧. 27. 將数据库生成的内容缓存到静态文件中 如果所有的内容都是从数据库获取的, 它们应该被缓存. 一旦生成了, 就將它们保存在临时文件中. 下次请求该页面时, 可直接从缓存中取, 不用再查数据库. 好处: >>节约php处理页面的时间, 执行更快 >>更少的数据库查询意味着更少的mysql连接开销 28. 在数据库中保存sessio- base 标签非常有用. 假设你的应用分成几个子目录, 它们都要包括相同的导航菜单. www.domain.com/store/home.php www.domain.com/store/products/ipad.php 在首页中, 可以写: <a href="home.php">Home</a>   <a href="products/ipad.php">Ipad</a>  但在你的ipad.php不得不写成: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><a href="../home.php">Home</a>   <a href="ipad.php">Ipad</a></span>  因为目录不一样. 有这么多不同版本的导航菜单要维护, 很糟糕啊.  因此, 请使用base标签. <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><head>   <base href="http://www.domain.com/store/">   </head>   <body>   <a href="home.php">Home</a>   <a href="products/ipad.php">Ipad</a>   </body>   </html></span>  现在, 这段代码放在应用的各个目录文件中行为都一致.  31. 永远不要將 error_reporting 设为 0 关闭不相的错误报告. E_FATAL 错误是很重要的.  <span style="color:#333333;font-family:'Helvetica, Arial, sans-serif';">ini_set('display_errors', 1);   error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT);</span>  32. 注意平台体系结构 integer在32位和64位体系结构中长度是不同的. 因此某些函数如 strtotime 的行为会不同. 在64位的机器中, 你会看到如下的输出. <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">$ php -a   Interactive shell     php > echo strtotime("0000-00-00 00:00:00");   -62170005200   php > echo strtotime('1000-01-30');   -30607739600   php > echo strtotime('2100-01-30');   4104930600</span>  但在32位机器中, 它们將是bool(false). 查看这里, 了解更多. 33. 不要过分依赖 set_time_limit 如果你想限制最小时间, 可以使用下面的脚本: <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">set_time_limit(30);     //Rest of the code</span>  高枕无忧吗?  注意任何外部的执行, 如系统调用,socket操作, 数据库操作等, 就不在set_time_limits的控制之下. 因此, 就算数据库花费了很多时间查询, 脚本也不会停止执行. 视情况而定. 34. 使用扩展库 一些例子: >>mPDF -- 能通过html生成pdf文档 >>PHPExcel -- 读写excel >>PhpMailer -- 轻松处理发送包含附近的邮件 >>pChart -- 使用php生成报表 使用开源库完成复杂任务, 如生成pdf, ms-excel文件, 报表等. 35. 使用MVC框架 是时候使用像 codeigniter 这样的MVC框架了. MVC框架并不强迫你写面向对象的代码. 它们仅將php代码与html分离. >>明确区分php和html代码. 在团队协作中有好处, 设计师和程序员可以同时工作. >>面向对象设计的函数能让你更容易维护 >>内建函数完成了很多工作, 你不需要重复编写 >>开发大的应用是必须的 >>很多建议, 技巧和hack已被框架实现了 36. 时常看看 phpbench  phpbench 提供了些php基本操作的基准测试结果, 它展示了一些徽小的语法变化是怎样导致巨大差异的. 查看php站点的评论, 有问题到IRC提问, 时常阅读开源代码, 使用Linux开发.  英文:http://www.binarytides.com/blog/35-techniques-to-enhance-your-php-code/ 原文链接:http://www.oschina.net/question/1579_47231
文章
XML  ·  前端开发  ·  PHP  ·  数据库  ·  数据格式
2012-08-07
浅析网络基础架构
背景由于平时倾向于关注业务层面的架构与技术,对网络基础架构上的知识了解不多,对其中很多知识点都是一知半解,甚至有些都没有听说过,比如AServer是什么?为什么会有AServer?它的原理是什么?等等,带着这些问题来浅析网络基础架构。看一次网络请求网络架构是为了服务网络请求的,那一次网络请求都发生了什么?先回顾一下OSI模型,自上向下分为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。主要过程先把主要过程呈现出来,然后再挨个看内部细节。1.URL解析一个合法的URL一定包含协议、域名等信息。如果我们经常访问一个网站,那么浏览器会缓存网站的相关信息。试着输入taobao,如果之前有访问过,那么浏览器会自动联想出 https://www.taobao.com。2.DNS解析DNS简单来说是将域名转为IP地址的映射服务,可以是1对多,顺序返回通常选择第一个。MAC查看DNS映射的命令是:cat /etc/resolv.conf说DNS解析之前得先说下IP地址,它为互联网上的每一个网络、主机分配一个逻辑地址,正如每台电脑都有自己的IP地址一样,服务器也同样如此。计算机在网络上进行通讯是基于TCP/IP协议的,只能识别如“114.114.114.114”之类的IP地址,并不认识域名,那为什么我们不直接通过IP地址来访问网络服务,减少一层DNS解析仿真速度不是更快吗?自己认为主要是两个原因:域名更具备可读性,试想一下如果访问网站都需要输一串数字,那将是多么痛苦的事情。域名提高了服务可用性,试想如果直接通过固定IP访问,一旦这个IP挂了,那服务将不可用,但是DNS可以根据探活机制动态更新IP列表,保证一定时间后故障IP会被下掉,客户端可以正常访问。解析顺序浏览器缓存操作系统缓存本地hosts文件缓存路由器缓存ISP DNS (DNS服务提供商)13个根域名服务器,.com -> .cn -> .net ...假设DNS服务器只有一个,那它将面临通信容量大、远距离网络延迟高、维护成本高、可靠性低等问题,所以DNS服务器采用分布式集群方式工作。服务器层次划分根服务器,根域名服务器是最高层次的域名服务器,所有的根域名服务器都知道所有顶级域名服务器的域名和ip。如果本地域名服务器没有缓存相应记录,首先会向根域名服务器发起请求。顶级域名服务器,顶级域名服务器管理在该顶级域名服务器注册的所有二级域名,但受到DNS查询就会有相应应答。(可能是给出最后的结果或下一步应当找的域名服务器ip)权威域名服务器,权威域名服务器是负责查询域名的解析设置,一般由域名解析服务商提供,权威域名服务器是直接对域名进行解析过程的。本地域名服务器,每一个因特网服务提供ISP(电信联通移动)都可以拥有一个本地域名服务器。这种服务器有时也被称为默认域名服务器。本地域名服务器一般离用户较近,一般不超过几个路由的距离。如果要查询的IP同属一个本地ISP时即可直接返回结果地址ip。域名的结构由标号序列组成,各标号之间用点隔开。类似于这样:“….三级域名.二级域名.顶级域名”。例如 https://www.taobao.com 中顶级域名:.com二级域名:taobao三级域名:www3.建立TCP连接HTTP请求为什么要用TCP协议建立连接?HTTP协议并没有明确要求必须使用TCP协议作为运输层协议,但是因为HTTP协议对可靠性的的要求,默认HTTP是基于TCP协议的。若是使用UDP这种不可靠的、尽最大努力交付的运输层协议来实现HTTP的话,那么TCP协议的流量控制、可靠性保障机制等等功能就必须全部放到应用层来实现。TCP 三次握手seq(序号):TCP连接字节流中每一个字节都会有一个编号,而本字段的值指的是本报文段所发送数据部分第一个字节的序号。ack(确认号):表示期望收到的下一个报文段数据部分的第一个字节的编号,编号为ack-1及以前的字节已经收到。SYN:当本字段为1时,表示这是一个连接请求或者连接接受报文。ACK:仅当本字段为1时,确认号才有效。连接建立阶段:第一次握手:客户端的应用进程主动打开,并向服务端发出请求报文段。其首部中:SYN=1,seq=x。第二次握手:服务器应用进程被动打开。若同意客户端的请求,则发回确认报文,其首部中:SYN=1,ACK=1,ack=x+1,seq=y。第三次握手:客户端收到确认报文之后,通知上层应用进程连接已建立,并向服务器发出确认报文,其首部:ACK=1,ack=y+1。当服务器收到客户端的确认报文之后,也通知其上层应用进程连接已建立。CLOSED:关闭状态、LISTEN:收听状态、SYN-SENT:同步已发送、SYN-RCVD:同步收到、ESTAB-LISHED:连接已建立4.服务器处理请求服务器处理请求场景比较多,这里只介绍一下常见的处理流程:请求静态资源(html, css, js, png...),服务器可能通过NGINX直接将请求转发到静态资源服务器。API请求,请求到达服务器后可能会经历:反序列化,参数校验,用户鉴权,模型转换,信息填充,持久化处理,result构造,返回响应等5.浏览器接受响应浏览器接受后端返回的响应,请求的具体响应信息可以通过F12查看,包括但不限于:Response header、Response Body、Timing、Cookies等6.渲染页面前端了解不多,这里为了内容完整稍做简述。前端文件主要分为四类:html:为前端页面的主体,由标签、指令与转义字符(实体)等组成,简单来说就是定义条条框框。css: 为前端页面的样式,由选择器、作用域与样式块组成,简单来说就是定义条条框框的样式,什么颜色,多少px等。js:为前端页面的脚本,由DOM、BOM与ES组成,简单来说就是定义条条框框里面显示的内容,以及如何获取。assets:前端资源,比如图片,文本等。渲染顺序:解析HTML解析CSS渲染doom树部署架构总览结构组成相关术语DS:Director Server,指的是负载均衡器节点,负责接收客户端请求,并转发给RS。RS:Real Server,处理实际请求的后端服务器节点。CIP:Client IP address,客户端的IP地址。VIP:Virtual IP address,DS用于和客户端通信的IP地址,作为客户端请求的目标IP地址。DIP:Directors IP address,DS用于和内部RS通信的IP地址。RIP:Real IP address,后端服务器的IP地址。看完部署架构组成,我们来浅析每个组成模块的作用,DNS已经介绍过了,从负载均衡开始吧。负载均衡(LB/SLB)服务负载均衡(Load Balance)是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。SLB(服务器负载均衡):在多个提供相同服务的服务器的情况下,负载均衡设备存在虚拟服务地址,当大量客户端从外部访问虚拟服务IP地址时,负载均衡设备将这些报文请求根据负载均衡算法,将流量均衡的分配给后台服务器以平衡各个服务器的负载压力,避免在还有服务器压力较小情况下其他服务达到性能临界点出现运行缓慢甚至宕机情况,从而提高服务效率和质量,因此对客户端而言,RS(real server 实际服务器)的IP地址即是负载均衡设备VIP(虚拟服务地址IP)地址,真正的RS服务器IP地址对于客户端是不可见的。为什么有LB没有LB的时候,用户直接访问服务器,存在两个问题:用户直接访问web 服务器,如果服务器宕机,那么用户将无法访问。用户和服务器是 N:1,如果某个时刻访问服务器的用户很多,超过服务器能处理的极限,就会出现加载速度缓慢或根本无法连接的情况。可以看到没有LB的情况下网络的可靠性不高。如果有多个服务器同时提供相同的服务能力,那是不是就可以解决上述问题?答案是是的,但是客户端同一时刻只能连接一台服务器,那么应该选择哪一台服务器呢?通过添加LB来解决这个问题,LB内部有负载均衡算法,可以动态的为客户端选择一台适合的服务器连接,不可用的服务器也将通过定时心跳检测从LB连接池中剔除掉,避免造成客户端错误连接,常用 IP + Port 的方式来实现。curl -i http://33.x.x.x:7002/appHealth/liveness如果访问的客户端数量太多LB也顶不住了怎么办?同样的加LB机器,LB集群也通过定时心跳检测来保证连接可用。LB分类二层负载均衡(mac)根据OSI模型分的二层负载,一般是用虚拟mac地址方式,外部对虚拟MAC地址请求,负载均衡接收后分配后端实际的MAC地址响应。三层负载均衡(ip)一般采用虚拟IP地址方式,外部对虚拟的ip地址请求,负载均衡接收后分配后端实际的IP地址响应。(即一个ip对一个ip的转发, 端口全放开)四层负载均衡(tcp)在三次负载均衡的基础上,即从第四层"传输层"开始, 使用"ip+port"接收请求,再转发到对应的机器。四层的负载均衡就是基于IP+端口的负载均衡:在三层负载均衡的基础上,通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。对应的负载均衡器称为四层交换机(L4 switch),主要分析IP层及TCP/UDP层,实现四层负载均衡。此种负载均衡器不理解应用协议(如HTTP/FTP/MySQL等等)。实现四层负载均衡的软件有:F5:硬件负载均衡器,功能很好,但是成本很高。lvs:重量级的四层负载软件nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活haproxy:模拟四层转发,较灵活七层负载均衡(http)七层的负载均衡就是基于虚拟的URL或主机IP的负载均衡:在四层负载均衡的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。对应的负载均衡器称为七层交换机(L7 switch),除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息,实现七层负载均衡。此种负载均衡器能理解应用协议。实现七层负载均衡的软件有:haproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移;nginx:只在http协议和mail协议上功能比较好,性能与haproxy差不多;apache:功能较差LVS(四层LB)基础概念一组服务器通过高速的局域网或者地理分布的广域网相互连接,在它们的前端有一个负载调度器(Load Balancer)。负载调度器能无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、高可用的服务器一样。客户程序不受服务器集群的影响不需作任何修改。系统的伸缩性通过在服务机群中透明地加入和删除一个节点来达到,通过检测节点或服务进程故障和正确地重置系统达到高可用性。由于我们的负载调度技术是在Linux内核中实现的,我们称之为Linux虚拟服务器(Linux Virtual Server)。LVS集群当单台LVS无法承载全部的负载均衡任务时,可以通过等价路由让多台LVS形成一个LVS集群,共同完成负载均衡的任务。LVS集群部署后需要前置引入交换机来做LVS集群的健康检查。LVS和交换机间运行OSPF协议,交换机通过ECMP等价路由,将请求分发给LVS集群。1个VIP配置在集群的所有LVS上,当一台LVS宕机后,交换机会自动发现并将其从ECMP等价路由中剔除。NGINX(七层LB)LVS只能实现对四层负载均衡,Nginx负载均衡既可以实现对四层的负载又可以实现对七层的负载,可以根据ip端口也可以根据应用名称来转发。首先用户发送请求首先会被转发到四层负载均衡上,因为访问网站都是基于域名加端口的,四层就满足了访问条件,然后在根据请求的内容转发到七层负载上,七层负载再根据请求的类型转发到不同的后端web集群,四层和七层也可以在一台服务器上,使用Nginx就可以实现这种架构。Nginx实现负载均衡需要两个模块proxy_pass代理模块upstream虚拟资源池模块如何使用可以看:https://www.nginx.com/resources/wiki/start/四层与七层的区别四层负载均衡:传输层优点:性能高,数据包在底层就进行了转发缺点:仅支持ip:prot转发,无法完成复杂的业务逻辑应用七层负载均衡︰应用层优点:贴近业务,支持URI路径匹配、Header改写、Rewrite等缺点:性能低,数据包需要拆解到顶层才进行转发负载均衡调度器在调度器的实现技术中,IP负载均衡技术是效率最高的。在已有的IP负载均衡技术中有通过网络地址转换(Network Address Translation)将一组服务器构成一个高性能的、高可用的虚拟服务器,我们称之为VS/NAT技术(Virtual Server via Network Address Translation),大多数商品化的IP负载均衡调度器产品都是使用此方法,如Cisco的LocalDirector、F5的Big/IP和 Alteon的ACEDirector。在分析VS/NAT的缺点和网络服务的非对称性的基础上,我们提出通过IP隧道实现虚拟服务器的方法VS/TUN (Virtual Server via IP Tunneling),和通过直接路由实现虚拟服务器的方法VS/DR(Virtual Server via Direct Routing),它们可以极大地提高系统的伸缩性。所以,IPVS软件实现了这三种IP负载均衡技术,它们的大致原理如下。NAT Virtual Server via Network Address Translation,通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程,过程如下图所示:发送进行SNAT,接收进行DNAT:Client -> Server的包: DNAT, 修改desination IPServer -> Client的包: SNAT, 修改source IPFNAT与NAT不同的,Full NAT发送和接收都会进行SNAT和DNAT:Client -> Server的包: DNAT + SNAT, 修改desination IP和source IPServer -> Client的包: DNAT + SNAT, 修改desination IP和source IPTUNVirtual Server via IP Tunneling,采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报 文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 TUN技术后,集群系统的最大吞吐量可以提高10倍。TUN模式中,DS和RS必须支持“IP Tunneling”或者“IP Encapsulation”协议DRVirtual Server via Direct Routing,VS/DR通过改写请求报文的MAC地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同TUN技术一样,DR技术可极大地 提高集群系统的伸缩性。这种方法没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连 在同一物理网段上。LB算法有了LB后客户端和服务器之前的关系由 N:1 变为 N:N,如何选择一台合适的服务器来承接客户端请求至关重要,如果选择得不好就会造成“旱的旱死,涝的涝死”等现象,流量配比、服务器性能、应用场景等都是影响LB算法的重要因素。轮叫(Round Robin)调度器通过"轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。加权轮叫(Weighted Round Robin)调度器通过"加权轮叫"调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。最少链接(Least Connections)调度器通过"最少连接"调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用"最小连接"调度算法可以较好地均衡负载。加权最少链接(Weighted Least Connections)在集群系统中的服务器性能差异较大的情况下,调度器采用"加权最少链接"调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。基于局部性的最少链接(Locality-Based Least Connections)"基于局部性的最少链接" 调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器 是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用"最少链接"的原则选出一个可用的服务器,将请求发送到该服务器。带复制的基于局部性最少链接(Locality-Based Least Connections with Replication)"带复制的基于局部性最少链接"调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个 目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务 器组,按"最小连接"原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器,若服务器超载;则按"最小连接"原则从这个集群中选出一 台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的 程度。目标地址散列(Destination Hashing)"目标地址散列"调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。源地址散列(Source Hashing)"源地址散列"调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。统一接入层(AServer)业务接入AServer之前,外部请求是通过LVS集群转发给业务集群。接入Aserver之后,所有外部请求都先通过LVS集群转发到Aserver,然后Aserver再转发给业务集群,那为什么业务应用需要接入AServer?所有Https应用都涉及到ssl证书,Aserver就是为了解决海量证书维护问题。外部流量都统一到AServer之后,AServer就必须解决这样一个问题:如何将外部请求正确地转发给对应的业务集群?VIPServerVIPServer通过管理应用的VIP table信息,提供软负载的能力,实现应用间直连交互。那有了VIPServer之后有什么好处呢?没有VIPServer假设现在有两个,分别是A/B,都是集群部署的,在没有VIPServer的时候,应用A要访问应用B需要经过LVS找到应用B的某个VIP,这时候LVS相当于网关,当请求量过大的时候LVS存在性能瓶颈。有VIPServer接入VIPServer后,应用B上线时会将自己的VIP列表注册到VIPServer,当应用A要访问应用B时会从VIPServer中找一个应用B的VIP,然后以直连的方式与应用B交互,可以看到VIPServer只起到服务发现的作用,处于旁路位置,并不作为网关。Nginx有了VIPServer就能解决服务发现的问题,Nginx服务流量的代理与转发。密钥中心负责密钥的存储、使用、分发、更新等,并提供数据加密解密、签名验签 API。在统一接入时主要负责证书的验证。附录缩写IDC: Internet Data Center 互联网数据中心,简称IDC机房。用来存放服务器的地方,是实体服务器的集群。AServer:阿里统一接入参考DNS相关IP地址:https://baike.baidu.com/item/IP%E5%9C%B0%E5%9D%80/150859DNS解析:https://www.zhihu.com/question/23042131DNS服务器:https://zhuanlan.zhihu.com/p/38282917TCP三次握手:https://zhuanlan.zhihu.com/p/24860403TCP报文缩写:https://www.kvkft.com/info/syn%E6%8A%A5%E6%96%87%E5%85%A8%E7%A7%B0.htmlLBLinux服务器集群系统(一):http://www.linuxvirtualserver.org/zh/lvs1.htmlLVS负载均衡原理:https://www.cnblogs.com/zhangxingeng/p/10497279.htmllinux负载均衡总结性说明(四层负载/七层负载):https://www.cnblogs.com/kevingrace/p/6137881.html
文章
缓存  ·  负载均衡  ·  网络协议  ·  算法  ·  前端开发  ·  应用服务中间件  ·  Linux  ·  调度  ·  nginx  ·  C++
2022-05-17
PHP&Javascript&CSS&jQuery常用知识大全(整理+原创)
---------------------------------------------------------                      PHP知识大全 --------------------------------------------------------- 1. 变量如何定义?如何检查变量是否定义?如何删除一个变量?怎样检测变量是否设置?        $定义   isset()// 检测变量是否设置         defined()// 检测常量是否设置        unset()//销毁指定的变量        empty()// 检测变量是否为空   2. 什么是可变变量?        一个变量的变量名可以动态的设置和使用。        $a = 'hello' , $$a = 'world',  ${$a}=hello world   3. 变量赋值方式有哪几种?        1)直接赋值   2)变量间赋值   3)引用赋值   4. 引用和拷贝有什么区别?        拷贝是将原来的变量内容复制下来,拷贝后的变量与原来的变量使用各自的内存,互不干扰。        引用相当于是变量的别名,其实就是用不同的名字访问同一个变量内容。当改变其中一个变量的值时,另一个也跟着发生变化。   5. php中变量有哪些基本数据类型?        php支持8种原始数据类型包括:        四种标量类型(布尔型boolean,整型interger,浮点型float/double , 字符串string)        两种复合类型(数组array , 对象object)        两种特殊类型(资源resource,NULL)   6. 其它类型转换为boolean类型时,哪些被认为是false?        布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', 空数组,特殊数据类型NULL, 没有设定的变量。      empty()函数在哪些情况下返回true?        布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', array()空数组,特殊数据类型NULL, 没有任何属性的对象,没有赋值的变量。   7. 如果定义了一个变量$a ,但是没有赋初始值              那么$a==0吗?    $a==false吗?    $a==''吗?        $a==NULL吗?    $a===NULL吗?     答:echo=>什么都没有 , var_dump=>NULL        empty($b)==true吗?———————————— echo=>1 , var_dump=>bool(true)        此时如果输出$a++是多少?———————   echo=>什么都没有 , var_dump=>NULL        如果输出++$a又是多少?—————————      echo=>1  , var_dump=>int(1)   8. 字符串怎么转成整数,有几种方法?怎么实现?        强制类型转换: (整型)字符串变量名;        直接转换:settype(字符串变量,整型);        intval(字符串变量);   9. 标量数据和数组的最大区别是什么?        一个标量只能存放一个数据,而数组可以存放多个数据。   10. 常量如何定义? 如何检测一个常量是否被定义?常量的值只能是哪些数据类型?        define()//定义常量 , defined()//检查常量是否定义        常量的值只能是标量类型的数据。   11. 常量分为系统内置常量和自定义常量。请说出最常见的几个系统内置常量?        __FILE__ , __LINE__ , PHP_OS , PHP_VERSION   12. 如果定义了两个相同的常量,前者和后者哪个起作用?        前者起作用,因为常量一旦定义就不能被重新定义或者取消定义。   13. 常量和变量有哪些区别?        1)常量前没有$符号;        2)常量只能通过define()定义,而不能通过赋值语句定义;        3)常量可以在任何地方定义和访问,而变量有全局和局部之分;        4)常量一旦定义就不能被重新定义或者取消定义,而变量而通过赋值方式重新定义;        5)常量的值只能是标量数据,而变量的数据库类型有8种原始数据类型。   14. PHP中常用的几个预定义的全局数组变量是哪些?        有9大预定义的内置数组变量:        $_POST, $_GET, $_REQUEST, $_SESSION, $_COOKIE, $_FILES,$_SERVER, $_ENV, $GLOBALS   15. 在实际开发中,常量最常用于哪些地方?        1)连接数据库的信息定义成常量,如数据库服务器的用户名、密码、数据库名、主机名;        2)将站点的部分路径定义成常量,如web绝对路径,smarty的安装路径,model、view或者controller的文件夹路径;        3)网站的公共信息,如网站名称,网站关键词等信息。   16. 函数的优越性有哪些?        提高程序的可维护性  提高软件的可靠性  提高程序的可重用性  提高程序的开发效率   17. 如何定义一个函数?函数名区分大小写吗?        1)使用 function 关键字;        2)函数命名规则和变量一样,以字母或者下划线开头,而不能以数字开头;        3)函数名不区分大小写;        4)函数名不可以使用已经声明过的或者系统自建的函数名称。   18. 什么是变量的能见度 或者 说是变量作用域?        就是变量在程序中的可作用范围。根据变量的能见度,变量分为局部变量和全局变量。   19. 什么是局部变量和全局变量?函数内是否可以直接调用全局变量?        局部变量是函数内部定义的变量,其作用域是所在的函数。如果函数外还有一个跟局部变量名字一样的变量,程序会认为它们两个是完全不同的两个变量。当退出函数的时候,其中的局部变量就同时被清除。全局变量是定义在所有函数以外的变量,其作用域是整个php文件,但是在用户自定义的函数内部是无法使用的。如果一定要在用户自定义的函数内部使用全局变量,那么就需要使用global关键字声明。也就是说如果在函数内的变量前加上golbal来修饰,那么函数内部就可以访问到这个全局变量,不仅可以利用这个全局变量进行运算而且可以对这个全局变量进行重新赋值。全局变量还可以使用 $GLOBALS['var'] 来调用。   21. 什么是静态变量?        如果一个函数内定义的变量前使用关键字static来声明,那么该变量就是静态变量。        一般函数内的变量在函数调用结束后,其存储的数据将被清除,所占的内存空间也被释放。而使用静态变量时,该变量会在函数第一次被调用时被初始化,初始化后该变量也不会被清除,当再次调用该函数时,这个静态变量不再被初始化,而能保存上次函数执行完后的值。可以说静态变量在所有对该函数的调用之间共享。   22. php中函数传递参数的方式有哪些?两者有什么区别?        按值传递和按地址传递(或按引用传递)        (1)按值传递:  待传递的变量,与传递给函数之后的变量是存储在不同的空间中。所以函数体内对                该变量值做的修改,不影响原本的变量值。      (2)按地址传递: 使用 & 符号,表明该参数是以地址的方式传递值。并不会将主程序中的指定数值或目标变量传递给函数,而是把该数值或变量的内存储存区块地址导入函数之中,所以函数体内的该变量和主程序中的该变量在内存中是同一个。函数体做的修改,直接影响到函数体外部的该变量的值。     23. 什么是递归函数?如何进行递归调用?        递归函数其实就是调用自身的函数,但是必须满足以下两个条件:        1)在每一次调用自身时,必须是更接近于最终结果;        2)必须有一个确定的递归终止条件,不会造成死循环。        举例说明:        在实际工作中往往会在遍历文件夹的时候使用。        如果有个例子是希望获取到目录windows下所有的文件,那么先遍历windows目录,如果发现其中还有文件夹,那么就会调用自身,继续往下寻找,依次类推,        直到遍历到再也没有文件夹为止,这也就是意味着遍历出来了所有的文件。   24. 判断一个函数是否存在?      function_exists( string $function_name )  如果存在,返回true, 不存在则返回 false。   25. func()和@func()之间有什么区别?        第二个函数调用失败不会报错,第一个会报错   26. include()和require()函数的用法和区别是什么?include_once()和require_once()呢?        include和require出现错误后的错误级别不一样        include_once()和require_once()在加载之前要判断是否已经导入   27. 说出前置++和后置++的区别?        前置++是先将变量增加1,然后在将值赋值给原来的变量;        后置++是先返回变量的当前值,然后再将变量的当前值增加1.   28. 字符串运算符“.”与算术运算符“+”有什么区别?        当“a”“b”之间使用.时认为是连字符。如果两者间是+的时候php会认为是一次运算。        1)如果+号两边的字符串是数字组成的,那么会将字符串自动转为整型;        2)如果+号两边是纯粹的字母,那么会输出0;        3)如果+号两边的字符串是以数字开头的,那么会截取字符串开头的数字,然后进行运算。   29. 什么是三目(或三元)运算符?        根据一个表达式的结果在另两个表达式中选择一个。        例如: ($a==true) ? 'good':'bad';   30. 控制流程语句有哪些?        1:三种程序结构    顺序结构、分支结构、循环结构        2:分支: if/esle/esleif/     switch/case/default        3: switch 需要注意的:               case子句中的常量可以是整型、字符串型常量、 或者常量表达式,不允许是变量。              同一个switch子句中,case的值不能相同,否则只能取到首次出现case中的值。        4: 循环  for while   do...while          do...while 后面必须加入分号结尾。          while 和 do...while 的区别        5:break 和 continue 的区别。               break可以终止循环。               continue没有break强大,只能终止本次循环而进入到下一次循环中。   31. 数组的概念是什么?数组根据索引分为哪两种,如何区分?数组的赋值方式有哪两种?        数组是一个可以存储一组或一系列数值的变量(复合型变量)        索引数组(索引值为数字,以0开始)和关联数组(以字符串作为索引值)        数组的赋值方式有哪两种?        数组的声明方式主要有两种。        1.通过array()函数声明数组; 可以通过key=>value的方式分别定义索引和值,也可以不定义数组的索引下标,只给出数组的元素值。        2.直接为数组元素赋值,不需要调用array()函数。例如:        $arr[0] = 1;     $arr[1] = 2;        特别注意:        数组的下标如果是等价于整数的字符串值(但不能以0开头),则会被当作整数对待。        例如: $array[3] 与  $array['3'] 引用的是相同的一个元素,而 $array['03'] 引用的则就是另外的一个元素了。   32.数组如何遍历?        ①for循环        ②foreach循环  ,这是最常用的遍历方式。用法如下:foreach($arr as $key=>$value){}        ③list each 和while 配合起来循环   33. foeach数组的时候指针是如何指向的?list()/each()/while()循环数组的时候指针如何指向的呢?        当foreach开始执行的时候,数组内部的指针会自动指向第一个单元。因为foreach所操作的是指定数组的拷贝,而不是该数组本身。而each()一个数组后,数组指针将停留在数组中的下一个单元或者碰到数组结尾时停留在最后一个单元。如果要再次使用each()遍历数组,必须要使用reset().        reset()将数组的内部指针倒回到第一个单元并返回第一个数组单元的值。   34. 如何计算数组长度(或者说计算数组中所有元素的个数)?字符串怎么取长度?        count() -- 计算数组中的元素个数。        可以使用count(数组名)或者count(数组名,1),如果有第二个参数,并且是数字1,则表示递归统计数组元素的个数。如果第二个参数是数字0,则等同于只有一个参数的count()函数。        sizeof() -- count() 的别名(count — 计算数组中的单元数目或对象中的属性个数) 字符串:strlen()— 获取字符串长度         mb_strlen()— Get string length   35. 数组中相关的常用函数有哪些?        1) count --(sizeof别名)— 计算数组中的单元数目或对象中的属性个数                  例如:int count ( mixed $var [, int $mode ] )  $var 通常都是数组类型,任何其它类型都只有一个单元。  $mode 默认值为0. 1为开启递归地对数组计数        2) in_array ( mixed $needle , array $haystack [, bool $strict ] ) — 检查数组中是否存在某个值。如果 needle 是字符串,则比较是区分大小写的。如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。        3) array_merge(array $array1 [, array $array2 [, array $... ]] ) 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。               特别注意:如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。               如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引          4) 数组与字符串之间的转换               (1)explode ( string $separator , string $string [, int $limit ] )  使用一个分隔字符来分隔一个字符串。               (2)implode ( string $glue , array $arr )  使用一个连接符将数组中的每个单元连接为一个字符串。join 为 implode 的别名        5) sort(array &$array [, int $sort_flags ]) — 对数组按照值排序,当本函数结束时数组单元将被从最低到最高重新安排。   36. 数组合并函数array_merge()和数组加法运算$arr + $arr2 的区别是什么?        array_merge()->使用array_merge(),如果是关联数组合并,如果数组的键名相同,那么后面的值将覆盖前者;如果是数字索引数组合并,则不覆盖,而是后者附加到前者后面。"+"->使用数组加法运算,与array_merge()不同,加法运算不管是关联数组还是数字索引数组,都是将相同键名的的值舍弃,也就是只保留首次出现该键名的元素,后来的具有相同键名的元素都不会被加进来。   37. 字符串定义的时候单引号和双引号有什么区别?        单引号加载速度比双引号加载速度快 38. echo(),print(),print_r()的区别?        (1)echo 是语法,Output one or more strings,没有返回值;        (2)print 是函数,不能输出数组和对象,Output a string,print有返回值;        (3)print_r 是函数,可以输出数组。print_r是个比较有意思的函数,可以输出stirng、int、float、     array、object等,输出array时会用结构表示,print_r输出成功时返回true;而且print_r可以通过print_r($str,true)来,使print_r不输出而返回print_r处理后的值。此外,对于echo和print,基本以使用echo居多,因为其效率比print要高。   39. 按照功能分类说说都有哪些字符串处理函数?这些函数的作用是什么?        A. 字符串输出函数        (1)echo $a,$b,$c......;  是一个语言结构,而不是一个真正的函数。        (2)print($a)    本函数输出字符串。若成功则返回 1,失败返回 0        (3)print_r($a)        (4)var_dump($a); 能输出类型、长度、值        B. 去除字符串首尾空格的函数: trim  ltrim  rtrim(别名:chop)   使用第二个参数,还可以去除指定的字符。        C. 转义字符串函数:addslashes()        D. 获取字符串长度的函数:strlen()        E. 截取字符串长度的的函数:substr()        F. 检索字符串函数: strstr() , strpos()        G. 替换字符串函数:str_replace()   40. 请给出以下问题的正确答案?        1).$arr = array('james', 'tom', 'symfony');请将$arr数组的值用’,’分割并合并成字符串输出?          echo implode(‘,’,$arr);        2).$str = ‘jack,james,tom,symfony’; 请将$str用’,’分割,并把分割后的值放到$arr数组中?           $arr = explode(‘,’,$str);        3).$arr = array(3,7,2,1,’d’,’abc’);   请将$arr按照从大到小的顺序排序,并保持其键值不变?           arsort($arr); print_r($arr);        4).$mail = “gaofei@163.com”;    请将此邮箱的域(163.com)取出来并打印,看最多能写出几种方法?               echo strstr($mail,'163');               echo substr($mail,7);               $arr = explode("@",$mail); echo $arr[1];        5). 如果有一个字符串,该字符串是“123,234,345,”。请问如何切割掉这个字符串最后一个逗号?        6). 获取随机数的函数有哪几个?mt_rand() 和 rand()哪个执行速度快?   41.页面字符出现乱码,怎么解决?        1.首先考虑当前文件是不是设置了字符集。查看是不是meta标签中写了charset,如果是php页面还可以看看是不是        在header()函数中指定了charset;        例如:        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />        header(“content-type:text/html;charset=utf-8”);        2.如果设置了字符集(也就是charset),那么判断当前文件保存的编码格式是否跟页面设置的字符集保持一致,        两者必须保持统一;        3.如果涉及到从数据库提取数据,那么判断数据库查询时的字符集是否跟当前页面设置的字符集一致,两者必须统一,        例如:mysql_query(“set names utf8”)。   42. 正则表达式是什么?php中有哪些常用的跟正则相关的函数?请写出一个email的正则,中国手机号码和座机号码的正则表达式?        正则表达式是用于描述字符排列模式的一种语法规则。正则表达式也叫做模式表达式。        网站开发中正则表达式最常用于表单提交信息前的客户端验证。        比如验证用户名是否输入正确,密码输入是否符合要求,email、手机号码等信息的输入是否合法        在php中正则表达式主要用于字符串的分割、匹配、查找和替换操作。               preg系列函数可以处理。具体有以下几个:        string preg_quote ( string str [, string delimiter] )        转义正则表达式字符 正则表达式的特殊字符包括:. \\ + * ? [ ^ ] $ ( ) { } = ! < > | :。        preg_replace -- 执行正则表达式的搜索和替换        mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]        preg_replace_callback -- 用回调函数执行正则表达式的搜索和替换        mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )        preg_split -- 用正则表达式分割字符串        array preg_split ( string pattern, string subject [, int limit [, int flags]] )          常用的正则表达式写法:        中文:/^[\u4E00-\u9FA5]+$/        手机号码:/^(86)?0?1\d{10}$/        EMAIL:        /^[\w-]+[\w-.]?@[\w-]+\.{1}[A-Za-z]{2,5}$/        密码(安全级别中):        /^(\d+[A-Za-z]\w*|[A-Za-z]+\d\w*)$/        密码(安全级别高):        /^(\d+[a-zA-Z~!@#$%^&(){}][\w~!@#$%^&(){}]*|[a-zA-Z~!@#$%^&(){}]+\d[\w~!@#$%^&(){}]*)$/   44. preg_replace()和 str_ireplace()两个函数在使用上有什么不同?preg_split()和split()函数如何使用?   preg_replace — 执行正则表达式的搜索和替换   str_ireplace — str_replace() 的忽略大小写版本   str_replace — 子字符串替换            preg_split — 用正则表达式分割字符串        split — 用正则表达式将字符串分割到数组中   45. 获取当前时间戳的函数主要有哪些?用PHP打印出今天的时间,格式是2010-12-10 22:21:21?        用PHP打印出前一天的时间格式是2010-12-10 22:21:21?如何把2010-12-25 10:30:25变成unix时间戳?        echo date ("Y-m-d H:i:s" ,strtotime(‘-1,days’));            date('Y-m-d H:i:s',time());          $unix_time = strtotime("2009-9-2 10:30:25");//变成unix时间戳        echo date("Y-m-d H:i:s",$unix_time);//格式化为正常时间格式   46.  在url中用get传值的时候,若中文出现乱码,应该用哪个函数对中文进行编码?        用户在网站表单提交数据的时候,为了防止脚本攻击(比如用户输入<script>alert(111);</script>),php端接收数据的时候,应该如何处理?        使用urlencode()对中文进行编码,使用urldecode()来解码。           使用htmlspecialchars($_POST[‘title’])来过滤表单传参就可以避免脚本攻击。   48. 说说mysql_fetch_row() 和mysql_fetch_assoc()和mysql_fetch_array之间有什么区别?        第一个是返回结果集中的一行作为索引数组,第二个是返回关联数组,而第三个既可以返回索引数组也可以返回关联数组,取决于它的第二个参数 MYSQL_BOTH MYSQL_NUM  MYSQL_ASSOC 默认为MYSQL_BOTH        $sql =”select * from table1”;        $result = mysql_query($sql);        mysql_fetch_array($result, MYSQL_NUM);   49. 请说出目前学过的返回是资源的函数?        答:       fopen(打开文件)                 imagecreatefromjpeg(png gif) — 从 JPEG 文件新建一图像                 imagecreatetruecolor — 新建一个真彩色图像                 imagecopymerge — 拷贝并合并图像的一部分                 imagecopyresized  — 拷贝部分图像并调整大小                 mysql_connect  — 打开一个到 MySQL 服务器的连接               mysql_query();只有这执行select的时候成功,才返回资源,失败返回FALSE               50. 打开、关闭文件分别是什么函数? 文件读写是什么函数?删除文件是哪个函数?        判断一个文件是否存在是哪个函数?新建目录是哪个函数?   51. 文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?        1.首现要在php.ini中开启文件上传;        2.在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;        3.上传表单一定要记住在form标签中写上enctype="multipart/form-data";        4. 提交方式 method 必须是 post;        5. 设定 type="file" 的表单控件;        6.要注意上传文件的大小MAX_FILE_SIZE、文件类型是否符合要求,上传后存放的路径是否存在。 可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名,这样就避免了重名。可以自己设置上传文件的保存目录,与文件名拼凑形成一个文件路径,使用move_uploaded_file(),就可以完成将文件保存到指定目录。     52. $_FILES是几维数组?第一维和第二维的索引下标分别是什么?批量上传文件的时候需要注意什么?        二维数组。第一维是上传控件的name,二维下标分别为name/type/tmp_name/size/error.   53. header()函数主要的功能有哪些?使用过程中注意什么?        答:     header()发送http头信息    -header("content-type:text/html; charset=utf-8");-------------------//当前页面输出内容是html,编码为utf-8格式    -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    -header("content-type:image/png gif jpeg");----------------------------------//当前页面输出内容的格式是图片    -header("refresh:5;url=http://www.1004javag.com/five/string.php");--//页面5秒后要跳转到新网址 -header("location:http://1004javag.com/five/string.php");-----------//页面重定向 54. 文件下载的时候如果使用header()函数?        答:header("content-type: application/octet-stream;charset=UTF-8"); //在这里加utf-8和在上面定义有什么区别?、??              header("accept-ranges: bytes");             header("accept-length: ".filesize($filedir.$filename));             header("content-disposition: attachment; filename=".$filedir.$filename);     55. 什么是ajax?ajax的原理是什么?ajax的核心技术是什么?ajax的优缺点是什么?        ajax是asynchronous javascript and xml的缩写,是javascript、xml、css、DOM等多个技术的组合。     '$'是jQuery的别名.     页面中用户的请求通过ajax引擎异步地与服务器进行通信,服务器将请求的结果返回给这个ajax引擎,   最后由这个ajax引擎来决定将返回的数据显示到页面中的指定位置。Ajax最终实现了在一个页面的指定位置可以加载另一个页面所有的输出内容。        这样就实现了一个静态页面也能获取到数据库中的返回数据信息了。所以ajax技术实现了一个静态网页在不刷新整个页面的情况下与服务器通信,        减少了用户等待时间,同时也从而降低了网络流量,增强了客户体验的友好程度。               Ajax的优点是:        1.  减轻了服务器端负担,将一部分以前由服务器负担的工作转移到客户端执行,利用客户端闲置的资源进行处理;        2.  在只局部刷新的情况下更新页面,增加了页面反应速度,使用户体验更友好。        Ajax的缺点是不利于seo推广优化,因为搜索引擎无法直接访问到ajax请求的内容。        ajax的核心技术是XMLHttpRequest,它是javascript中的一个对象。   56. jquery是什么?jquery简化ajax后的方法有哪些?        jQuery是Javascript的一种框架。        $.get(),$.post(),$.ajax()。$是jQuery对象的别名。          代码如下:        $.post(异步访问的url地址 , {'参数名' : 参数值} , function(msg){               $("#result").html(msg);        });               $.get(异步访问的url地址 , {'参数名' : 参数值} , function(msg){               $("#result").html(msg);        });          $.ajax({               type: "post",               url: loadUrl,               cache:false,               data: "参数名=" + 参数值,               success: function(msg) {                      $("#result").html(msg);               }        });     57. 什么是会话控制?        简单地说会话控制就是跟踪和识别用户信息的机制。会话控制的思想就是能够在网站中跟踪一个变量,通过这个变量,系统能识别出相应的用户信息,根据这个用户信息可以得知用户权限,从而展示给用户适合于其相应权限的页面内容。目前最主要的会话跟踪方式有cookie,session。   58. 会话跟踪的基本步骤        1).访问与当前请求相关的会话对象  2).查找与会话相关的信息        3).存储会话信息     4).废弃会话数据   59. 使用cookie的注意事项有哪些?        1) setcookie()之前不可以有任何页面输出,就是空格,空白行也不可以;        2) setcookie()后,在当前页面调用$_COOKIE['cookiename']不会有输出,必须刷新或到下一个页面才可以看到cookie值;        3) 不同的浏览器对cookie处理不同,客户端可以禁用cookie,浏览器也可以闲置cookie的数量,一个浏览器能创建的cookie数量最多300个,并且每个不可以超过4kb,        每个web站点能设置的cookie总数不能超过20个。        4) cookie是保存在客户端的,用户禁用了cookie,那么setcookie就不会起作用了。所以不可以过度依赖cookie。   60. 使用session的时候,通过什么来表示当前用户,从而与其他用户进行区分?        sessionid,通过session_id()函数可以取得当前的session_id。   61. session和cookie的使用步骤分别是什么?什么是sesssion和cookie的生命周期?session和cookie的区别是什么?        cookie是保存在客户端机器的,对于未设置过期时间的cookie,cookie值会保存在机器的内存中,只要关闭浏览器则cookie自动消失。如果设置了cookie的过期时间,那么浏览器会把cookie以文本文件的形式保存到硬盘中,当再次打开浏览器时cookie值依然有效。             session是把用户需要存储的信息保存在服务器端。每个用户的session信息就像是键值对一样存储在服务器端,其中的键就是sessionid,而值就是用户需要存储信息。服务器就是通过sessionid来区分存储的session信息是哪个用户的。              两者最大的区别就是session存储在服务器端,而cookie是在客户端。session安全性更高,而cookie安全性弱。        session在web开发中具有非常重要的份量。它可以将用户正确登录后的信息记录到服务器的内存中,当用户以此身份访问网站的管理后台时,无需再次登录即可得到身份确认。而没有正确登录的用户则不分配session空间,即便输入了管理后台的访问地址也不能看到页面内容。通过session确定了用户对页面的操作权限。           使用session的步骤:        1. 启动session:使用session_start()函数来启动。        2. 注册会话:直接给$_SESSION数组添加元素即可。        3. 使用会话:判断session是否为空或者是否已经注册,如果已经存在则像普通数组使用即可。        4. 删除会话:               1.可以使用unset删除单个session;               2.使用$_SESSION=array()的方式,一次注销所有的会话变量;               3.使用session_destroy()函数来彻底销毁session。        cookie怎么使用?        1. 记录用户访问的部分信息        2. 在页面间传递变量        3. 将所查看的internet页存储在cookies临时文件夹中,可以提高以后的浏览速度。        创建cookie:setcookie(string cookiename , string value , int expire);        读取cookie:通过超级全局数组$_COOKIE来读取浏览器端的cookie的值。        删除cookie:有两种方法        1.手工删除方法:        右击浏览器属性,可以看到删除cookies,执行操作即可将所有cookie文件删除。        2.setcookie()方法:        跟设置cookie的方法一样,不过此时将cookie的值设置为空,有效时间为0或小于当前时间戳。   62. 如何设置一个cookie的名字为username,值为jack,并且让此cookie一周后失效?        一个浏览器最多可以产生多少个cookie,每个cookie文件最大不能超过多少?        setcookie(‘username’,’jack’,time()+7*24*3600);        最多可以产生20个cookie,每个最多不超过4K   63. 设置或读取session之前,需要做什么?        可以直接在php.ini中开启session.auto_start = 1或者在页面头部用session_start();        开启session,session_start()前面不能有任何输出,包括空行。   64. 在实际开发中,session在哪些场合使用?        session用来存储用户登录信息和用在跨页面传值。        1)常用在用户登录成功后,将用户登录信息赋值给session;        2)用在验证码图片生成,当随机码生成后赋值给session。   65. 注销session会话的形式有几种?        unset()   $_SESSION=array();   session_destroy();   66. 什么是OOP?什么是类和对象?什么是类属性?        OOP(object oriented programming),即面向对象编程,其中两个最重要的概念就是类和对象。        世间万物都具有自身的属性和方法,通过这些属性和方法可以区分出不同的物质。        属性和方法的集合就形成了类,类是面向对象编程的核心和基础,        通过类就将零散的用于实现某个功能的代码有效地管理起来了。              类只是具备了某些功能和属性的抽象模型,而实际应用中需要一个一个实体,也就是需要对类进行实例化,类在实例化之后就是对象。类是对象的抽象概念,对象是类的实例化。    对象是一个高级的数组,数组是一个最原始的对象,同样的对象也可以遍历        OOP具有三大特点:         1. 封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。        2. 继承性:就是子类自动继承其父级类中的属性和方法,并可以可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。 php只支持单继承,也就是说一个子类只能有一个父类。        3. 多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。          OOP的优点:1、代码重用性高(省代码)    2、使程序的可维护性高(扩展性)  3、灵活性           67. 常用的属性的访问修饰符有哪些?分别代表什么含义?        private,protected,public。           类外:public ,var        子类中:public,protected ,var        本类中:private,protected,public ,var        如果不使用这三个关键词,也可以使用var关键字。但是var不可以跟权限修饰词一起使用。var定义的变量,子类中可以访问到,类外也可以访问到,相当于public        类前面:只能加final,abstract        属性前面:必须有访问修饰符(private,protected,public,var)        方法前面:static,final,private,protected,public ,abstract   68. $this和self、parent这三个关键词分别代表什么?在哪些场合下使用?        $this 当前对象   self  当前类   parent  当前类的父类        $this在当前类中使用,使用->调用属性和方法。        self也在当前类中使用,不过需要使用::调用。    parent在类中使用。   69.类中如何定义常量、如何类中调用常量、如何在类外调用常量。        类中的常量也就是成员常量,常量就是不会改变的量,是一个恒值。        定义常量使用关键字const.        例如:const PI = 3.1415326;        无论是类内还是类外,常量的访问和变量是不一样的,常量不需要实例化对象,        访问常量的格式都是类名加作用域操作符号(双冒号)来调用。        即:类名 :: 类常量名;   70. 作用域操作符::如何使用?都在哪些场合下使用?        调用类常量   调用静态方法   71. 什么是魔术方法?常用的魔术方法有哪几个?        以__开头的系统自定义的方法。        __construct()  __destruct()   __autoload()   __call()    __tostring()   72. 什么是构造方法和析构方法?        构造方法就是在实例化一个对象的同时自动执行的成员方法,作用就是初始化对象。        php5之前,一个跟类名完全相同的方法是构造方法,php5之后魔术方法__construct()就是构造方法。如果类中没有定义构造方法,那么php会自动生成一个,这个自动生成的构造方法没有任何参数,没有任何操作。        构造方法的格式如下:        function __construct(){}        或者:function 类名(){}        构造方法可以没有参数,也可以有多个参数。        析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。        析构方法的定义方法为:__destruct();        因为php具有垃圾回收机制,能自动清除不再使用的对象,释放内存,一般情况下可以不手动创建析构方法。   73. __autoload()方法的工作原理是什么?        使用这个魔术函数的基本条件是类文件的文件名要和类的名字保持一致。        当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时. 就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。   74. 什么是抽象类和接口?抽象类和接口有什么不同和相似的地方?        抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。        抽象类是通过关键字 abstract 来声明的。        抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少要包含一个抽象方法,        抽象方法没有方法体,该方法天生就是要被子类重写的。        抽象方法的格式为:abstract function abstractMethod();                   因为php中只支持单继承,如果想实现多重继承,就要使用接口。也就是说子类可以实现多个接口。接口类是通过interface关键字来声明的,接口类中的成员变量和方法都是public的,方法可以不写关键字public,接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。抽象类和接口实现的功能十分相似,最大的不同是接口能实现多继承。在应用中选择抽象类还是接口要看具体实现。子类继承抽象类使用extends,子类实现接口使用implements。        抽象类至少有一个抽象方法吗??????        答:如果一个类声明成抽象类,里面可以没有抽象方法            如果一个类中有抽象方法,这个类必须是抽象类   75. __call的参数有几个,类型是什么,意义是什么?        魔术方法__call()的作用是当程序调用一个不存在或不可见的成员方法时,php会先调用__call()方法,将那个不存在的方法的方法名和参数都存储下来。        __call()包含两个参数,  第一个参数是那个不存在的方法的方法名,是个字符串类型;                             第二个参数是那个不存在的方法的所有参数,是个数组类型。        本人认为__call()方法的意义更多在于调试,可以定位到错误。同时可以捕捉异常,如果某个方法不存在,则执行其它可替代方法。   76. smarty模板技术的用途是什么?        为了php与html分开,美工和程序员各司其职,互不干扰。   77. smarty配置主要有哪几项?        1. 引入smarty.class.php;        2. 实例化smarty对象;        3. 重新修改默认的模板路径;        4. 重新修改默认的编译后文件的路径;        5. 重新修改默认的配置文件的路径;        6. 重新修改默认的cache的路径。        7. 可以设置是否开启cache。        8. 可以设置左侧和右侧定界符。   78. smarty在使用过程中需要注意哪些细节?        Smarty是基于MVC概念的一种模板引擎,它将一个页面程序分成了两部分来实现:即视图层和控制层,也就是说smarty技术将用户UI与php代码分离开。这样程序员和美工各司其职,互不干扰。        smarty运用过程中要注意以下几个问题:        1.正确配置smarty。主要要实例化smarty对象,配置smarty模板文件的路径;        2.php页面中使用assign赋值 和 display显示页面;        3.smarty模板文件中不允许出现php代码段,所有的注释,变量,函数都要包含在定界符内。               A.{}               B. foreach               C. if else               D. include               E. literal   79. MVC的概念是什么?各层主要做什么工作?        MVC(即模型-视图-控制器)是一种软件设计模式或者说编程思想。        M指Model模型层,V是View视图层(显示层或者用户界面),C是Controller控制器层。        使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。        在网站开发中,        模型层一般负责对数据库表信息进行增删改查,        视图层负责显示页面内容,        控制器层在M和V之间起到调节作用,控制器层决定调用哪个model类的哪个方法,        执行完毕后由控制器层决定将结果assign到哪个view层。   81. java语言中方法重写和重载分别代表什么意思?准确说php支持方法的重载吗?很多参考书中提到的php重载实际上该如何正确理解?        答:        php不支持方法的重载,很多书里提到的PHP‘重载’应该是‘重写’   82. final关键字能定义类中的成员属性吗?        答:不能,类的成员属性只能有public ,private , protected ,var 来定义   83. final关键字定义的类能够被继承吗?        答:final定义的类不能被继承   84. 说说static关键字的使用场合?static能用在class前吗?     static可以跟public,protected,private一起使用吗?构造方法可以是static的吗?        答:       static可以在属性和方法前面使用,调用static属性或者方法时,只要将类载入就可用,不用实例化               static不能用在class的前面                   static可以跟public,protected,private一起使用,在方法的前面;               ▲构造方法不能是static   85. 接口可以实例化吗?抽象类能实例化吗?        答:接口和抽象类都不能被实例化   86. class前面能加访问修饰符吗?如果能加,只能是哪几个访问修饰符?可以是权限访问修饰符public,protected,private吗?        答:class前面可以加final,static;        class前面不能加public,protected,private   87. 类中属性前可以不加访问修饰符吗?成员变量前的修饰符只能是public,protected,private吗?还可以是哪几个?        答:类中的属性必须加修饰符,除了那3个以外,还可以加var   88. 如果echo一个数组,页面输出什么?echo一个对象呢?print一个数组或者对象呢?        答:页面只能输出“Array”;echo一个对象会出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php on line 33”            print一个数组时也只是输出“Array”,print一个对象出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php ”            ▲print和echo是一样的             89. __tostring()魔术方法在什么时候被自动执行? __tostring()魔术方法必须要return返回值吗?        当echo或者print一个对象时,就是自动触发。而且__tostring()必须要返回一个值        90. 什么是抽象方法?        答:在方法前面有abstract,而且方法没有方法体,连“{ }”也不能有   91. 如果一个类中有一个方法是抽象方法,而这个类没有定义成抽象类,会报错吗?           答:会,"Fatal error: Class t2 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (t2::ee) in"   92. 如果一个类是抽象类,而类中的方法都是非抽象的方法,会报错吗?        答:不会报错,如果一个类是抽象类,其中可以没有抽象方法,但是一个类中有个方法是抽象方法,那么这个类一定是一个抽象类   94. final 关键字的应用应注意的问题?          使用final关键字定义的类,禁止继承。        使用final关键字定义的方法,禁止重写。   95. 如果一个类既要继承一个父类,又要实现多个接口,该如何写?        书写格式例如: class MaleHuman extends Human implements Animal,Life { ... }   96. 什么是单点入口呢?         所谓单点入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发,         比如说在上面我们就使用index.php作为程序的单点入口,当然这个是可以由你自己任意控制的。        单点入口有几大好处:            第一、一些系统全局处理的变量,类,方法都可以在这里进行处理。比如说你要对数据进行初步的过滤,你要模拟session处理,你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面            第二、程序的架构更加清晰明了。   97. PHP提供了2套正则表达式函数库,分别是哪两套?【        (1) PCRE   Perl兼容正则表达式         preg_   为前缀        (2) POSIX  便携式的操作系统接口       ereg_   为前缀   98. 正则表达式的组成?     由原子(普通字符,如英文字符)、     元字符(有特殊功用的字符)     模式修正字符     一个正则表达式中,至少包含一个原子   99. 不常用魔术方法的触发时机?        __isset()  __unset()的触发时机        __sleep()、 __wakeup()  在对对象进行串行化的时候调用        如果序列化对象的时候,不写__sleep()方法,则所有的成员属性都会被序列化,而定义了__sleep()方法,则只序列化指定数组中的变量。因此,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。        使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。        使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。               101.常见框架        thinkPHP  yii  ZendFramework  CakePhp  sy   102. 常用魔术方法的触发时机?        1)__autoload() :当程序实例化某个类,而该类没有在当前文件中被引入。此时会触发执行__autoload()。程序希望通过该方法,自动引入这个类文件。该方法有一个参数,即就是那个忘记引入的类的名称。__autoload()方法的工作原理是什么?当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后,就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。        2)__construct()  :这个是魔术构造方法。构造方法是实例化对象的时候自动执行的方法,作用就是初始化对象。该方法可以没有参数,也可以有多个参数。如果有参数,那么new这个对象的时候要记得写上相应的参数。在php5以前,没有魔术构造方法,普通构造方法是一个跟类名同名的方法来实现构造的。如果一个类中既写了魔术构造方法,又定义了普通构造方法。那么php5以上版本中,魔术方法起作用,普通构造方法不起作用。反之,在php5以前版本中,不认识魔术构造方法,只是把该方法当做普通的方法。        3)__destruct()  :这个是魔术析构方法。析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。析构方法没有参数。        4)__call() :当程序调用一个不存在或不可见的成员方法时,自动触发执行__call()。它有两个参数,分别是未访问到的方法名称和方法的参数。而第二个参数是数组类型。        5)__get() :当程序调用一个未定义或不可见的成员属性时,自动触发执行__get()。它有一个参数,表示要调用的属性的名称。        6)__set():当程序试图写入一个不存在或不可见的成员属性时,PHP就会自动执行__set()。它包含两个参数,分别表示属性名称和属性值。        7)__tostring()  :当程序使用echo或print输出对象时,会自动调用该方法。目的是希望通过该方法将对象转化为字符串,再输出。__tostring() 无参数,但是该方法必须有返回值。        8)__clone()  :当程序clone一个对象的时候,能触发__clone()方法,程序希望通过这个魔术方法实现:不仅仅单纯地克隆对象,还需要克隆出来的对象拥有原来对象的所有属性和方法。   103. MVC的概念是什么?        MVC(即模型-视图-控制器)是80年代发明的一种软件设计模式或者说编程思想。        M指模型层,V是指视图层(显示层或者用户界面),C是指控制层。        使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。        C存在的目的则是在M和V之间起到调节作用,确保M和V的同步,一旦M改变,V应该能同步更新。        将M和V分离,就可以做到同一个网页,在不同节日到来的时候能显示不同的页面风格,这只需要提前制作多个视图层模板页面,        而无需更改M层程序。        MVC做到了编程中的分工合作,代码的可重用性得到最大化体现,程序逻辑更加清晰而富有条理,便于后期维护管理。   104、     访问权限修饰符有哪几种,对比解释        答:1、public 表示公共的,在本类中和子类中以及类外,可以对其调用        2、protected表示受保护的,可以在本类中和子类中调用        3、private表示私有的,只能在本类中调用        4、var,效果等同于public 105、     Class关键词前可以有哪些修饰词        a)    Final修饰,表示该类是最终的,无法继承        b)    Abstract修饰,表示该类是抽象类   106、     作用域操作符在那些场合下使用        答:作用于操作符的使用场合        a)    本类中:               i.     self::类常量               ii.     self::静态属性               iii.    self::方法()   parent::方法()        b)    子类中:               i.     parent::类常量               ii.     parent::静态属性(public或者protected)               iii.    parent::方法()(public或者protected)        c)    类外:               i.     类名::类常量               ii.     类名::静态属性(public)               iii.    类名::静态方法(public)   107、     $this,self, parent分别代表什么?哪些场合下使用        答:$this代表的是当前对象  self代表的是当前的类  parent代表的是当前类的父类        使用场合:        $this只能使用在当前类中,通过$this->可以调用当前类中的属性和方法;        self只能在当前类中使用,通过作用域操作符::访问当前类中的类常量、当前类中的静态属性、当前类中的方法;        parent只能使用在有父类的当前类中,通过作用域操作符::访问父类中的类常量、父类中的静态属性、父类中的方法。   108、     说明是接口、抽象类二者有何相同和不同的地方?        1、接口是帮助php实现功能意义上的多继承的,用interface来声明,其方法没有方法体,使用implemens关键词来实现接口。        接口中只能包含抽象方法和类常量,不可以包含成员属性。        2、抽象类是一种不能被实例化的类,只能作父类,用abstract class来定义,抽象类和普通类可以没有区别,类中可以包含成员属性、类常量、方法。        子类得用extends来继承,而且只能是单继承。        两者相同点是都不可以被实例化,都是需要被继承才可以使用。        两者的最大区别是接口可以实现多继承,而抽象类只能是单继承。        接口中不能包含成员属性,而抽象类中可以有成员属性。        接口中的抽象方法必须是public或者无访问修饰词,接口中的抽象方法不能用abstract来修饰。        抽象类中的方法可以是普通方法,也可以是抽象方法,如果是抽象方法,一定需要使用abstract来修饰。   109、     解释PHP中单例模式?        又叫做单态模式、单元素模式、singleton pattern。单例模式指在PHP的应用程序的范围内只对指定的类创建一个实例。使用单例模式的类称为单例类。在php中单例类必须要有一个私有的构造方法,还要有一个私有的魔术克隆方法(该方法体中为空)和一个私有的静态的成员属性$_instance.私有构造方法防止除自身以外的类来实例化它。私有的方法体为空的克隆方法防止该类被克隆。$_instance用来存储被自身实例化后的对象。还必须要有一个公共的静态的方法getInstance()。该方法返回已经存储了实例对象的$_instance。   单例:一个类至始至终只能实例化一个对象,这样的类就是单例类 单例类的优点:① 节省空间 ② 节省资源 实现单例类的四个要点:①私有的构造函数②私有的__clone的方法③私有的静态属性,属性有以保存类的实例④公共的静态方法来实例化对象 无限级分类:         ①数据库设计:region_id(自增ID) region_name(地区名称) parent-id(上级地区id) region_path(全路径)        ②程序设计:全路径的作用:a根据全路径顺序取数据 b用作信息层级显示    110、   什么是SQL注入?        SQL注入攻击是黑客对数据库进行攻击的常用手段之一。一部分程序员在编写代码的时候,        没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,        程序将提交的信息拼凑生成一个完整sql语句,服务器被欺骗而执行该条恶意的SQL命令。注入者根据程序返回的结果,        成功获取一些敏感数据,甚至控制整个服务器,这就是SQL注入。   111、   如何防止SQL注入?        要对提交的信息进行过滤,对单引号进行转义。        首先可以在php.ini中设置,让所有的单引号在提交后都进行转义。或者使用addslashes().   112、     FCKEditor自动过滤的解决办法?        如果您需要编辑模板页,默认的FCK设置是会去掉<HTML></HTML><BODY></BODY>标签,而且会给你加上<P></P>标签的,如果需要保留的话,只要更改下设置可以了。        在fckconfig.js里面有:FCKConfig.FullPage = false ;        改为:FCKConfig.FullPage = true;        如果想去掉自动添加<P>的代码就可以在这里设置        默认是        FCKConfig.EnterMode = 'p' ;    // p | div | br        FCKConfig.ShiftEnterMode = 'br' ; // p | div | br        改成        FCKConfig.EnterMode = 'br' ;    // p | div | br        FCKConfig.ShiftEnterMode = 'p' ; // p | div | br   113、     $_REQUEST、$_GET、$_POST、$_COOKIE 的关系和区别:            1.关系:$_REQUEST包含了$_GET、$_POST、$_COOKIE等的所有内容,是它们的集合体。        2.通过$_REQUEST获取变量值,PHP页面因为不确定它是哪种传值方式,        因此会根据php.ini中的配置来接收值。        php.ini里可以设置,variables_order = “GPC”。其含义是GET,POST,COOKIE.        所以PHP页面会先从$_GET中获取,再从$_POST中获取,然后从$_COOKIE中获取。        新获得的值会覆盖之前获取到的值。        因此从表现形式上看,$_REQUEST最后是获取$_COOKIE中的值,如果$_COOKIE中没有值,        会获取$_POST中的值,如果$_POST没有获取到 ,就去$_GET中获取。        如果$_GET中也没有该值,那么$_REQUEST就返回null。               114、     什么是多条件查询(复合查询),如何实现多条件查询?        如何实现万能查询呢?查询的时候要填写查询条件,这些条件会通过表单进行提交。        首先需要检查提交的条件是否为空。如果不为空,就认为这个值是要被当作条件,        我们就可以使用字符串连接的方式来组合一个sql查询语句。        当执行后获取查询结果。   115.       文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?        1). 首现要在php.ini中开启文件上传;        2). 在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;        3). 上传表单一定要记住在form标签中写上enctype="multipart/form-data";        4). 提交方式 method 必须是 post;        5). 设定 type="file" 的表单控件,并且必须具有name属性值;        6). 为了上传成功,必须保证上传文件的大小是否超标、文件类型是否符合要求,上传后存放的路径是否存在;        7). 表单提交到接收页面,接收页面使用$_FILES来接收上传的文件。$_FILES是个多维数组。第一维下标是上传控件的name,二维下标分别为name/type/tmp_name/size/error。分别代表文件名、文件类型、上传到临时目录下的临时文件名、文件大小、是否有错误。如果是批量上传,那么二维下标就是数组,而并非是字符串。        8). 文件上传后是被放置在服务器端临时路径下,需要使用move_uploaded_file ()函数,才可以将上传后的文件保存到指定目录。        9). 为了避免上传文件重名,可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名。   116.      使用GD2库创建图像的步骤?        1). 创建一个画布:imagecreate();        2). 设置画布背景颜色,使用RGB设置颜色:imagecolorallocate();        3). 设置文字颜色:imagecolorallocate();        4). 在画布上书写文字:imagestring();        5).  以 JPEG 格式将图像输出到浏览器或文件:【根据图片格式不同,函数还可以是imagepng()、imagegif()等】   imagejpeg();        6). 清除图像资源:imagedestroy();   117.      GD2库生成缩略图的步骤是什么?        1). 读取希望生成缩略图的源图像,创建图像对象:【根据图片格式不同,函数也相应不同】               $src_image = imagecreatefromjpeg();        2). 获取原图像的宽度和高度$srcW,$srcH,根据缩放比例计算出新图像的宽度和高度$dstW、$dstH:        3). 创建一个真色彩的图像对象,宽度和高度设置成刚才计算出的宽度和高度:               $dst_image = imagecreatetruecolor($dstW,$dstH);        4). 拷贝图像并调整大小:   imagecopyresized();        5). 将图像输出:【根据图片格式不同,函数也相应不同】  imagejpeg();        6). 清除图像资源(将源图像资源和目标图像资源都清除)   imagedestroy();   118.      GD2库给图片增加水印如何做?        1. 添加简单的文本水印:               利用imagestring()函数就可以在图片上写文本水印。        2. 增加一个图形水印:               1). 读取希望增加水印的源图片,创建图像对象:【根据图片格式不同,函数也相应不同】                      $image = imagecreatefromjpeg();               2). 创建一个水印图片的图像对象:                      $watermark = imagecreatefrompng();               3). 拷贝并合并图像:                      imagecopymerge();               4). 将图像输出:【根据图片格式不同,函数也相应不同】                      imagejpeg();               5). 清除图像资源(将源图像资源和水印图像资源都清除)                      imagedestroy();   119.      什么是事务?什么是回滚?事务的作用是什么?        事务就是组合起来的几个独立的sql操作。如果其中一项失败,那么就让这几个组合起来的sql操作都回退到未执行状态。这就是事务的回滚。mysql中MyISAM存储引擎的表不支持事务,只有InnoDB 存储引擎的表才支持事务,为了让事务正常执行,就需要让参与事务的所有数据表都设置成innoDB类型。事务被包装在了 BEGIN 和 COMMIT 语句之间。在没有使用 COMMIT 语句的情况下,对数据库的操作不是永久的,一旦运行了 ROLLBACK,就会被回退。只有执行了COMMIT,数据表中的信息才被改动。事务的目的就是为了保证数据的完整性。   120.      模拟SESSION机制实现数据库存放会话数据有什么作用?【备用】       如果使用默认的SESSION机制,大家都知道默认的SESSION_ID是存放在COOKIE中,用户的身份是靠SESSION_ID来识别的,而COOKIE文件是存放在用户浏览器的客户端,这样就会带来一个问题,当用户在办公室选择一些商品到购物车,在准备下订单付款的时候,用户选择了支付宝在线的支付方式,恰巧办公室的电脑上面没有安装支付宝的数字证书,而在用户家里的电脑安装过数字证书,所以呢,用户就需要回家去支付。但是回家登录商城之后,发现购物车中精心挑选的商品都不存在了。这是为什么呢?问题就在家里电脑上的并没有存放SESSION_ID的cookie文件,因而就无法正确的读取服务器上对应session文件中的数据,所以无法将原来的选择的商品息读取过来。这样的购物车功能给用户的用户体验式非常糟糕的,所以我们就需要采取模拟SESSION机制使用数据库来存放会话数据。   121.       什么是无限极分类?        要实现无限极分类,数据库建表是关键。        表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。        1. id ,当前数据的唯一标识;        2. typename ,类型名称;        3. parentid , 当前类型的上一层父类型的id;        4. path , 其中存储当前类型的id和它所有父级类型的id。        这些id之间采用“-”隔开。        5. 当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。        select * from 表名 where 条件 order by path; 无限极分类的原理是什么?        要实现无限极分类,数据库表结构是关键。        表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。        1. id ,当前数据的唯一标识;        2. typename ,类型名称;        3. parentid , 当前类型的上一层父类型的id;        4. path , 其中存储当前类型的id和它所有父级类型的id。        这些id之间采用“-”隔开。        5. 当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。         select * from 表名 where 条件 order by path;   122.    分页原理是什么?        数据分页需要以下几个条件:        1. 参与分页的总条数 【$msg_count】 ,该值通过数据库查询可以获取到;        2. 每页显示的条数【$pagesize】 ,这个数值由自己定义;        3. 当前页的页码数 【$page】,该数值通过地址栏传递和接收;        4. 可以通过以上资料计算出总页数 【$pagecount】 ,此处需要借助ceil();               【$pagecount = ceil($msg_count/$pagesize);】        5. 数据库查询借助sql语句中的【limit】来实现数据的变化:               例如:               select * from 表名 where 条件 limit $startnum , $pagesize;               而$startnum = ($page-1)*$pagesize;   123、   如何在smarty模板语言中使用php代码?        借助于两个smarty内建函数。        1. inluce_php 函数用于在模板中包含 php 脚本。例如:        {include_php file="test.php"}        2. php 标签允许在模板中直接嵌入 php 脚本。例如:        {php}               echo "这个是php内建函数的作用";        {/php}        124、   请列出至少五个smarty中的变量调节符并说明功能?        default  例如:{$arr|default:’xxxx’} ,默认变量调节器,当变量为空时显示给定的默认值        truncate   例如:{$articleTitle|truncate:10} , 切割字符串长度为指定的长度;        count_characters   例如:{$articleTitle|count_characters} ,获取字符串长度;        strip_tags   例如:  {$articleTitle|strip_tags} ,去除字符串中的所有html标签;        date_format  例如:{$smarty.now|date_format(‘’)} ,格式化时间戳。   125、   写程序实现如下功能:       a.如何判断一个字符串中是否存在一个字符?        echo strstr('abcdefgcd'  , 'cd');        echo strpos('ab0defgcd'  , 'cd');       b.如何判断一个字符串中一个字符出现的次数?        echo substr_count('abcdefgcd'  , 'cd');       c.如何去掉一个字符串的最后一个字符        echo substr('abcdefgcd'  , 0 ,  -1);   126、     如何使用smarty的缓存、步骤?什么叫单模板多缓存?        如果给整个网站开启缓存,那么$smarty->caching=1,此时缓存的时间为smarty.class.php中默认的时间,也就是3600秒。如果对每一个页面独立设置缓存,那么$smarty->caching=2 ,缓存时间就会跟display的参数模板页相挂钩,也就是可以实现对每个模板页设置不同的缓存时间。        用法例如:        if(!$smarty->is_cached('index.html')) {               //此处可以执行数据库操作               $smarty->cache_lifetime = 3600*6;        }        $smarty->display('index.html');               对于例如新闻单条这样的页面,新闻的模板都是一个,如果开启缓存,那么所有的新闻单页的缓存都是一个,根本不会随着id的变化而变换内容。所以为了区分不同的页面缓存,需要使用单模板多缓存技术。具体做法是以id作为display的第二个参数来实现。此外对于具有分页的列表页,也必须在display中使用第二个参数,可以使用新闻类型id和当前页面合并成第二个参数。   127、   写一个递归函数完成以下功能:向函数中传一个多维数组,对数组中所有的值做判断        ,如果值是’number’则设置该值为0?(提示:该题考的是递归的应用,因为传入的数组不确定是多少维的,所以需要递归判断)          function recursive_array($arr) {               if(is_array($arr)) {                      foreach($arr as $key=>$value) {                             if(is_array($value)) {                                    $arr[$key] = recursive_array($value);                             } else {                                    if($value=='number') {                                           $arr[$key] = '0';                                }                             }}}               return $arr;        }          128、   使用jquery写一个全选的例子?        //全选与取消全选        function selectAll(flag) {               for(var i=0; i<$("#fonds input").size(); i++) {                      $("#fonds input").get(i).checked=flag;               }}        //判断复选框已经被勾选了多少个?        function checkFonds() {               var count=0;               for(var i=0; i<$("#fonds input").size(); i++) {                      if($("#fonds input").get(i).checked==true) {                             count++;                      }}               alert(count);        }        //利用后代选择器和get()来获取指定的控件        $(“div a”).get(2)   129、     请说明smarty中fetch方法的功能?        Fetch方法可以获取到页面所有的内容,并且赋值到一个变量中。        如果第四个参数为true,则等同于display,直接输出到浏览器中。        如果第四个参数为false,则不输出。        Display方法就是第四个参数为true的fetch方法。        Display = Fetch() + echo()   130、   写出关于文件上传的相关函数?                    strrchr($filename , '.');      explode('.' , $filename);        end($arr);                     strrpos($filename , '.');        substr($filename , $pos+1);    pathinfo($filename , PATHINFO_EXTENSION);        date(‘YmdHis’)               time()      rand();        mt_rand()                      move_uploaded_file()   131、   如何将SESSION存放在数据库中,可以结合数据表设计说明.        默认情况下php.ini中session.save_handler = files,也就是session是以文件形 式存储的。        如果想更改为数据库或其它存储方式,那么需要更改设置,让 session.save_handler = user。        除了在php.ini中配置外,还可以在PHP页面中单独配置,用        ini_set ('session.save_handler, 'user')来设置session的存储方式,设置为用户自定义存储方式。        设置好存储方式后,需要使用session_set_save_handler()函数。        该函数是设置用户级别的session保存过程的函数。该函数有6个参数,这6个参数其实是6个自定义函数的名称,分别代表对session的开启,关闭,读,写 ,销毁,gc(垃圾回收)。        示例代码如下:        function open () { }        function close() { }        function read () { }        function write () {}        function destroy () {}        function gc () {}        session_set_save_handler ("open", "close", "read", "write", "destroy",  "gc");        session_start();        现在你就可以象往常一样地使用session了。        数据库结构如下:        Session_id , session_value ,expire_time , 分别存储sessionid的id和值以及失效时间。   132、    常用的正则表达式写法:        中文:/^[\u4E00-\u9FA5]+$/        手机号码:/^(86)?0?1\d{10}$/        EMAIL:        /^[\w-]+[\w-.]?@[\w-]+\.{1}[A-Za-z]{2,5}$/        密码(安全级别中):        /^(\d+[A-Za-z]\w*|[A-Za-z]+\d\w*)$/        密码(安全级别高):        /^(\d+[a-zA-Z~!@#$%^&(){}][\w~!@#$%^&(){}]*|[a-zA-Z~!@#$%^&(){}]+\d[\w~!@#$%^&(){}]*)$/ ——————————————————————————                     PHP初     —————————————————————————— order顺序 var(variables)变量 model典型 样式 模型 module模数;模块;组件 enctype SEO搜索引擎优化(Search Engine Optimization) Search搜索 Engine 引擎 Optimization最佳化,最优化 mod_rewrite模块重写 CMS 内容管理系统(content manage system) electronic commerce(电子商务) gc(garbage collection)垃圾回收   ---------------Apache与WAMP安装--------------- 1.wamp安装 apache (2.2版本) mysql(5.067版本)  php(5.2版本)   LAMP  Linux下的安装 负责版本控制 SVN 一台机器能安装多个apache服务 但是只能安装一个MySQL服务 -------------PHP上------------- PHP: personal home page  个人家庭主页  94年产生的 5.2.6版本 ASP: active  server page   93 JSP: java server page   类里面定义常量叫类常量 用const定义 类常量必须有初始值 define('','','false/true')里有三个参数,默认为false时区分大小写,反之不区分大小写 在类里面叫做方法  在类外叫做函数 常量默认为大小写敏感。 ::作用域操作符   标量和非标量类型的区别:标量只能存一个数据,非标量能存多个数据 (属性  变量名  类常量)区分大小写 (变量  类名  系统自带函数  自定义函数)不区分大小写  当$_POST['user_name']等没加‘’是会先当作常量来编译 3.函数 可变函数:函数的名字是一个变量 可选参数:参数有默认值 递归(recursive)函数体内有一个循环体,自己调用自己,但他跟死循环有区别,死循环是没有尽头的,     他是无限循环,递归有尽头,他最终会获得一个值 function pager( $page $msg_count $pagesize $url="?"){ }----》$url="?"即为可选参数     数组的合并 array_merge()              $arr1+$arr2 两数组相加: 只要是具有相同的下标,则只保留首次出现的元素,后者舍去 array_merge:索引数组会将后者的元素附加到前者后面;若是关联数组,相同下标,后者覆盖前者    explode() 取数组最后一个元素 8.文件的操作    mkdir新建目录    rmdir删除目录    skandir输出指定路径下的文件或目录    fopen(资源)— 打开文件或者 URL    fclose— 关闭一个已打开的文件    fgets — 一次读取一行    fgetc — 一次只读取一个字符    fgetss — 一次读取一行并过滤掉 HTML 标记    file_get_contents — 将整个文件读入一个字符串    fread-读取文件    file_put_contents— 将一个字符串写入文件    fwrite-写入文件    unlink-删除文件    pathinfo — 返回文件路径的信息 array_push — 将一个或多个单元压入数组的末尾(入栈) array_unshift — 在数组开头插入一个或多个单元 9.其它函数    输出控制函数:ob(output buffer) ob_flush    加密函数 md5    数学类函数:abs绝对值,rand随机数,ceil取整,floor,mt_rand生成更好的随机数    转换函数:explode 使用一个字符串分割另一个字符串,implode    时间函数:date(),strtotime (将字符串转换为时间戳)    处理地址栏: url_encode url_decode 10.乱码问题    ASCII(American Standard Code for Information Interchange)81年产生    ANSI 美国国家标准学会( American National Standards Institute)    utf-8(-8代表一次传输8个字符)可变字节编码(中文3个字节)(utf:Unicode转换格式(UCS Transformation Format)      utf-16(-16代表一次传输16个字符)    GBK. 国家标准扩展码(Guo-Biao Kuozhan)90年产生(双字节编码)    GB2312 因为国际排行2312位(81年产生)    BIG5    unicode (国际编码)可变字节编码    Latin_1    utf-8+ bom    ISO:国际标准化组织(International Standardization Organization)   11.数据库操作    数据库优化:char(查询速度快)               varchar        引擎:myisam(mysql indexed sequential access method)索引顺序访问方法        支持事务的引擎:BDB ,innodb        innodb:是以inno开头的一家公司的商标   表类型就是表的存储引擎     dll:动态数据连接库  封装的类库   修饰符:public,var,protected,private,static,final,abstract 访问权限修饰符:public,private,protected        public:类成员访问没有限制,多有外部成员都可以访问        protected:受保护的,不能被类外部成员访问,该类的直接子类可以访问,可以实现对成员属性的读、写操作        private:私有的,只能类里边的成员自己访问,类外部的成员都不能访问        一个属性被修饰为私有的(private),那么这个属性在类的外部是不可以读取和修改的,现在有一种方法 可以设置该属性既是私有的,还可以被类的外部成员读取即__get()和__set()    修饰class的修饰符:final,abstract(抽象) final被它修饰的类是不能被继承的 定义属性必须要加修饰符:可以是public和var 定义方法时可以有修饰符public,可以不写,默认为public   如果父类中的方法被声明为final,则子类无法覆盖该方法; 如果一个类被声明为final,则不能被继承。 final只能出现在class类和方法中   方法前可以有public,private,protected,static,final,abstract修饰。     继承性:耦合性越低越好  const修饰,一定要有初始值 ( smarty的保留变量:{$smarty.now},{$smarty.const},{$smarty.post},{$smarty.get},{$smarty.cookies},{$smarty.config},{$smarty.session},){$smarty.capture}  调用属性时,如果前有$后边就不能有,后有前不能有,如:$this->abc                                               self::$abc 当用parent调用父类方法时,将方法自动转化为静态的   多态性:由继承  重写(覆盖)(重新写一遍)(override重写)造成的             php不支持重载(重复载入),php为弱变量语言(overload重载)   抽象:一个类包含抽象方法就是抽象类,抽象类中不一定有抽象方法 抽象类的定义abstract 接口里可以有抽象类,还可以有类常量,通过interface来定义一个接口, 实现多个接口时,接口中的方法不能有重名。 接口中定义的所有方法都必须是public,这是接口的特性。 接口里的方法必须被重写 静态:static 不能与构造方法共存,static不能new对象,构造方法可以new对象,方法体中不能用$this   在php5以前的版本中,当普通构造方法和__construct(魔术方法)共存在时,它会调用普通构造方法,它对__construct(魔术方法)是不识别的,在php5以后的版本中,当共存时他会先调用__construct(魔术方法)。析构方法是最后被执行的,被自动调用的方法 单例(单态)singleton ——————————————————————————                     PHP中     —————————————————————————— 2.jQuery   包括javascript框架和prototype.js框架 选择器:   1.基本选择器:     ①、$('#result')=jQuery('#result')=document.getElementById('result')                            <div id='result'>                         <div class='result'>    ②、class选择器 $('.result')    ③、元素选择器$('div')   2.子代选择器:$('#myform < input')   3.后代选择器:$('#myform  input')   4.组合选择器:$('#myform < span < input') 3.Ajax  ajax的用处是用来异步js和xml 不仅可以获取xml数据,还可获得hmtl和json数据    ajax的优点:1.提升用户的体验2.占用带宽小3.减小服务器的负载    ajax就是把B页面的内容,显示到A页面的指定位置,实现异步传输    $.ajax() 返回其创建的 XMLHttpRequest 对象。    $.ajax({     url:,  data:,  type:,  datatype:,  success:function(这个参数里,存在被传回的页面的所有内容){}   });   $.post('请求地址','传递参数','回调函数');   $.get('请求地址','传递参数','回调函数'); post传值文件没有大小限制,保密性好,必须有form表单 get传值安全性不高,有大小限制 当地址栏里有中文时,用urlencode(编码 URL 字符串) urlencode — 编码 URL 字符串 urldecode(解码已编码的 URL 字符串)   4.会话控制         session:unset()和array() 是连同内存和session文件内容一起删除,而session_destroy只是将文件删除    cookie没有生命周期的叫会话cookie,随着浏览器的关闭,cookie消失    cookie有两种存在方式,一种是以文件形式存在,另一种是保存在内存里    cookie里面只能存字符串   会话控制主要是为了跨页面传值 序列化是把其他的类型转换成字符串类型 5.smarty 代码重用(include,require,include_once,require_once) include require 比 require_once include_once 性能高  加载类文件用 require_once(最好) include_once   6.PDO    dsn(data source name)    //数据源    $dsn = 'mysql:host=127.0.0.1;dbname=java1008a'; die('到此结束'); 等同于 echo '到此结束';die;   ----------------------------------------------------------------------------------   2.b/s与c/s简单比较,区别: --a、运行环境不同(广域网、局域网) --b、安全级别不同(低/高) --c、用户群不同(全部用户/局部用户) --d、系统升级不同(无缝升级/整体升级) --e、用户开启不同(浏览器/特制软件) --f、软件界面特点不同(信息流/用户体验)   比如:b/s就是网上的微博、博客;c/s就是在网吧打的网络游戏(奇迹、传奇等) 3.php是什么:运行在服务器端的脚本语言 --Hypertext Preprocessor --personal home page 4.php语言能做什么 --图形化用户界面程序 --服务器端运行脚本程序   3.php外部变量$_POST[]、$_GET[];     特殊运算符   '.'是连接符   ".="是连接赋值   "@"屏蔽错误信息  $link=@mySQl_connect(主机,用户名,密码) 5.流程控制(顺序、选择、循环) ****************************************************************************** ****************************************************************************** 第三单元【字符串】 1.字符串的三种定义方式(单引号、双引号、定界符) ---单引号定义(转义\'和\\) ---双引号定义(转义\n \r \t \$ \\ \") ---定界符方法<<<eof   2.函数部分 explode/implode substr()** str_replace/trim/ltrim/rtrim   strstr(str, search)获得指定字符串最开始出现到最后的内容 strrchr(str, search)获得指定字符串最后出现到最后的内容 strpos(str,  search)获得指定字符串最开始出现的位置 strrpos(str, search)获得指定字符串最后出现的位置 ucfirst(str)将字符串第一个字母大写 ucwords(str)将字符串的每个单词的第一个字母大写 strlen(str)获得字符串长度 strcmp(str1, str2)比较两个字符串大小,                 返回负数表示 str1 小于 str2;                 返回正数表示 str1 大于 str2;                 返回零表示二字符串相同   urlencode(str)替换所有非字母数字的字符,变为%后面跟两位16进制数,空格变为+号 urldecode(str)对已%##编码的URL进行解析还原 parse_url(str)解析完整的url转变为为数组 parse_str(str,out)解析请求字符串转变为数组 htmlspecialchars()转换html代码为实体代码 printf/sprintf %b %d %c %x %s %f %X –    b           整数转成二进位。 –    c            整数转成对应的 ASCII 字符。 –    d           整数转成十进位。 –    f            单倍精确度数字转成浮点数。 –    o           整数转成八进位。 –    s            转成字符串。 –    x            整数转成小写十六进位。 –    X           整数转成大写十六进位。   1.数组和栈的操作   array_push(目标数组,字符串)将字符串压入数组的最后   array_pop(目标数组)将数组最后的元素弹出并返回 2.数组和队列的操作   array_unshift(目标数组,字符串)将字符串放到数组的开始位置   array_shift(目标数组)删除数组的第一个元素并返回 3.数组和指针的操作key() current() next() prev() reset() end() 4.预定义数组($_GET $_POST $_FILES $_COOKIE $_SESSION) ****************************************************************************** ****************************************************************************** 第六单元【其他常用函数】 date(format,[timestamp])//格式化时间信息,并返回 time()//返回当前时间戳信息   mktime(hour,minute,second,month,day,year) mktime(小时,分钟,秒,月,天,年)//取得一个日期的 Unix 时间戳   max()//取得最大值 -echo max(1, 3, 5, 6, 7);  // 7 -echo max(array(2, 4, 5)); // 5 -echo max(0, '1hello');     // 1hello -echo max('hello', 0);     // hello -echo max(-1, 'hello');    // hello -echo max(array(2, 4, 8), array(2, 5, 7)); // array(2, 5, 7) -echo max('string', array(2, 5, 7), 42);   // array(2, 5, 7)数组和非数组比较数组总认为最大   mt_rand(65,94)//获得随机数 round()//四舍五入取整 flush()//输出准备区内容 urlencode('张三')//返回字符串中,除了-_.之外的所有非字母数字部分为%后接两位 16进制数,空格转化为+ urldecode()//对已经编码的部分反编码 var_dump()//输出变量的详细信息(八种数据类型数据都可以输出)   chr(mt_rand(65,94))随机获得字母 ord(chr(mt_rand(65,94)))将字母转化为数字 basename(路径名)获得路径中文件名部分 strtolower转换小写   第七单元【php连接mysql】 *mysql_connect(主机,用户名,密码) 打开一个到 MySQL 服务器的连接 *mysql_select_db(数据库,连接数据库资源) 选择 MySQL 数据库 *mysql_query("set names utf8");设定字符集          *mysql_close() 关闭 MySQL 链接 *mysql_query(语句) 发送并执行一条sql语句 mysql_fetch_row(结果资源)从结果集中取得一行结果(索引数组) mysql_fetch_assoc(结果资源)从结果集中取得一行结果(关联数组) *mysql_fetch_array(结果资源)从结果集中取得一行结果(索引/关联数组) mysql_fetch_object(结果资源)从结果集中取得一行结果(对象数组)   mysql_errno()返回错误号码 *mysql_error()返回错误信息 *mysql_num_rows(结果资源)用于计算查询结果中所得行的数目 *mysql_affected_rows()获得受影响的结果数目 *mysql_insert_id()传回最后一次使用 INSERT 指令产生的自动增长 ID 值   mysql_result(结果集,索引行,字段)指定获取结果 mysql_free_result(结果资源)释放结果集 mysql_num_fields(结果资源)用于计算查询结果中所得列的数目 mysql_fetch_field(结果资源)从结果集中取得列的结果,以对象形式返回 mysql_pconnect()永久连接数据库   1.留言板建立数据库bbs,建立两张表leave_word和back_word(留言表和回复表)   leave_word:   字段       数据类型   id        int         主键、自增   title     varchar(20) 标题   content   text        内容   itime     datetime    添加时间     back_word:   id        int         主键、自增   leave_id  int         外键(留言id)   content   text        内容   btime     datetime    回复时间 4.删除留言,对无效、无用的留言实现删除功能(这时需要用get方式传递被删除留言id值) 5.修改留言,对需要修改(get方式传递被删除留言id值,再利用隐藏域方式传递给接收页面) 6.留言详细显示功能,有的留言内容比较多,在明细页面不可能全部显示出来(这时利用get方式传递留言id) 7.在详细页面可以实现回复功能和回复留言展示,步骤:制作一个回复表单和接收数据页面        3.构造方法和析构方法        构造函数:实例化对象首先第一个需要做的事情就是构造函数。一个小孩出生到5岁之前,所有的事情都是父母帮助做的,包括起名字、穿衣服、吃饭等等。        析构函数:一个对象被使用完后需要做一些善后工作,这些善后工作是不需要人为干预的,例如资源释放、变量删除等。例如:一个小狗死后,主人非常爱惜它,就把它埋在了家后园的一颗树下。小狗被埋这件事情是主人做的,不是狗做的。这就是析构函数。        3.类的重写        子类和父类之间的事情,就是说父类有的方法,子类不但可以直接使用,还可以在子类中        重新定义具体内容,例如有一个父亲会驾驶汽车,那么他的儿子也会驾驶汽车,但他的儿子        可以不驾驶汽车,而驾驶飞机,这就是类方法的重写。      D    1.final(最后的)关键字使用        该关键字修饰的类不能被继承        该关键字修饰的方法不能被重写      2.static(静态)关键字使用(类的内部、外部、子类)        实例化对象在内存中的分配有讲到大的数据在内存被分配到堆空间里边。现在有一个例子:有一个        "学生"这个类,里边有一个成员属性是"国家",标识该对象是属于哪个国家的,比如美国、英国、德国等 ,这个类在实例化对象时候,每个对象在内存中都会分配一个空间用于存放国家这个成员属性,如果      有100个对象,那么在内容中会分配100个相应的空间。如果这个类的使用对象是在"中国"境内,那么      每个对象的国家属性就会是一样的,即"中国",相应的在内存中会有100个空间存放100个相同的内容      这会造成空间浪费,其实到这里我们可以知道100个相同的内容用一个空间存放就可以,反正都是一样的,        这就产生了静态化概念"static"。        用static修饰的成员属性,该属性就不是对象的,而是类的。      3.self和parent关键字使用        在类的内部访问类中的成员(属性和方法),可以用"$this",该关键字泛指对象,这是访问一般的类        成员,如果访问的成员是用static关键字修饰的,就不能用"$this"了,因为用static修饰的类        成员是被类本身拥有,不属于任何对象了,这时候需要用"self"关键字修饰 self::成员        在类的外部访问类本身拥有的成员可以这样  类名::成员属性。        在子类中访问父类拥有的成员可以用parent关键字  parent::成员属性      4.const(常量)关键字使用        在php中可以定义常量,类外部用define定义,类内部用const定义。        常量的拥有者是类本身,类内部访问常量用 self::常量                       类外部访问常量用 类名::常量                     子类访问常量    parent::常量      6.魔术方法clone、__call、__autoload使用      clone:在一个项目里边我们有时候需要两个或多个完全一样的初始化对象,这时候可以使用clone技术      不用clone技术也可以,不过每个新的对象都需要初始化属性值,这样比较繁琐,也容易出错, 使用clone就比较简单,克隆出来的多个对象彼此是独立的,互不相干。            $p2 = clone $p1;    __call:在类的使用过程中,如果一个对象调用的方法不在类里边,那么这时候程序要报错,然后程序退           出不能继续运行。这样做用户体验非常不好,如果有一种方法可以使得程序报错完后可以继续运 行,这样的程序给人更智能、用户体验更好的感觉,这时候就可以用__call              public function __call($method_name,$args){               echo "你访问的方法:";               echo $method_name;               echo "参数:";               print_r($args);               echo "不存在";              }        __autoload:开发一个软件系统,往往里边会有很多类,在初始化类对象之前需要先include这个对                 象对应的类文件。所有的类不能都放到一个文件(文件臃肿,不易维护),这样就会在程               序开始处有很多的include列表,这样做非常繁琐,出现一个新的类就需要被include,               有没有一种方法可以使得被include的类文件在实例化对象时候才引入,否则不动作,               答案是有的,这时候可以用魔术方法__autoload                 function __autoload($className){                      include($className.'.php');                 }      8.子类继承父类时候成员修饰符限制,子类的修饰级别大于父类。例如父类的修饰符是protected,        则子类修饰级别是protected或public。父类是public的,子类也必须是public的       1.抽象类        在类里边定义的没有方法体的方法就是抽象方法,有抽象方法的类被称为抽象类。抽象类不能实例化对象。        所谓没有方法体就是方法在声明时候没有花括号和里边的内容。        作用之处:          例如:我有一个类"动物",里边有方法"吃食"(还可以有许多其他的方法)         动物这个类可以有许多子类例如:狗、鱼、鸟等,这些子类有一个共性就是都有吃食这个方法         一般的解决方法是:定义3个类,里边都有吃食方法。这样实现没有问题的,但是如果其中一个         类没有吃食方法,这时候程序是不给报错的。我们现在要做的就是3个类中任何一个没有吃食方法           系统就要报错。这时候就需要用到抽象类了。        抽象类按照字面意思理解就是对3个类的进一步抽象。抽象出来吃食方法。        抽象类技术特性:        a、抽象类不能实例化        b、类的成员方法是抽象的,则这个类也是抽象的        c、抽象方法体内没有实现细节,具体实现留给子类实现        d、继承抽象类的子类必须实现父类的抽象类,除非自己也是抽象类。             2.接口(插座实例)        当一个抽象类里边的全部方法都是抽象方法时候,这个抽象类就是"接口"。        接口技术特性:        a、interface声明        b、全部接口方法是public的,因此可以省略        c、接口只定义方法,没有具体方法实现        d、实现类用implements实现接口,全部接口方法都要实现        e、接口可以多实现,中间用逗号分开        f、接口是对抽象类的抽象,抽象类是对类的抽象,类是对事物的抽象。        g、接口不能实例化        (1)、抽象类和接口有什么不同         抽象类只能单继承,接口可以多实现         抽象类里面可以有抽象方法和普通方法,而接口里只有抽象方法         抽象类里面可以有自己的属性,而接口里面只能有常量         接口里面的方法必须是public的,而抽象类不同        (2)、抽象类和接口的相似之处         抽象类里面的抽象方法在继承的时候必须都要重写,接口里面的方法也必须都要实现。         抽象类和接口都不能直接实例化,        抽象类需要继承(extends),接口需要实现(implements)。         抽象类和接口都体现了多态的特性。   3.jquery        jquery是js的封装包,里边有很多集成的函数可以让我们使用,jquery的宗旨就是写更少的代码实现更多的功能        使用的方法:        1.引进jquery包               <script type="text/javascript" src='jquery-1.4.2.js'><script>        2.测试jquery是否加载成功               $(function(){                      alert("jquey加载成功");               })        3.获取页面的元素               $('#div');通过id获取页面元素                 $('.div');通过class获取页面元素        jquery中的事件        1.$('#mydiv').click(function(){});鼠标点击事件【要写在onload事件里边】        2.$('#mydiv').hover(function(){},function(){});鼠标移动到对象事件        3.$('#mydiv').attr();获得对象属性信息        4.$('#mydiv').attr('checked');查看单复选框的选定情况!        5.$('#mydiv').css();获得对象的属性信息        6.$('#mydiv').css(样式,值);给对象赋予样式        7.$('#mydiv').addClass('trb');给元素class属性赋值trb;        8.$('#mydiv').removeClass('trb');使元素失去class属性;        9.$('#mydiv').submit(function(){});提交事件;        10.$('#mydiv').keyup(function(){});键盘敲击事件;             在项目中的使用:表单的验证   20.  * 什么是单一入口(单点入口)呢?         所谓单一入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发,         比如说在上面我们就使用index.php作为程序的单点入口,        当然这个入口文件的名字是可以由自己任意定义的。        单点入口有几大好处:            第一、一些系统全局变量,都可以在这里定义。            比如说你要对数据进行初步的过滤,你要模拟session处理,            你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面            第二、程序的架构更加清晰明了。  
文章
JavaScript  ·  前端开发  ·  PHP  ·  数据库  ·  索引
2013-01-07
腾讯后台面经大全(整合版)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a724888/article/details/81186950 微信公众号【Java技术江湖】一位阿里 Java 工程师的技术小站。(关注公众号后回复”Java“即可领取 Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源) ​   **本文里的面经内容全部来源于牛客网,作为秋招备战复习与查缺补漏时使用。里面部分面经有我的注释和想法,以及部分解答,不一定正确,大家可以查询补充。**   作者:牛客5143046号 链接:[https://www.nowcoder.com/discuss/89164?type=2&order=3&pos=25&page=1](https://www.nowcoder.com/discuss/89164?type=2&order=3&pos=25&page=1) 来源:牛客网 腾讯提前批一面  Tcp如何实现可靠传输  如何处理syn flood  Os如何实现内存管理  进程间调度和上下文切换怎么实现  系统调用或者说中断的过程  软中断 硬中断  内存延迟分配怎么实现的  了解vfs吗  了解云计算,虚拟化吗  内存分配的系统调用是什么  Linux里的Rcu知道吗  Linux里有哪些锁  有哪些自旋锁,分别是怎么实现的  Linux的地址空间布局是怎么样的  为什么内核映射到每个进程是一样的,如果每个进程的内核映射是不一样的会怎么样   还有一些,实在想不起来了 一直在虐操作系统,简直懵逼 作者:牛客5143046号 链接:[https://www.nowcoder.com/discuss/89164?type=2&order=3&pos=4&page=0](https://www.nowcoder.com/discuss/89164?type=2&order=3&pos=4&page=0) 来源:牛客网 腾讯提前批一面  Tcp如何实现可靠传输  如何处理syn flood  Os如何实现内存管理  进程间调度和上下文切换怎么实现  系统调用或者说中断的过程  软中断 硬中断  内存延迟分配怎么实现的  了解vfs吗  了解云计算,虚拟化吗  内存分配的系统调用是什么  Linux里的Rcu知道吗  Linux里有哪些锁  有哪些自旋锁,分别是怎么实现的  Linux的地址空间布局是怎么样的  为什么内核映射到每个进程是一样的,如果每个进程的内核映射是不一样的会怎么样   还有一些,实在想不起来了 一直在虐操作系统,简直懵逼 作者:给个offer养家糊口 链接:[https://www.nowcoder.com/discuss/76678?type=2&order=3&pos=49&page=1](https://www.nowcoder.com/discuss/76678?type=2&order=3&pos=49&page=1) 来源:牛客网 感觉凉凉。。 1,讲项目 2,项目用到了redis,讲一下redis的主从复制怎么做的。。讲了挺久的。。 aof和rdb两种同步方式 3,写代码,去掉字符串中的空格空格,C语言实现(虽然写出来了,但是面试官说4行代码就能写出来这个。。)(2年没写过C和Cpp了崩溃。。) 4,如何把一个文件快速下发到100w个服务器(不会) (面试官之后说你可以想想迅雷是怎么做到下载速度那么快的) p2p的下载,分发文件到整个网络中,每个机器既能上传又能下载 5,如何判断一个图是否连同?(开始说DFS,面试官说不满意,后来说并查集) dfs判断节点个数。并查集看是否所有节点的根节点是否能够相同 最后面试官要我加强一下C和Cpp。。 欢声笑语打出GG,我的BAT梦。。秋招再见了。。 作者:给个offer养家糊口 链接:[https://www.nowcoder.com/discuss/75986?type=2&order=3&pos=145&page=1](https://www.nowcoder.com/discuss/75986?type=2&order=3&pos=145&page=1) 来源:牛客网 我猜我是凉了。。 面试官是个挺严肃的小哥。。自我介绍和项目介绍也没有。。擅长的东西基本上都没问。。 题目不是先后顺序的。。想起来就补充。。 1,写SQL 2,左连接 3,TCP和UDP的区别 4,1000w个整数排序,范围0到100w,8g内存 MapReduce 5,网络的4层结构?TCP协议属于哪一层?TCP四次挥手的过程?最后等待关闭连接要多长时间?(时间真忘了。。)超时重传是怎么做的?ACK序号是表示已收到的序号吗?(卧槽我说的是的。。没理解他想问的是重传这块。。) 2msl。 ack是表示返回已收到的序列。 超时重传是对每个序列做一个计时器,然后如果没有收到ack则说明超时,重传 6,HashMap解决冲突的方法,Java里面怎么实现的 链表和红黑树 7,设计题,给每个组分配不同的IP段,怎么设计一种结构使的快速得知IP是哪个组的(开始想直接NAT协议搞一搞每个IP一个组的。。面试官说场景不对是给每部分的IP分组。。想用Trie树,面试官让我再优化一下。。) b+数,每个树节点保存一个段 8,非递归完成二叉树的先序遍历(差点没写出来。。用的左神教的Morris遍历。。) 先序用栈 中序用栈 后序用两个栈 9,什么情况下会发生死锁,解决策略有哪些? 1 独占资源 2 依赖对方资源 3 循环依赖 4 不能剥夺。 预防 避免 检测解除 10,Java怎么进行垃圾回收的?什么对象会进老年代?垃圾回收算法有哪些?为什么新生代使用复制算法? 11,讲一讲Java里面的final关键字怎么用的 12,重载和重写的区别?相同参数不同返回值能重载吗? 不能 13,讲一下快速排序的思路? 最后问了问腾讯真的要Java么。。面试官说他们是腾讯云的,语言不怎么重要都要写的。。 其它的记不得了。。想起来再补充吧 作者:MeiduiQing 链接:[https://www.nowcoder.com/discuss/75868?type=2&order=3&pos=158&page=1](https://www.nowcoder.com/discuss/75868?type=2&order=3&pos=158&page=1) 来源:牛客网 西安腾讯后台一面 挂经 面试官高级大佬,穿着拖鞋和短裤面试,看到面试官抖腿就有点虚。 全程大量手写问题: 手写快排 手写,创建一张用户表 create table A not exist { id, int(3), not null, primary key; name, varchar(20), not null; sex, tinyint(1); } 写一个类,修改刚才的用户表 alter table add column(address, varchar(30)) alter table delete column(address) 写出你熟悉的Linux命令 文件:ls ll -a la 进程和文件:ps,top,df,du,pstree 网络:netstat,ping,curl,traceroute 文本:cat,vi,wc,grep,awk,sed,head,tail,more,less, 查找:whereis find -n locate which 权限:chmod chown 777 su sudo 定时任务和后台执行:crontab nohup &后台执行 写出你熟悉的JVM命令(面试官提示:字节码 JStack,自己没反应过来) jstack,jmap,jstat,jmat,jps,jvisualvm 编辑器怎么deBug 怎样查看一个Java进程的使用情况(关于deBug,在编辑器上敲指令被追问很多) jps看进程,可以jstack看线程的调用栈,运行时可以跟踪线程的堆栈结构。也可以通过visualvm JUnit知道吗,写你知道的命令 Assert.assertEquals Assert.assertTrue mock,before,after。 写你知道的Git命令 git init git pull git fetch git merge git add git commit git push git reset --hard git stash git stash pop 手写单例模式(光说双加锁了,被指出来有地方写错了) volatile修饰单例 1 判空 2 加锁后再次判空 3 实例化 写你用过的jar包 rt.jar hibernate.jar spring-mvc.jar spring-context.jar spring-aop.jar redis-client.jar fastjson.jar spring-boot-starter.jar 简单将了一下毕设用的技术,GG 你的职业规划是什么 已收获好人卡,还是要滚去学习了 作者:名字不给看 链接:[https://www.nowcoder.com/discuss/75533?type=2&order=3&pos=190&page=1](https://www.nowcoder.com/discuss/75533?type=2&order=3&pos=190&page=1) 来源:牛客网 具体几面记不清了,大概问了: springioc,aop,mvc ,分布式存储架构 一般存储使用raid冗余阵列或者SSD快速磁盘。 分布式存储方案 1 块存储 直接对磁盘进行裸盘映射使用,甚至不安装文件系统,使用起来比较麻烦。 2 文件存储,基于文件系统使用存储,通过网络协议访问,比如ftp。一般是单机的存储系统。 3 对象存储,包括控制节点和存储节点,控制节点存储元数据,存储节点存储数据,一般通过api使用。类似hdfs,结合块存储的速度和文件存储的易用性。并且支持并发读写 ,异常, 请求失败怎么办, 重发 加锁失败怎么办, 轮询cas 回滚失败怎么办, 记录日志,重试 加密算法, 1 md5,sha摘要算法,非对称加密 2 rsa是对称加密算法,有公钥私钥之分,比较复杂。 间隙锁(可重复读有没有间隙锁,你确定?), 可重复一般不能避免幻读(但是mysql中可以,它使用了gap lock+行级锁的加强版:next key lock来避免幻读) 序列化则是加表锁。 当然使用mvcc机制也可以解决这个问题 mvvc,存储引擎, b,b ,红黑树, 三次握手四次挥手,进程线程区别, 进程通信,jvm内存模型,gc机制… 祝各位好运。两次二面挂,已绝望。 作者:燕大咸鱼干 链接:[https://www.nowcoder.com/discuss/75171?type=2&order=3&pos=248&page=1](https://www.nowcoder.com/discuss/75171?type=2&order=3&pos=248&page=1) 来源:牛客网 1 、先自我介绍,然后看我简历问我通信的为什么通信的选择做互联网?(我能说是因为钱多吗?当然不能,我就说互联网发展前景好,然后两人简单聊了一下)。 2、然后问我语言、计算机网络、数据结构、操作系统哪个比较擅长?(我答语言吧) 3、接着问我C语言中的内存分配,malloc函数? 4、谈谈Java中的内存模型? 5、讲一下你对多线程和多进程的了解? 6、为什么是三次握手,两次可不可以? 7、窗口滑动和拥塞控制? 8、问了一个操作系统的东西,没太听懂,我就直接说我不知道!  9、用代码写一下如何求二叉树的最大深度? 先序遍历求高度 作者:做一个白日梦 链接:[https://www.nowcoder.com/discuss/75109?type=2&order=3&pos=258&page=1](https://www.nowcoder.com/discuss/75109?type=2&order=3&pos=258&page=1) 来源:牛客网 二.腾讯 腾讯23号内推的,结果没收到提前批电话,最后通过笔试得到的面试机会,不过因为自己数据结构这块确实太菜了,二面挂 一面: 一面过的出奇的轻松,大概因为面试官不是做Java的,面试官就让我介绍了下项目,然后让我说个自己学过的最难的数据结构。。。没说出来,就让我走了,结果第三天收到复试通知 二面: 1.介绍项目 2.有一个页面能同时展示两个广告,现在有五个广告,设计算法使五个广告展示概率为1:2:3:4:5 搞出一堆数,按比例放,然后轮询展示 3.有25匹马,五个赛道,用最少比赛次数将25匹马排序 链接:[https://www.nowcoder.com/questionTerminal/e07d8e0df93b4f6b93a3fadbe72f2c7c](https://www.nowcoder.com/questionTerminal/e07d8e0df93b4f6b93a3fadbe72f2c7c) 来源:牛客网 毫无悬念,一匹马只有跑了才能看出其速度,25匹马至少都跑了一次,最少五轮,且每轮能排出名次;由于最终只要最快的三名,顾每组只有1、2、3有意义继续比下去,4、5名直接淘汰。每组的3有意义的前提是该组的2就是总排名的2、1就是总排名的1,每组的2有意义的前提是该组的1至少第二;归根到底还是看每组第一的情况,故5个第一比一次,第一就是总的第一;第四、第五及其所在的组全部被淘汰;故第一的组的二、三名,第二的组第一、二名;第三的组的第一名比最后一次,前两名就是总的二、三名;共七轮。      a1,a2,a3,a4,a5;------>a1,a2,a3;      b1,b2,b3,b4,b5;------>b1,b2,b3;      c1,c2,c3,c4,c5;------>c1,c2,c3;        d1,d2,d3,d4,d5;------>d1,d2,d3;        e1,e2,e3,e4,e5;------>e1,e2,e3; a1,b1,c1,d1,e1;------> a1 ,b1,c1 a2,a3,b1,b3,c1;------> a2,a3 ; 作者:anyco 链接:[https://www.nowcoder.com/discuss/75031?type=2&order=3&pos=268&page=1](https://www.nowcoder.com/discuss/75031?type=2&order=3&pos=268&page=1) 来源:牛客网 一面 ①项目中,redis在项目中用来干什么,基于什么考虑。讲了频繁访问的数据放到redis中,还有拿redis做异步任务队列。 ②单机redis有可能挂掉,解决措施。 1 单机做持久化,主从部署 2 哨兵或者集群 ③集群redis挂掉的话,解决措施。讲了把数据访问直接转到mysql(面完想了一下,是不是最好加一个异步任务队列来数据库操作)。 整个集群挂掉只能异地容灾了啊 ④redis挂掉了,然后现在恢复了,怎么做,redis挂掉的这段时间,你是把在mysql上存取数据,这样势必要同步数据到redis。但是同步这个过程你redis是需要被访问的,解决措施。然后我给了方案说redis和mysql完全同步之后,再拿redis访问。 1 同步后访问 2 增量同步 3 主从,写入主,访问从 ⑤数据库分库分表,垂直和水平来分。如果某个问题数据暴增,讲了用分类来作为分库的依据。又给了场景,如果某类问题数据暴增,要怎么做。后面面试官说了基于预测,可以先做一些冗余的库。比如某类问题可能会有数据暴增,那可以对这个模块加冗余的库。然后冗余库接下去怎么用这个没听清楚(hash??)。 1 垂直分业务,水平分数量。 2 划分依据,比如id,时间戳,根据场景,比如某一个类。 3 分片的规则就是进行hash,取模等方式进行。 4 最好使用数据库中间件如mycat ⑥负载均衡。讲了应用集群,nginx。 nginx的7层负载和四层负载均衡 1 LVS的四层负载均衡,nat,只是改了目标ip而已,返回需要回到代理 2 lvs的二层负载均衡 用虚ip访问,修改mac地址,返回不需要回到代理 3 lvs的三层负载均衡 用虚ip访问,使用隧道技术,返回不需要回到代理 ⑦nginx怎么去判断某台服务器的负载情况,然后转发请求。 应该是定时报告Nginx各个机器的情况,当然数据需要存在配置中心比如etcd中,服务器和etcd保持心跳,发送负载情况,nginx从etcd获取机器情况,可以支持机集群的伸缩。 ⑧在nginx+10台服务器的集群中,某个服务器挂掉了,这个时候nginx怎么处理(这时nginx肯定不能把请求转到这个服务器,那要怎么办)。 和我刚才说的一样,使用etcd这样的服务注册中心即可。 二面 ①java里面抽象类和接口区别。同步机制的方式。 ②接口能不能直接执行方法。 ③冒泡、快排、堆排。空间复杂度。 ④tcp、udp区别。tcp粘包。 ⑤八个球,有一个比较重的,给一个没有刻度的天平,怎么最快找出。 3和3称,相同再称,2次搞定 ⑥怎么看因为工作换主语言。 ⑦数据库分库分表。 ⑧家庭情况、女票、互联网行业高压、腾讯文化、房价,足足聊了十几分钟 ⑨个人提问环节,说了秒杀系统的设计,爆发性增长的数据给数据库带来的问题。 PS:全部面试走完,让师兄在内网查了,状态是offer报批中,也不知道是个啥状态。。 二面的问题可能会让你们比较惊讶。。。 作者:BugFree 链接:[https://www.nowcoder.com/discuss/74961?type=2&order=3&pos=284&page=1](https://www.nowcoder.com/discuss/74961?type=2&order=3&pos=284&page=1) 来源:牛客网 写在前面 面试官超nice,以一种聊天的形式跟你交流。上午10点10左右开始,11点40结束。总的来说,基础还可以,但是有些东西的底层学的还是不够深。 问题回忆 1.  自我介绍 1.  怎么平衡科研与项目开发之间的时间 1.  说说你在项目里做了哪些工作 1.  简历里提到了代码重构,为什么重构?怎么重构的? 1.  了解网络编程吧?说说TCP、UDP的区别,最主要的区别是什么?什么时候用这两者?为什么握手三次(而不是2次、4次)?为什么挥手四次(而不是三次)? 1.  做一道题吧:有100盏灯,编号依次为1,2,3.100,电灯全部关着。现在来了100个人,第一个人把所有的灯开关按下;第二个人隔一个灯按下(2,4,6...);第三个人每隔两个灯按下(3,6,9...).第100个人隔99个灯按下(100),最后还有几盏灯,那几盏灯亮着? 1.  我看你用过SVN和git,说说它们的区别。 1.  知道哈希吧,说说哈希算法 1.  知道哈夫曼编码吗?我说本科时学过,他说那行,给你一堆数,构建一棵哈夫曼树。。。写完后,他笑着说,这题给你出简单了。。。 1.  你有没有什么想问的?(常规三问:您是哪个部门的,做什么?对我今天面试的表现,简单评价一下?对我今后的学习或者工作提些建议?) 作者:﹏*安分 链接:[https://www.nowcoder.com/discuss/74819?type=2&order=3&pos=312&page=1](https://www.nowcoder.com/discuss/74819?type=2&order=3&pos=312&page=1) 来源:牛客网 1.自我介绍 2.介绍一下项目,项目架构图画一下 3.数据库事务,项目中那里用到了事务 4.数据库隔离级别 5.linux系统用过没?没用过 6.java的网络编程,java中socket的使用,刚开始纳闷为什么狂问我java网络编程方面的东西,后来才知道腾讯基本用java来做网络编程,其他的都是用c 来实现。 7.udp和tcp的区别,tcp的流量控制,拥塞控制,tcp怎样保证可靠传输 8.http和https的区别,https是如何加密的,它的加密方式是怎样 9.今天又让我介绍区块链 10.java中的锁介绍一下 11.10亿个扣扣号,每秒有10万条请求查询过来,如何处理作者:﹏*安分 消息队列削峰,缓存查找,数据库集群 作者:少年已去 链接:[https://www.nowcoder.com/discuss/74814?type=2&order=3&pos=314&page=1](https://www.nowcoder.com/discuss/74814?type=2&order=3&pos=314&page=1) 来源:牛客网 发个面经,攒攒人品 一面 一面问的都比较基础,Java的四个特性,jvm内存空间,进程与线程区别,hashmap底层,快排,索引等等 二面 1.c++stl库 2.c++的vector和map和java的区别等等c++相关 3.加密算法 4.innodb和MyISAM 5.数据库MD5加密方法的具体实现 6.三级范式 7.索引 8.数据库CAP 9.进程的结构 10.进程的调度 11.进程通信方式 12.手画TCP三次握手四次挥 13.http协议 13.手写快排 14.堆排 16.二叉树,字典树,红黑树的自旋 17.并发,自己做业务选怎样的进程控制方式 18.socket 19.xms调优 20.哈希算法 总结: 腾讯主要是c++的,java招的很少,所以二面会问你好多c++相关的,根本不会,二面面试官也问了如果过了,能不能转c++,总之凉凉,但是面腾讯收获还是挺大的,面试官会给你一些很好的建议。 作者:johnnydd 链接:[https://www.nowcoder.com/discuss/74787?type=2&order=3&pos=319&page=1](https://www.nowcoder.com/discuss/74787?type=2&order=3&pos=319&page=1) 来源:牛客网 现场面的,一进去看到面试官我就蒙了,同学上午面的,他的面试官是个年轻小哥哥,我下午,面试官看着40来岁,我当时心就凉了一节(这肯定是个部门老大什么的吧...),然后全程表情很严肃,像是一直质疑我,我很纳闷,说到最后,我都有点不想去思考问题,只想快点结束 首先简单自我介绍,然后简单说了下项目,我项目用到了mycat,问我底层如何实现,不会, 问了我为什么用dubbo,他一直质疑是因为我的项目做的很大,一个人无聊做着玩什么技术也往上面放, 然后面试官的意思是我自己做的东西既然没有那么多并发量就不用考虑那么多技术,意思是要用一个东西要知道为什么要去用,跟他扯了半天真的不想扯……心里苦 然后问了Java虚拟机内存模型,四次挥手,还有个慢启动快重传,我这个网了……一下说成之前操作系统学过这个,我俩都冷场了一下…… 问了linux进程相关的, hashmap concurrenthashmap 内部实现细节, 然后还有触发器是什么, 问了个智力题, 8个球一个重给个天平,最少算几次, 然后就是千万的数据求前100个最大重复的,大学做过印象最深刻的事情,有什么想要问我的? 基本就是这,半个小时整,面完我心凉了 1 采用Hash+小顶堆 Hash就是为了统计每个数出现的次数,然后发生冲突的地方用个链表把它链接起来,在每个节点中存储一个含有data和count成员的结构体,data记录相应的数字,而count记录对应的数字出现的次数,这一步的时间复杂度是o(n).(注意这里虽然数字很多,但是因为会存在大量的重复数据,不用担心最后的空间会有10亿) 然后创建一个大小为100的小顶堆,然后将Hash表中前面100个非空的成员放入小顶堆中,然后将hash表中的其他数据和堆顶出现的次数比较,如果比堆顶出现的次数少,则丢弃当前数,如果大于堆顶元素的出现次数,则替换堆顶,然后进行堆调整,这一步时间复杂度是o(nlog100). 总的时间复杂度是o(n)+o(nlog100) 2 用一个bit数组 data[十亿]初始化为0 读取数据i,若 data[i] == 0 ,data[i]=1; 否则 记录用一个结构体记录i,并记录他的的次数。最后则可以 求出 出现次数最多的数整数 作者:SFISH 链接:[https://www.nowcoder.com/discuss/74718?type=2&order=3&pos=349&page=1](https://www.nowcoder.com/discuss/74718?type=2&order=3&pos=349&page=1) 来源:牛客网 先说下最遗憾的,叫写冒泡排序都能写数组溢出,非科班面对算法题真的紧张。凉凉。 面试官是做php的,我用java。 问了http和https的区别。 答: 后者是前者的安全实现,客户端发起请求时服务端会返回一个公匙,然后客户端根据公匙规则发送消息,服务端根据自己的配对密匙解密实现加密。 那公钥放哪里呢? 数字证书 答:请求头。(面试官笑,是这样吗?我说这一块我理解的不够深就跳过去了) 问: session和cookie讲一下? session的出现是为了解决cookie存放本地而且量小的问题产生的,通过浏览器缓存的技术把需要的信息缓存,服务端就可以在同一应用中不同页面传递数据,我觉得服务端采用的是hash表存放的信息。 那怎么知道是哪个客户端呢? 这个刚忘讲了,服务端会发送一个id标识客户端。 sessionid 问:进程线程讲一下 进程由操作系统调控,线程由进程调控(忘了讲一下内核和用户线程的映射,太紧张了),就好像一个java程序就是一个进程,里面很多线程,比如生产者消费者模式,进程就像框架框住他们,生产者消费者就是两个线程,在这个框架里面生存,做资源交换。 问:那进程的通信呢? 我知道共享内存,还有管道和信号量就不太了解了(紧张,脑子有点空白),信号量我知道java并发包下的信号量,如果您需要我可以跟您讲。 问:线程怎么共享资源 (我其实很想讲java内存模型,但是面试官就这么不喜不怒我也不知道要不要回答这个)我以jvm为例讲一下吧,jvm里的堆就是一个公共区间,线程负责来取资源,这样就可以实现资源共享,如果您需要问原理,我可以跟您讲一下内存模型。(面试官又是java开发,所以我真不知道要不要把底层讲的很细) 问:讲一下反射机制(我提到spring的ioc就是反射机制,但是我说我不会spring写项目) (面试官也知道反射机制的么)在类加载的加载阶段会产生java.lanag.class对象,而且初始化阶段jvm也规定由reflect包下的方法必须加载进来,这样就可以通过class forname动态加载类获得对象和调用getclass获得class对象,然后再用newinstance方法获得对象,然后就可以了(又忘了讲类加载) 问:讲一下hashmap和hash冲突 1.7的时候用的是数组加单链表,1.8变成了红黑树(忘了讲初始容量和扩容问题,大佬的不怒自威太可怕,不知道该怎么),讲了一下取哈希值的改进,可以算的更快 (这里提一下,大家应该发现面试官都在问hashmap,因为java8的一个核心优化就是hashmap,所以多看看博客) 好像差不多就这么多,很伤心面试官没有问jvm和底层锁,不然我可以跟它就这个话题扯10多分钟) 总得来讲,我觉得冒泡排序我真的想自宫,为什么这个我都能写错??? 反正我只是来见大佬的,一个遗憾就是问的大佬的问题大佬表示都不方便回答。 好了,今年java想找工作,就把自己当成全栈工程师来努力吧,毕竟今年天下研发皆java,所以我当初是不是应该坚持一下走深度学习? 秋招再见! 作者:yunux 链接:[https://www.nowcoder.com/discuss/74614?type=2&order=3&pos=360&page=1](https://www.nowcoder.com/discuss/74614?type=2&order=3&pos=360&page=1) 来源:牛客网 刚现场面完一面,凉凉。。。。。。 走的内推,可惜时间投的比较晚,3.21号投的,结果3.30号才来电话,全程差不多聊了一个小时,问的很详细也很基础。 1、项目介绍,大约15分钟。 2、基础,大约15分钟。 2.1、Java Map结构?(脑抽了orz) 2.2、进程、线程区别?线程共享进程哪些资源? 同一进程间的线程究竟共享哪些资源呢,而又各自独享哪些资源呢? 共享的资源有 a. 堆  由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的) b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的 c. 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的 d. 文件等公用资源  这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。 独享的资源有 a. 栈 栈是独享的 b. 寄存器  这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC 2.3、TCP三次握手,四次挥手?为什么三次?TIME-WAIT状态? 2.4、Linux Socket相关。 2.5、Linux指令,查看一个进程打开哪些文件 lsof -p pid lsof命令是什么? 可以列出被进程所打开的文件的信息。被打开的文件可以是 1.普通的文件,2.目录  3.网络文件系统的文件,4.字符设备文件  5.(函数)共享库  6.管道,命名管道 7.符号链接 8.底层的socket字流,网络socket,unix域名socket 9.在linux里面,大部分的东西都是被当做文件的…..还有其他很多 怎样使用lsof 这里主要用案例的形式来介绍lsof 命令的使用 1.列出所有打开的文件: lsof 备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位 2\. 查看谁正在使用某个文件 lsof   /filepath/file 8\. 列出某个用户以及某个程序所打开的文件信息 lsof -u test -c mysql 10\. 通过某个进程号显示该进行打开的文件 lsof -p 3、数据结构和算法,大约25分钟。大多剑指原题。 3.1、二叉树,BFS、DFS,Python怎么实现?口述代码(没讲好gg) 3.2、字符串最长升序序列,动态规划。 dp 3.3、数组中数字出现的次数,一个数组中除了两个数字只出现一次,其他的都出现两次,找出这两个数字?位运算。 3.4、Top-K问题,海量日志数据,提取出访问次数最多的那个IP。分而治之+Hash+堆。(思路算对,但是没回答好orz) 分治,hash,堆 4、闲聊,大约5分钟. 结束后没收到二面,清明做笔试,性格测试。 * * * 今天4.15一面,去了扫码签到,很快就上去面试,面完很丧。。。。。 全程25分钟左右,自我介绍,然后项目介绍,Java多线程同步怎么做?(没回答好orz),会不会C++(答好久没用了,现在用Python和Java,回答完后就感觉面试官没啥问的了), 动态规划了解不?说一下快排,说完就结束了。。。。。凉凉。。。。。唉。。。。。没说留简历也没下次面试的事,感觉很丧,都没怎么问问题,感觉面试官兴趣不大。。。。。悲伤的故事。。。。。 作者:家有二呆 链接:[https://www.nowcoder.com/discuss/74046?type=2&order=3&pos=426&page=1](https://www.nowcoder.com/discuss/74046?type=2&order=3&pos=426&page=1) 来源:牛客网 笔试后面试 一面,先自我介绍,然后做了两题手写代码(手写代码实现查询链表的倒数第1000个节点,一个struct,里面有多种类型变量,给一个指针指向这个结构,然后让我算指针偏移后的地址), 一题算法思考(1000万个关键字,每个关键字小于等于50字节,求前K个热词,内存为1M)。 分治+堆排序 接着开始对着项目问,问了一下我Reactor模式,RPC框架原理。一面过。 io多路复用,异步事件 远程调用转化为本地调用 二面,上来先自我介绍,接着对着我项目问我springboot的aop,动态代理,问我日志的时候,由于自己忘记怎么切日志,有点忘了。 接着面试官站起身来, 拿了一题算法题。我定睛一看,实现12306余票查询的关键数据结构与算法。 车次 + 时间:车厢 + 车座。两层hash+一层数组即可。 当时就感觉凉了,耐着性子和面试官讨论,面试官引导我这个和座位有关,慢慢 写了个简单版的。 面试官很nice,虽然我写的渣,也没说我什么,然后就问了一下我微服务,有什么缺点,网络这块,问的很深。 划分非常细,分布式问题要考虑的比较多。 对协议栈这块一定要有 思考,背那种tcp和udp的区别于应用,可能面不过TEG。 物理层,要么是电磁波要么是物理缆线。 链路层,基于物理层封装成帧,mac寻址,局域网可达 网络层,冲出局域网,全世界联网,路由 传输层,解决网络层的丢包,失序,低效等问题 应用层让浏览器发挥效果,让web应用成为现实 面完后,脑子都有点迷糊。如果大家投了腾讯的后台,如果又是TEG面的话,大家一定要复习好基础, 要有架构思维,一定要对不同的技术的优缺点能说个七七八八。 基本会问你技术对比,优势劣势。对了,还问了我如何学习新技术,这个大家一定要准备。 查看状态,进HR面了。 4月19 HR打电话,确定了信息,问是否愿意接受offer,答曰:愿意。 春招到此结束,祝各位都收到自己想要的offer。 作者:f*Snow 链接:[https://www.nowcoder.com/discuss/73842?type=2&order=3&pos=444&page=1](https://www.nowcoder.com/discuss/73842?type=2&order=3&pos=444&page=1) 来源:牛客网 1.创建对象的方法  2.序列化  3.线程池  4.http状态码,http头  5.证明一个数是2的n次方  1、通过循环除2;这种方法不值一提,略过; 2、针对32位/64位只有有限个 2 的N次方的常量值,逐个进行比较;额。。。这个也略过; 3、通过正则表达式进行文本匹配,判断是否2的后面都是 0 ;这个绕得更远了。。。 最后,有一种最简洁优雅的写法:(value & (value -1)) == 0; 喔,的确是简洁优雅!!! 6.堆排序  8.八大排序特点  9.链表的倒数第k个节点  答完了,面试官说挺好的基础还不错,晚上查状态还是挂了,想想可能细节回答的不好 作者:Masquerade° 链接:[https://www.nowcoder.com/discuss/73411?type=2&order=3&pos=480&page=1](https://www.nowcoder.com/discuss/73411?type=2&order=3&pos=480&page=1) 来源:牛客网 昨天收到腾讯的面试通知(考完腾讯的笔试以为挂了,就没抱希望,没想到还有面试机会) 给大家分享一下,就当攒个人品。 第一部分,远程笔试。 面试官发了个网页链接过来,给45分钟完成,网站是collabedit。 有6道题,挺简单的,十多分钟就写完了。 1、char *s1, const char *s2,删除s1中s2出现过的字符 2、删除单项链表中重复的节点 (1 2 2 3 3 9) -> (1 2 3 9) 3、求二叉树的深度 4、单链表判环 5、判断一个数是不是回文数 6、求一个数组的最长连续子序列 第二部分,电话面试。 先看了下我的答案,找了几个小的bug(root没有判断NULL,链表头节点没有判断NULL,还是不够严谨啊) 然后问我有没有别的解法,就算过去了。 然后聊项目,因为没什么项目,所以聊的不多,哎,为什么你们可以这么厉害,渣渣求一条活路。 然后问问题。 1、网络了解吗?讲一讲TCP协议的三次握手,为什么要有三次?(紧张,说得不够清楚,答的不好) 2、了解Linux吗?epoll了解吗? yes epoll create 红黑树 epoll ctl 插入节点 epoll wait 就绪链表 3、数据库了解吗,用过哪些数据库? 4、这些知识是你在网上看的还是课上学的? 5、还有什么问题要问我? 然后让面试官评价一下,其他的还行,经验不够足。 反思一下: 1)第一次面试,有点紧张,还是要多锻炼,把自己充分展示出来。 2)知识面不够广,还要多学习啊! 3)通知太晚了,准备不够充分。 4)多实践。 问的问题这么少,时间这么短,应该是挂了,给自己点一首凉凉,以后好好搬砖好好学习。 然后,各位加油。 /*********************** 后续 *************************/ 收到二面通知了,但是明天没空,点了时间不合适,不知道HR会不会打电话再约时间。 作者:挽歌 链接:[https://www.nowcoder.com/discuss/73302?type=2&order=3&pos=489&page=1](https://www.nowcoder.com/discuss/73302?type=2&order=3&pos=489&page=1) 来源:牛客网 成都腾讯现场面试,今天上午9点半,签到等了一会儿就进去面试。 1\. 自我介绍(面试官是写 C++ 的),然后简单说了两句项目 2\. 什么是分布式 多节点部署,分布式存储,分布式计算,分布式部署 3\. 我看到你项目里面用了 Redis,讲讲 Redis 4\. 让你设计一个 Redis 或者说一个  cache,怎么做 map。 5\. 给你一段逻辑连续的内存,你怎么设计(全程怼我怎么保证充分利用空间和动态分配) 压缩链表 6\. 讲讲常用排序的优缺点,应用场景 7\. 手写快排 8\. 让你设计一个视频点播,你怎么设计这个模块 视频分类,视频列表,播放使用udp 这个一开始我写的是功能模块,后来面试官明示说从接入、存储...来谈 9\. 在上面那个我说道了拥塞控制,就开始问 TCP 拥塞控制机制 10\. 既然你的设计就是类似 TCP(我用的 UDP 来设计),为什么不用 TCP 慢,需要建立连接,重发,保证有序等,实际上不需要 11\. 逻辑题:6个赛道,36匹马,找出 top 1(如果是 top 6 呢) 1 6次跑完还剩6只,再跑一次 2 很麻烦 12\. 兴趣爱好 13\. 你自己的优缺点 总共面了一个小时,两个设计怼的太久了,细节扣的很仔细。大家简历一定不要留坑! 作者:初生小牛不怕虎 链接:[https://www.nowcoder.com/discuss/71195?type=2&order=3&pos=653&page=2](https://www.nowcoder.com/discuss/71195?type=2&order=3&pos=653&page=2) 来源:牛客网 记性不大好,只能想到一部分了,后面想到什么再补充吧,暂时分享给大家这些,祝大家好运! 一面: 主要写Java是吧 内存模型描述一下 并发控制,锁怎么管理的 balabala不太记得了 手撕代码: 单链表倒置 二分法查找排序数组 二面: 介绍项目 自己负责的部分 做这个项目感觉有什么收获 手撕代码: 求两个集合的交集和并集 括号匹配,带优先级的小括号中括号大括号 30瓶水,其中有一瓶毒药,小白鼠喝了毒药之后一天会死,求只有一天时间,用最少的小白鼠找出毒药 输出a~z全排列 全排列算法或者dfs HR面: 自我介绍 项目主要做的啥?自己负责的部分? 觉得最不好解决的几个问题?怎么解决的? 家是哪里的,爸爸妈妈都是干嘛的 还投了别的什么公司吗?偏向于哪个? 找实习比较看中什么? 你还有什么问题吗? 作者:袖手旁观1111 链接:[https://www.nowcoder.com/discuss/70644?type=2&order=3&pos=721&page=1](https://www.nowcoder.com/discuss/70644?type=2&order=3&pos=721&page=1) 来源:牛客网 3.20 一面 自我介绍 全程聊项目,面试官会打断提问 面试官介绍自己部门(IEG) 3.27 二面 自我介绍都没有,面试官甩过来链接,直接开始写代码。 两道都是leetcode原题,medium 227\. Basic Calculator II 81. Search in Rotated Sorted Array II 旋转数组用二分 第一道只讲了思路没写出来,第二道写出来了 一小时后状态变成不合适,全程一个后台开发的问题都没有问。。。我怀疑面了假的后台岗位。。。 作者:这就是我的逃跑路线,jojo! 链接:[https://www.nowcoder.com/discuss/70311?type=2&order=3&pos=778&page=2](https://www.nowcoder.com/discuss/70311?type=2&order=3&pos=778&page=2) 来源:牛客网 腾讯: 前言:可以说是个传奇了,之前根本没报因为听说没java,后来群里有人说自己报了人家问他java了,心想着锻炼下面试,结果一直没消息,内推快结束了突然约我面试,还是现场。。走完一二三面跪在了三面 一面:面试官说自己这边主要后台用php和go,我说进来再转也行,面试官说好吧。。。 问:网络协议,三次握手挥手 答:blabla大概说说 好了,问题结束,面试官掏出一个本本让我开始撕算法,开启手撕算法加练写字的奇妙旅程 算法一:两个有序数组合并取中位数 我:balbla写写写(面试官发呆中) 我:写完了,您看看(自己看了眼字真的难看,自己都看不懂) 面试官:。。。。。。横看竖看左看右看,。。。好吧。。。。 1 合并完再求 2 合并过程中第n/2个数就是中位数 算法二:给定二叉树显示最右边的那一列节点(左神的书还是剑指offer的原题) 我:blabla写写写 面试官:你这写的是不是不对啊 我:。。。还真不对,改。。。写好了 面试官:emmmmmmm(内心os:这人真的不是外星人么,这啥语言?) 我:我所下思路,层次遍历先右后左,存个temp值表示当前层数,第一次加的是最右边的 面试官:好了,你等会 层次遍历只打印最右边的即可 二面: 问:自我介绍 问:aio nio bio了解么? 答:了解,blablabla 问:select epoll区别 答:blablabla 问:同步异步,阻塞非阻塞的区别 我:blablabla 问:并行和并发的区别 我:blablabla 面试官突然拿出一个本,没错就是刚才一面的那个,翻了一面让我写算法 算法三:写个hash 我:?????? 面试官:实现个hashmap,就最简单的那种 我:。。。照着jdk1.7的hashmap写了个,主要写了put 面试官:emmmmmmmm,下一个 算法四:一个树,找最长路径,说思路就行了(估计看我字难看) 我:递归找树深度稍微变下 面试官:今天到这,如果还有面明天通知 递归找深度存最大值 三面:领进去前说是总监面,让我在办公室外面坐会等了会让我进去了(ps:总监办公室窗子外面视野真好) 问:自我介绍 我:。。。。。 问:好了,拿出两张纸开始算法吧 我:。。。。 算法五:链表反转 我:。。。。。。。 算法六:找环入口 我:。。。。。。 好了撕算法结束 问:大量int,内存装不下,去重 答:之前没背过,现说的一方法,面试官不满意 面试官:今天到此结束 总结:谢谢腾讯面试官抽出时间给我这个语言不对口基础也不扎实的菜鸡面试,还给我练手撕算法的机会,一开始紧张的一逼,后面不紧张了,字也写到能让人类勉强看懂的地步了,收获很多。 网申 一面: 语言不合,撕算法 算法七:两个数组去重,分别根据无序和有序说下,写个有序的算法 算法八:给个式子,括号匹配,然后括号去了怎么算出结果 出酒店挂 总结:至此腾讯算法课堂正式结束,总共8道算法,秋招再见 作者:雄关漫道1 链接:[https://www.nowcoder.com/discuss/70129?type=2&order=3&pos=792&page=1](https://www.nowcoder.com/discuss/70129?type=2&order=3&pos=792&page=1) 来源:牛客网 【腾讯 - 微信&腾讯视频 - c++ - 已挂】 微信一面 - 暂无后续: 1.TCP三次握手和握手时client&server的状态,为什么不是两次握手; 2.syn flood了解吗? DDOS? 洪泛攻击,分布式请求攻击 3.select&epoll是什么?并发度各有什么限制? epoll为什么快? 就绪列表,根据场景 4.epoll的水平触发和边缘触发? 水平不断通知io就绪,边缘触发只有一次通知 5.进程间通信?哪个最快?为什么? 共享内存,不需要额外机制 6.XSS原理? 跨站点脚本注入。嵌入js代码导致页面被恶意篡改和重定向 7.为什么要用https?http的缺点? http明文传输不安全,https加密传输 8.https建立连接的过程? 数字证书,生成随机数,公钥加密,私钥解密,以后都用该随机数进行对称加密 9.非对称加密算法了解哪些? rsa 10.简单聊了聊项目。 腾讯视频一面: 1.TCP三次握手四次挥手的11个状态; 2.C++用过吗?说说函数重载; 3.函数重载的原理; 4.extern c的作用; 5.一致性哈希的性质,算法; 6.说说快排,时间复杂度是多少,怎么算的;(tips:设快排复杂度为T(n),由于一次partition复杂度为O(n),有   T(n) = 2T(n/2) + O(n)) 7.红黑树知道吗?说说; 8.聊项目; 腾讯视频二面 - 已挂: 加微信面,拍了张试卷,让半小时内手撕代码,悄悄泄题 ![](C:/Users/%E5%91%A8%E6%9D%B0%E4%BC%A6/AppData/Local/YNote/data/xll1025@163.com/213e0c824fc048a4b2d64074055b7283/052798f2f2e7.png) 1 lru缓存。过期删除。 2 删除空格,左移即可,或者计算空格数,然后从右到左把字符串排好。 3 使用长度为26的数组,存储0和1,0对于无,1对应有,一共2的26次方种情况,然后打印 作者:吴祚煜 链接:[https://www.nowcoder.com/discuss/70021?type=2&order=3&pos=802&page=1](https://www.nowcoder.com/discuss/70021?type=2&order=3&pos=802&page=1) 来源:牛客网 聊一聊今天的腾讯实习面经吧。。然后211渣硕。。 很早就内推了腾讯身边的同学早就接到电话面试了我迟迟没接到以为凉凉了。 然后昨天晚上突然就到电话叫我去面试。 然后我是第一次面试。之前准备的也都是Java,投的是后台,就抱着必死的决心去面试了。 第一次去漕河泾,那块的整体工作氛围还是不错的。约的是下午2点,提早到了,面试官还在午休,然后就上去了。 去了之后在他们的茶水间的面的试,一边喝茶一遍面试,整体气氛很轻松。 然后第一个问题是:你会C++吗,你对C++了解多少。(不会,本科课程要求水平) 第二个问题:那先做一套笔试题吧 笔试题题目大致如下: 第一部分简答: 1、析构函数 2、操作系统内存管理 3、Linux指令 4、Tcp/ip 5、TCP协议 还有几题记不太清了 第二部分撕代码: 1、快排 2、堆排(大、小) 做完之后就开始正式面试。由于我表达了我不会C++(建议大家对于不擅长的领域不要硬着头皮回答,干脆说不会比较好) 问了许多网络、操作系统的内容,这部分内容我在复习Java时都准备了,问题不难,都答上来了。 然后做了2道数学题: 1、桶中取球排列组合问题 2、二进制问题,问题如下: 1000瓶水有1瓶水有毒,老鼠喝一滴就会死,但是需要一周毒发,请问最少需要多少老鼠多少时间才能找到那瓶有毒的水。 答案是10只老鼠1周,解法是十进制转二进制 然后就问项目。具体就不展开了。 然后问了一下什么时候能来实习。就把真实情况汇报了。 然后一面就结束了。 比较感谢面试官没有因为C++而直接把我拒掉,面试时也没有在C++这方面为难我,而且整个面试过程非常轻松愉快,整体感觉一面有点话痨,就感觉面试官是我的一个同学一样亲切,感谢面试官。 然后他让我等5分钟他去问组长。然后组长就来面试了,二面开始了。 组长首先了解家庭情况,学校学习情况。 然后第一个问题:了解Socket吗?用过吗?(很巧我最近的一个项目正好用过就回答的比较好,顺便把项目介绍了一遍) 第二个问题:你研究生的研究方向是系统搭建吗?(因为我有一个导师安排的公司实习是有系统搭建的部分,但是我的研究方向是图像分类DCNN,于是我跟他解释了我的方向以及我为什么要搭那个系统) 第三个问题:你深度学习图像识别成果?(论文写好已投SCI,审稿中,然后顺便把我的框架,数据集,方法,环境啥的都介绍了一下,中间把之前本科时做的一个相关项目也介绍了) 第四个问题:你对你未来职业规划 第五个问题:你最希望做什么工作(问我这个问题估计是因为我不会C++) 大概就记得这五个了,感觉主要问的技术方面不是很多,还是侧重之前的实习、项目还有研究方向相关。顺便了解了一下我的想法。 二面的时候在对面试官提问环节我对面试官问了很多问题,也是我想知道的,我还让他带我逛了一圈他们的办公室。 然后就约我明天复试了。 总结一下今天的面试体验,漕河泾那边整体工作氛围很好,茶水间很棒,两位面试官都很好,然后感觉可能一位就是我以后的同事或者导师,一位可能以后就是我的leader。 然后对于C++知识不了解的情况,第一位面试官就主动帮我圆,编程都是相关的,只要你有足够的学习能力就没有问题,然后说如果以后进来想做Java也有机会,公司也有项目需要Java。 然后说了很多对实习生的培养的东西,大概就是主要了解你这个人的整体水平吧。 最后攒一波人品祝我明天好运吧! 作者:牛陌王 链接:[https://www.nowcoder.com/discuss/69623?type=2&order=3&pos=844&page=1](https://www.nowcoder.com/discuss/69623?type=2&order=3&pos=844&page=1) 来源:牛客网 1、自我介绍 2、数据库使用的怎么样等等 3、数据结构 *   B+树 *   红黑树 *   图的最短路径 *   等等 4、网络编程 *   高并发与异步的服务器怎么设计 网络io的话epoll大法好。异步就用回调模型呗, 高并发就要多线程开发代码。具体设计就是请求到达,处理,访问io,以及回复结果 *   epoll后的套接字怎么存 红黑树+链表 *   等等 5、项目 面试的是搜索平台的面试官,说可能做的工作方向和你做的方向不匹配,凉凉~ 作者:不稂不莠 链接:[https://www.nowcoder.com/discuss/68690?type=2&order=3&pos=953&page=1](https://www.nowcoder.com/discuss/68690?type=2&order=3&pos=953&page=1) 来源:牛客网 面试官背景:腾讯云平台部门 1. 自我介绍 2. 自己的项目介绍(下面的问题都是根据项目提问的) (1) 腾讯云COS对象存储的原理 (2) 为什么用Restful (3) 为什么Restful比传统的http好? 接口含义明确 (4) 还知道什么类似Restful的规则? cap maven (5) 用什么做接口数据传输(参数格式)?(json...) (6) Redis的应用场景? (7) 为什么不用memcached?和redis比较? (8) 权限是怎么做的?(介绍shiro)(介绍数据库实现权限的设计) (9) Redis用来缓存哪些信息?如果缓存的数据数据库更新了呢? 同步更新 (10) 用户的登录状态如何判断?Session过期问题?如何判断session过期?(这里感觉自己太依赖框架了)session是在哪一层面做的? session可以设置时限,判断使用方法就行了,服务器层面,也就是内存 (11) Js的继承?.id和#id有什么区别?DOM对象是什么意思? (12) 人生经历中记忆最深刻的困难或者事情?是怎么解决的? 3. 那我们现在来面基础吧好吧 (1) 进程线程了解吗? (2) 线程里面有什么是独立的? 操作数栈,局部变量,寄存器 (3) 一个进程一定要有一个线程吗?没有线程的进程是什么? 不用 守护进程 (4) 协程是什么? (5) 同步和互斥是怎么做的? (6) 线程间的同步和互斥是怎么做的? (7) 守护进程和僵尸进程,孤儿进程有什么了解? 1 孤儿进程是子进程未结束时父进程异常退出,子进程变成孤儿,init进程会认做他爹。 2 僵尸进程是子进程结束后,父进程没有显示发送通知,导致子进程的结构没办法被回收,变成僵尸进程,站用空间。 3 守护进程就是init进程,负责监控进程的状态,以及认儿子,杀死父进程等操作 (8) 系统出现僵尸进程,为什么产生和怎么解决? init进程会杀死父进程或者回收僵尸进程 (9) 软连接和硬连接了解吗? 硬链接不同名文件指向同一个node,软连接只是节点中存储目标文件的绝对路径 (10) 硬连接和软连接删了,原对象会如何? 硬链接会删除文件,软连接不会 (11) 硬连接和软连接的底层原理? 硬链接不同名文件指向同一个node,软连接只是节点中存储目标文件的绝对路径 (12) Inode是什么? 文件的根节点,存储除了文件名之外的所有元数据信息。真正存储着数据所在硬盘地址的节点。 (13) 强类型和弱类型,静态类型动态类型是什么? 强类型如java,弱类型如Python (14) TCP/UDP的了解? (15) Tcp和udp的使用场景 (16) Tcp粘包 发送缓冲区和接收缓冲区处理不及时或者大小设置不当,导致粘包和拆包 (17) Tcp的time_wait (到这里我觉得面试官面不下去了) (18) http1.0和1.1有什么区别 header,长连接,二进制 (19) https协议?原理?端到端中间的过程。 (20) 对称加密和非对称加密? (21) Cookies和session的关系 (22) Cookies的最大保存时间 (23) Mysql索引的原理,底层是怎么存的? (24) 主键和唯一键有什么区别? (25) Varchar和char的区别? Varchar动态决定占用空间大小,char固定 (26) UTF-8下面varchar能占多少字符?GBK呢? 不懂 (27) 说下你知道的排序,比较一下他们的优缺点,复杂度和应用场景。 作者:早就戒了。 链接:[https://www.nowcoder.com/discuss/77167?type=2&order=3&pos=55&page=1](https://www.nowcoder.com/discuss/77167?type=2&order=3&pos=55&page=1) 来源:牛客网 早上早早的来到了酒店,等候着面试。 “XXX,请去1607”。此时时间9.27 来到面试官房间,简单的握了手,寒暄几句就开始面了。 说说你的XXX项目吧 然后就开始长达80分钟的讨论,讨论内容全都是和项目的整体设计有关,面试官提出要求,我画一下架构的设计,然后在再解释。 整整80分钟,首先问到了项目的架构设计,然后扩展,如果自己项目需要满足10W QPS的需求,架构如何设计? 老生常谈 项目里面高并发下如何实现请求的过滤以及消峰? 消息队列,缓存 集群环境下如何保证数据的一致性? 主从复制,同步 服务器集群以后如何做到数据的共享? 共享存储,或者服务注册中心zk 说一说一致性Hash吧? 一个2的32次方个点的环。 问我MySQL主从复制会不会?回答不会。 通过binlog完成主从复制,主库开一个线程打log到从库的relaylog上,从库根据这个log重写操作 那你自己设计一下MySQL的主从复制应该如何解决?画一下你的思路? 最后面试官告诉了我MySQL主从复制的原理。然后和他探讨了一下我对这个原理的疑惑。 当时是使用了Redis主从复制的思想来考虑的。 你这种解决办法是从结果来考虑,是不能从原因角度考虑? 说一下STL的Map? 我说我不会,然后讲了一下java的实现,画了一下数据结构图。 讲一下红黑树? 我说您直接看我博客吧,里面有对他的分析。 ali云用的linux什么版本?虚拟机的呢? 6.3和7.0; 说一下常用的shell命令? 看过那些书? 选择出最好的三本? 1 深入理解Javaweb技术内幕。 2 深入理解计算机系统 3 大型网站架构 学习过程? 为什么硕士不报计算机? 你项目里面的这些架构的设计是怎么学习的? 还有一些架构设计的问题忘了了。 最后和面试官聊了一下如何看待非科班转计算机?以及自己学习的是Java,和腾讯的需要不符合怎么办?以及面试结果 总共82分钟,非常感谢面试官对非科班的鼓励,以及对我的肯定,说实话能得到腾讯面试官的肯定更加让自己有信心了。本来想着就试一试,毕竟不是C 的,不管结果如何,起码面试官面了82分钟,就当做面了两轮吧。 作者:mactawish 链接:[https://www.nowcoder.com/discuss/77189?type=2&order=3&pos=52&page=1](https://www.nowcoder.com/discuss/77189?type=2&order=3&pos=52&page=1) 来源:牛客网 腾讯一面,后台开发技术面,已挂,把问题记下来。 面试官是一个二十多岁的男生,很和善,所以在面试的时候也没感觉到怎么紧张,然而他问的问题我都不会就很难受。 1\. 自我介绍,我就把做过的一些项目简单说了说。 2\. 进程,线程,协程的区别,磕磕绊绊,协程根本不知道是个啥 3\. 排序,问我哪些是稳定性排序,没答上来,让我手写快排,还好,写出来了。 4\. java里的sort方法,我说了collections的排序,得实现compare方法,巴拉巴拉说了一堆。 5\. linux服务器性能监测,这个我直接说不会了。 6\. 一次性哈希,我说没听说过,只知道哈希,面试官就让我说哈希是什么,我说了几句,说是建立映射关系存储数据,尽量保证哈希值不重复什么的,感觉没回答到点子上。 7\. 问我MySQL怎么进行数据存储,然后又问了一个实际例子: 假如有一亿QQ用户,每个用户都有500好友,每个人都可能玩很多腾讯出的游戏,问如何存储能使获取一个人的好友玩的游戏列表。 我想了半天,说不会,最后被提醒用kv存储,面试官让我回去看看bitmap,这一部分是印象最深耗时最长的部分。 8\. 面试官问我还有什么问题想问的,我就问了问该怎么准备面试,面试官就说了一大堆,要学好基础啊什么的(其实想想基础部分答的确实很烂),对于实践项目没提什么建议,主要还是基础。 自我介绍的时候可能说项目多一点,然后面试官就一直问我实践方向的事,然而我都回答的很烂,问基础部分还是回答很烂,感觉一直get不到面试官的点,面试过程中他有多次重复一些话,应该就是因为我不理解他的意思吧。 晚上回到宿舍,打开手机一看,已挂,早就料到了,所以也没觉得什么,不过还是有机会被别的部门捞出来,所以还是要努力去准备啊! 作者:不拿offer不睡觉 链接:[https://www.nowcoder.com/discuss/77226?type=2&order=3&pos=49&page=1](https://www.nowcoder.com/discuss/77226?type=2&order=3&pos=49&page=1) 来源:牛客网 本人大三一名渣渣本科生,除了有一次阿里的电话面试之外,这是第一次正式的面试。 因为准备得不是很充分,所以抱着去学习一下的心态去面试的。 给我面试的考官还是挺和善的,所以尽管第一次正式面试,也没有太紧张。 1、首先简单的自我介绍 2、接下来项目扯了很多时间。先简单介绍项目,然后项目中负责哪些方面、项目用了什么技术,项目中遇见的最难的问题、自己做出最大的贡献是什么、项目的特色       其实这是我第一个项目,所以很简单,没想到能被问这么久,其实很多地方都答的很模糊。 3、然后问我为什么不用C++开发(估计面试官是搞C++开发的)。然后我说老师建议我们初学者用eclipse开发,所以就用JAVA了。 4、接着问了一下JAVA和C++的区别。简单说了一下区别,然后我说C++挺久没用了,现在用JAVA比较多,所以他没问我C++了,但是后面也没我JAVA的问题,估计面试官不是JAVA方向。 c跟底层更接近 5、Linux知道吗?答:简单的了解过。哦,那直接没问Linux了。。。没问了。。。了 6、TCP的可靠传输原理,流水线传输、拥塞控制 流水线传输,效率比较高 7、MTO(还是MOT,记不太清了)对传输的影响。我根本不知道那是什么,这道题就跳过了 MTU限制最大帧长度,所以当ip数据报超过MTU时,ip数据报必须分片,tcp则会自己进行数据长度安排 8、线程和进程 9、进程之间的通信 10、进程内存地址的分配 分配虚拟内存地址 11、你还有什么想问的 我进程和线程方面确实没什么准备,没想到连续问到了这方面的几个问题。 应该是前面回答得不好,所以后面的也没问数据结构和算法方面的东西了。也没手撕代码,第一次面试就结束了,整个过程30几分钟,自我感觉凉凉,答的确实很差。 面试官还是挺和善的,所以整过过程我还是很轻松的。 准备实习面试的时间还是太短了,准备再好好学习一段时间,去迎接下一次面试。 作者:少年已去 链接:[https://www.nowcoder.com/discuss/74814?type=2&order=3&pos=314&page=1](https://www.nowcoder.com/discuss/74814?type=2&order=3&pos=314&page=1) 来源:牛客网 发个面经,攒攒人品 一面 一面问的都比较基础, Java的四个特性,jvm内存空间,进程与线程区别,hashmap底层, 快排,索引等等 二面 1.c++stl库 2.c++的vector和map和java的区别等等c++相关 3.加密算法 4.innodb和MyISAM 5.数据库MD5加密方法的具体实现 6.三级范式 7.索引 8.数据库CAP 9.进程的结构 10.进程的调度 11.进程通信方式 12.手画TCP三次握手四次挥 13.http协议 13.手写快排 14.堆排 16.二叉树,字典树,红黑树的自旋 17.并发,自己做业务选怎样的进程控制方式 18.socket 19.xms调优 20.哈希算法 总结: 腾讯主要是c++的,java招的很少,所以二面会问你好多c++相关的,根本不会,二面面试官也问了如果过了,能不能转c++,总之凉凉,但是面腾讯收获还是挺大的,面试官会给你一些很好的建议。 作者:ios开发 链接:[https://www.nowcoder.com/discuss/73823?type=2&order=3&pos=445&page=3](https://www.nowcoder.com/discuss/73823?type=2&order=3&pos=445&page=3) 来源:牛客网 岗位:linux后台研发 部门:社交网络事业群(sng) 时间:历时一个月 薪资:sp(已收到正式offer) 个人情况:主要做后台研发方向(c/c++/java)都用过,末流985计算机专业硕士,有过长达一年半的实习工作经历。计算机基础,算法,项目都还马马虎虎。之前秋招有运气好有拿到百度,滴滴(sp),京东(sp),美团,携程,搜狐(sp),好未来(ssp),便利峰(sp),一点资讯,小红书,虎牙(sp),乐信,华为,中兴等。。 一面:电话面,问了我目前的offer情况和找工作的理由,讲述一下zab协议过程,分布式锁原理,写失败会怎样? zab分为选主,同步,以及多数派通过决议。 分布式锁使用文件节点实现,watcher通知,写失败就时失败 redis中自己使用的场景,为什么这样用? 惊群和雪崩效应说一下?redis源码看过没? 避免惊群要保证每次只通知到一个等待线程 它的性能瓶颈是什么?nginx惊群效应? 性能瓶颈是内存大小。 在说nginx前,先来看看什么是“惊群”?简单说来,多线程/多进程(linux下线程进程也没多大区别)等待同一个socket事件,当这个事件发生时,这些线程/进程被同时唤醒,就是惊群。可以想见,效率很低下,许多进程被内核重新调度唤醒,同时去响应这一个事件,当然只有一个进程能处理事件成功,其他的进程在处理该事件失败后重新休眠(也有其他选择)。这种性能浪费现象就是惊群。 惊群通常发生在server 上,当父进程绑定一个端口监听socket,然后fork出多个子进程,子进程们开始循环处理(比如accept)这个socket。每当用户发起一个TCP连接时,多个子进程同时被唤醒,然后其中一个子进程accept新连接成功,余者皆失败,重新休眠。 那么,我们不能只用一个进程去accept新连接么?然后通过消息队列等同步方式使其他子进程处理这些新建的连接,这样惊群不就避免了?没错,惊群是避免了,但是效率低下,因为这个进程只能用来accept连接。对多核机器来说,仅有一个进程去accept,这也是程序员在自己创造accept瓶颈。所以,我仍然坚持需要多进程处理accept事件。 其实,在linux2.6内核上,accept系统调用已经不存在惊群了(至少我在2.6.18内核版本上已经不存在)。大家可以写个简单的程序试下,在父进程中bind,listen,然后fork出子进程,所有的子进程都accept这个监听句柄。这样,当新连接过来时,大家会发现,仅有一个子进程返回新建的连接,其他子进程继续休眠在accept调用上,没有被唤醒。 但是很不幸,通常我们的程序没那么简单,不会愿意阻塞在accept调用上,我们还有许多其他网络读写事件要处理,linux下我们爱用epoll解决非阻塞socket。所以,即使accept调用没有惊群了,我们也还得处理惊群这事,因为epoll有这问题。上面说的测试程序,如果我们在子进程内不是阻塞调用accept,而是用epoll_wait,就会发现,新连接过来时,多个子进程都会在epoll_wait后被唤醒! nginx就是这样,master进程监听端口号(例如80),所有的nginx worker进程开始用epoll_wait来处理新事件(linux下),如果不加任何保护,一个新连接来临时,会有多个worker进程在epoll_wait后被唤醒,然后发现自己accept失败。现在,我们可以看看nginx是怎么处理这个惊群问题了。 nginx的每个worker进程在函数ngx_process_events_and_timers中处理事件,(void) ngx_process_events(cycle, timer, flags);封装了不同的事件处理机制,在linux上默认就封装了epoll_wait调用。我们来看看ngx_process_events_and_timers为解决惊群做了什么: 1.  void 2.  ngx_process_events_and_timers(ngx_cycle_t *cycle) 3.  { 4.  。。。 。。。 5.  //ngx_use_accept_mutex表示是否需要通过对accept加锁来解决惊群问题。当nginx worker进程数>1时且配置文件中打开accept_mutex时,这个标志置为1 6.  if (ngx_use_accept_mutex) { 7.  //ngx_accept_disabled表示此时满负荷,没必要再处理新连接了,我们在nginx.conf曾经配置了每一个nginx worker进程能够处理的最大连接数,当达到最大数的7/8时,ngx_accept_disabled为正,说明本nginx worker进程非常繁忙,将不再去处理新连接,这也是个简单的负载均衡 8.  if (ngx_accept_disabled > 0) { 9.  ngx_accept_disabled--; 10.   11.  } else { 12.  //获得accept锁,多个worker仅有一个可以得到这把锁。获得锁不是阻塞过程,都是立刻返回,获取成功的话ngx_accept_mutex_held被置为1。拿到锁,意味着监听句柄被放到本进程的epoll中了,如果没有拿到锁,则监听句柄会被从epoll中取出。 13.  if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { 14.  return; 15.  } 16.   17.  //拿到锁的话,置flag为NGX_POST_EVENTS,这意味着ngx_process_events函数中,任何事件都将延后处理,会把accept事件都放到ngx_posted_accept_events链表中,epollin|epollout事件都放到ngx_posted_events链表中 18.  if (ngx_accept_mutex_held) { 19.  flags |= NGX_POST_EVENTS; 20.   21.  } else { 22.  //拿不到锁,也就不会处理监听的句柄,这个timer实际是传给epoll_wait的超时时间,修改为最大ngx_accept_mutex_delay意味着epoll_wait更短的超时返回,以免新连接长时间没有得到处理 23.  if (timer == NGX_TIMER_INFINITE 24.  || timer > ngx_accept_mutex_delay) 25.  { 26.  timer = ngx_accept_mutex_delay; 27.  } 28.  } 29.  } 30.  } 31.  。。。 。。。 32.  //linux下,调用ngx_epoll_process_events函数开始处理 33.  (void) ngx_process_events(cycle, timer, flags); 34.  。。。 。。。 35.  //如果ngx_posted_accept_events链表有数据,就开始accept建立新连接 36.  if (ngx_posted_accept_events) { 37.  ngx_event_process_posted(cycle, &ngx_posted_accept_events); 38.  } 39.   40.  //释放锁后再处理下面的EPOLLIN EPOLLOUT请求 41.  if (ngx_accept_mutex_held) { 42.  ngx_shmtx_unlock(&ngx_accept_mutex); 43.  } 44.   45.  if (delta) { 46.  ngx_event_expire_timers(); 47.  } 48.   49.  ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 50.  "posted events %p", ngx_posted_events); 51.  //然后再处理正常的数据读写请求。因为这些请求耗时久,所以在ngx_process_events里NGX_POST_EVENTS标志将事件都放入ngx_posted_events链表中,延迟到锁释放了再处理。 52.  if (ngx_posted_events) { 53.  if (ngx_threaded) { 54.  ngx_wakeup_worker_thread(cycle); 55.   56.  } else { 57.  ngx_event_process_posted(cycle, &ngx_posted_events); 58.  } 59.  } 60.  } 从上面的注释可以看到,无论有多少个nginx worker进程,同一时刻只能有一个worker进程在自己的epoll中加入监听的句柄。这个处理accept的nginx worker进程置flag为NGX_POST_EVENTS,这样它在接下来的ngx_process_events函数(在linux中就是ngx_epoll_process_events函数)中不会立刻处理事件,延后,先处理完所有的accept事件后,释放锁,然后再处理正常的读写socket事件。我们来看下ngx_epoll_process_events是怎么做的: 1.  static ngx_int_t 2.  ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) 3.  { 4.  。。。 。。。 5.  events = epoll_wait(ep, event_list, (int) nevents, timer); 6.  。。。 。。。 7.  ngx_mutex_lock(ngx_posted_events_mutex); 8.   9.  for (i = 0; i < events; i++) { 10.  c = event_list[i].data.ptr; 11.   12.  。。。 。。。 13.   14.  rev = c->read; 15.   16.  if ((revents & EPOLLIN) && rev->active) { 17.  。。。 。。。 18.  //有NGX_POST_EVENTS标志的话,就把accept事件放到ngx_posted_accept_events队列中,把正常的事件放到ngx_posted_events队列中延迟处理 19.  if (flags & NGX_POST_EVENTS) { 20.  queue = (ngx_event_t **) (rev->accept ? 21.  &ngx_posted_accept_events : &ngx_posted_events); 22.   23.  ngx_locked_post_event(rev, queue); 24.   25.  } else { 26.  rev->handler(rev); 27.  } 28.  } 29.   30.  wev = c->write; 31.   32.  if ((revents & EPOLLOUT) && wev->active) { 33.  。。。 。。。 34.  //同理,有NGX_POST_EVENTS标志的话,写事件延迟处理,放到ngx_posted_events队列中 35.  if (flags & NGX_POST_EVENTS) { 36.  ngx_locked_post_event(wev, &ngx_posted_events); 37.   38.  } else { 39.  wev->handler(wev); 40.  } 41.  } 42.  } 43.   44.  ngx_mutex_unlock(ngx_posted_events_mutex); 45.   46.  return NGX_OK; 47.  } 看看ngx_use_accept_mutex在何种情况下会被打开: 1.  if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) { 2.  ngx_use_accept_mutex = 1; 3.  ngx_accept_mutex_held = 0; 4.  ngx_accept_mutex_delay = ecf->accept_mutex_delay; 5.   6.  } else { 7.  ngx_use_accept_mutex = 0; 8.  } 当nginx worker数量大于1时,也就是多个进程可能accept同一个监听的句柄,这时如果配置文件中accept_mutex开关打开了,就将ngx_use_accept_mutex置为1。 再看看有些负载均衡作用的ngx_accept_disabled是怎么维护的,在ngx_event_accept函数中: 1.  ngx_accept_disabled = ngx_cycle->connection_n / 8 2.  - ngx_cycle->free_connection_n; 表明,当已使用的连接数占到在nginx.conf里配置的worker_connections总数的7/8以上时,ngx_accept_disabled为正,这时本worker将ngx_accept_disabled减1,而且本次不再处理新连接。 最后,我们看下ngx_trylock_accept_mutex函数是怎么玩的: 1.  ngx_int_t 2.  ngx_trylock_accept_mutex(ngx_cycle_t *cycle) 3.  { 4.  //ngx_shmtx_trylock是非阻塞取锁的,返回1表示成功,0表示没取到锁 5.  if (ngx_shmtx_trylock(&ngx_accept_mutex)) { 6.   7.  //ngx_enable_accept_events会把监听的句柄都塞入到本worker进程的epoll中 8.  if (ngx_enable_accept_events(cycle) == NGX_ERROR) { 9.  ngx_shmtx_unlock(&ngx_accept_mutex); 10.  return NGX_ERROR; 11.  } 12.  //ngx_accept_mutex_held置为1,表示拿到锁了,返回 13.  ngx_accept_events = 0; 14.  ngx_accept_mutex_held = 1; 15.   16.  return NGX_OK; 17.  } 18.   19.  //处理没有拿到锁的逻辑,ngx_disable_accept_events会把监听句柄从epoll中取出 20.  if (ngx_accept_mutex_held) { 21.  if (ngx_disable_accept_events(cycle) == NGX_ERROR) { 22.  return NGX_ERROR; 23.  } 24.   25.  ngx_accept_mutex_held = 0; 26.  } 27.   28.  return NGX_OK; 29.  } OK,关于锁的细节是如何实现的,这篇限于篇幅就不说了,下篇帖子再来讲。现在大家清楚nginx是怎么处理惊群了吧?简单了说,就是同一时刻只允许一个nginx worker在自己的epoll中处理监听句柄。它的负载均衡也很简单,当达到最大connection的7/8时,本worker不会去试图拿accept锁,也不会去处理新连接,这样其他nginx worker进程就更有机会去处理监听句柄,建立新连接了。而且,由于timeout的设定,使得没有拿到锁的worker进程,去拿锁的频繁更高。 消息中间件开源了解过没? kafka,rabbitmq (这个没深入问我,说了熟悉kafka,amq),说说tcp如何保证消息有序吧。接着大概问了我平时怎么学习的,爱看什么博客之类,面试就过了! 连续发送连续确认,根据序号来保证有序 时间:25分钟左右。 二面:电话面(一个星期左右)自我介绍,说说你会什么语言? 问了一点c语言方面知识,然后又问了一点java语言集合类的知识,你比较熟悉虚拟机是吧,jvm运行机制? jvm怎么进行类型安全检查? 中间还问了一个jvm编译方面问题? 编译成字节码,依据规则表明作用,按照此规则进行解析,验证,加载等 没回答出来,设计模式了解哪些? 说说动态代理模式和静态代理模式区别,动态代理底层实现原理? 动态代理动态生成字节码和创建实例,是运行时创建的,静态代理则是编译时就确定了的,需要更多代码 反射了解吗?作用说一下? 依赖倒置 文件描述符作用? 负责文件的标识,包括网络流,文件流,设备io流,都可以通过文件描述来表示 进程间通信方式? linux系统怎么查看网络连接? netstat 都有哪些状态?你刚才说的状态怎么发生的? tcp为什么要进行四次挥手?。。。。。。。 接下来两个算法题吧第一个, 1.A.....Z所有字母组合方式,不允许有重复的,用最优的方法实现!(说了位运算的方法)。 位运算判断2的26次方种情况 2.写一个方法输入一个整数,输出这个整数里面最大的质数,再次强调了方法最优! 质数标记法,标记处所有非质数,然后找出最大质数 找出N以内的质数 const  int N=100000; vector<int> prime;//保存N以内的所有质数  bool notprime[N];//标志是否为质数 notprime[1]=true;//1不是质数  for(int i=2;i*i<=N;i++) { if(!notprime[i])//如果i是质数 { for(int j=i*i;j<=N;j+=i)//范围以内的i*u不是质数,其中u=i,i+1,i+2,...;u从i开始记录,因为小于i的哪些之前已经记录过了 { notprime[j]=true; } } } for(int l=2;l<=N;l++)//保存所有质数 { if(!notprime[l]) { t.push_back(l); } } 最后,后续会有人联系你! 感受:后来这位二面面试官成了我的老大,面试过程还是很愉快的! 三面:现场面 过了10天收到了邀约现场面的消息,周五到了深圳,周六上午正式开始面试的,当时陆陆续续有好几个认真比等,社招的,实习的,校招的都有,大概11点轮到了我,一进去面试官老师给我递了一张纸,写两个代码吧: 1.跳跃数组问题 dfs 2 广度优先遍历二叉树 队列 然后讨论了我做的项目,也介绍了他们自己正在做的业务。前面两个算法问题我都很快写出来了然后自己做的项目面试官也比较感兴趣,所以过程还是很愉快的,没什么大问题。’ 四面:总监面 当天下午进行的总监面,一进去首先自我介绍,说说你最熟悉的项目,介绍下后台架构,你做的主要部分。(省略15分钟,全程我在说),你算法怎样? 二叉树后续遍历怎么实现? 用一个栈呢? 两个栈实现 然后问了一个算法问题,熟人问题,说一下你的思路? 你要怎么构造数据集?。。。你还有什么想问我的? 全程面试 30分钟左右的样子 五面:hr面 简单聊了一下学习,实习,爱好,女朋友之类的情况,接着问了目前拿到offer一些薪资情况,就要我回去等消息了!记得hr当时说我应该没问题。。 五面:面委会面 回来找内推人问了情况,显示是报批中,然后老大也说我这边也基本通过了,等offer就好了,然后接下来的两个星期本人就一心沉迷论文不能自拔。。结果就最近收到了要加面通知,面委会很快就打来电话了 自我介绍下!你做的项目中最拿手的架构介绍下?服务器用的什么? 我在网络上点击一个链接说一下全过程,到tomcat后,tomcat做了什么呢? 底层如何处理整个请求的?详细说一下?就这个问题我讲解了很久,面试官根据我的回答也问了很多其他知识点,线程池,nio,socket,servlet等。。 http常见状态吗300  302  301 304? 重定向 http缓存说一下? tacerroute原理?l icmp inux系统熟悉吗? 怎么查看占用某个端口的进程? netstat -anp 怎么查看网络连接? cpu100如何定位? us解释一下? 什么时候是不正常? closed-waited timewait状态是什么时候出现的? 数据库存储引擎了解吗? 说一下innodb和myaisam区别? 底层索引怎么实现的? 然后问了一个黑名单功能算法实现。 面试时间:大概16分钟左右。问的比较广,不是很深入,当时基本都回答出来了,面试官对我的评价还是很不错的。让我直接等hr电话。 然后前天下午收到了录用电话和邮件,沟通了薪水,最终也是给到了sp。 整个面试过程经历了将近一个月左右。非常感谢牛客这个平台,校招过程中通过这个平台认识了很多朋友,也通过内推拿到了很多面试机会,收获了很多大公司的offer,衷心祝越牛客越办越好,也祝19届的学弟学妹们能找一个好的工作。好好加油,机会总是留给有准备的人!! ps qq/微信  1581320438(欢迎叨扰)
文章
存储  ·  算法  ·  应用服务中间件  ·  数据安全/隐私保护  ·  C++
2018-07-24
PHP知识大全
---------------------------------------------------------                      PHP知识大全 --------------------------------------------------------- 1. 变量如何定义?如何检查变量是否定义?如何删除一个变量?怎样检测变量是否设置?        $定义   isset()// 检测变量是否设置         defined()// 检测常量是否设置        unset()//销毁指定的变量        empty()// 检测变量是否为空   2. 什么是可变变量?        一个变量的变量名可以动态的设置和使用。        $a = 'hello' , $$a = 'world',  ${$a}=hello world   3. 变量赋值方式有哪几种?        1)直接赋值   2)变量间赋值   3)引用赋值   4. 引用和拷贝有什么区别?        拷贝是将原来的变量内容复制下来,拷贝后的变量与原来的变量使用各自的内存,互不干扰。        引用相当于是变量的别名,其实就是用不同的名字访问同一个变量内容。当改变其中一个变量的值时,另一个也跟着发生变化。   5. php中变量有哪些基本数据类型?        php支持8种原始数据类型包括:        四种标量类型(布尔型boolean,整型interger,浮点型float/double , 字符串string)        两种复合类型(数组array , 对象object)        两种特殊类型(资源resource,NULL)   6. 其它类型转换为boolean类型时,哪些被认为是false?        布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', 空数组,特殊数据类型NULL, 没有设定的变量。      empty()函数在哪些情况下返回true?        布尔值false,整型值0, 浮点型值0.0, 空白字符串, 字符串'0', array()空数组,特殊数据类型NULL, 没有任何属性的对象,没有赋值的变量。   7. 如果定义了一个变量$a ,但是没有赋初始值              那么$a==0吗?    $a==false吗?    $a==''吗?        $a==NULL吗?    $a===NULL吗?     答:echo=>什么都没有 , var_dump=>NULL        empty($b)==true吗?———————————— echo=>1 , var_dump=>bool(true)        此时如果输出$a++是多少?———————   echo=>什么都没有 , var_dump=>NULL        如果输出++$a又是多少?—————————      echo=>1  , var_dump=>int(1)   8. 字符串怎么转成整数,有几种方法?怎么实现?        强制类型转换: (整型)字符串变量名;        直接转换:settype(字符串变量,整型);        intval(字符串变量);   9. 标量数据和数组的最大区别是什么?        一个标量只能存放一个数据,而数组可以存放多个数据。   10. 常量如何定义? 如何检测一个常量是否被定义?常量的值只能是哪些数据类型?        define()//定义常量 , defined()//检查常量是否定义        常量的值只能是标量类型的数据。   11. 常量分为系统内置常量和自定义常量。请说出最常见的几个系统内置常量?        __FILE__ , __LINE__ , PHP_OS , PHP_VERSION   12. 如果定义了两个相同的常量,前者和后者哪个起作用?        前者起作用,因为常量一旦定义就不能被重新定义或者取消定义。   13. 常量和变量有哪些区别?        1)常量前没有$符号;        2)常量只能通过define()定义,而不能通过赋值语句定义;        3)常量可以在任何地方定义和访问,而变量有全局和局部之分;        4)常量一旦定义就不能被重新定义或者取消定义,而变量而通过赋值方式重新定义;        5)常量的值只能是标量数据,而变量的数据库类型有8种原始数据类型。   14. PHP中常用的几个预定义的全局数组变量是哪些?        有9大预定义的内置数组变量:        $_POST, $_GET, $_REQUEST, $_SESSION, $_COOKIE, $_FILES,$_SERVER, $_ENV, $GLOBALS   15. 在实际开发中,常量最常用于哪些地方?        1)连接数据库的信息定义成常量,如数据库服务器的用户名、密码、数据库名、主机名;        2)将站点的部分路径定义成常量,如web绝对路径,smarty的安装路径,model、view或者controller的文件夹路径;        3)网站的公共信息,如网站名称,网站关键词等信息。   16. 函数的优越性有哪些?        提高程序的可维护性  提高软件的可靠性  提高程序的可重用性  提高程序的开发效率   17. 如何定义一个函数?函数名区分大小写吗?        1)使用 function 关键字;        2)函数命名规则和变量一样,以字母或者下划线开头,而不能以数字开头;        3)函数名不区分大小写;        4)函数名不可以使用已经声明过的或者系统自建的函数名称。   18. 什么是变量的能见度 或者 说是变量作用域?        就是变量在程序中的可作用范围。根据变量的能见度,变量分为局部变量和全局变量。   19. 什么是局部变量和全局变量?函数内是否可以直接调用全局变量?        局部变量是函数内部定义的变量,其作用域是所在的函数。如果函数外还有一个跟局部变量名字一样的变量,程序会认为它们两个是完全不同的两个变量。当退出函数的时候,其中的局部变量就同时被清除。全局变量是定义在所有函数以外的变量,其作用域是整个php文件,但是在用户自定义的函数内部是无法使用的。如果一定要在用户自定义的函数内部使用全局变量,那么就需要使用global关键字声明。也就是说如果在函数内的变量前加上golbal来修饰,那么函数内部就可以访问到这个全局变量,不仅可以利用这个全局变量进行运算而且可以对这个全局变量进行重新赋值。全局变量还可以使用 $GLOBALS['var'] 来调用。   21. 什么是静态变量?        如果一个函数内定义的变量前使用关键字static来声明,那么该变量就是静态变量。        一般函数内的变量在函数调用结束后,其存储的数据将被清除,所占的内存空间也被释放。而使用静态变量时,该变量会在函数第一次被调用时被初始化,初始化后该变量也不会被清除,当再次调用该函数时,这个静态变量不再被初始化,而能保存上次函数执行完后的值。可以说静态变量在所有对该函数的调用之间共享。   22. php中函数传递参数的方式有哪些?两者有什么区别?        按值传递和按地址传递(或按引用传递)        (1)按值传递:  待传递的变量,与传递给函数之后的变量是存储在不同的空间中。所以函数体内对                该变量值做的修改,不影响原本的变量值。      (2)按地址传递: 使用 & 符号,表明该参数是以地址的方式传递值。并不会将主程序中的指定数值或目标变量传递给函数,而是把该数值或变量的内存储存区块地址导入函数之中,所以函数体内的该变量和主程序中的该变量在内存中是同一个。函数体做的修改,直接影响到函数体外部的该变量的值。     23. 什么是递归函数?如何进行递归调用?        递归函数其实就是调用自身的函数,但是必须满足以下两个条件:        1)在每一次调用自身时,必须是更接近于最终结果;        2)必须有一个确定的递归终止条件,不会造成死循环。        举例说明:        在实际工作中往往会在遍历文件夹的时候使用。        如果有个例子是希望获取到目录windows下所有的文件,那么先遍历windows目录,如果发现其中还有文件夹,那么就会调用自身,继续往下寻找,依次类推,        直到遍历到再也没有文件夹为止,这也就是意味着遍历出来了所有的文件。   24. 判断一个函数是否存在?      function_exists( string $function_name )  如果存在,返回true, 不存在则返回 false。   25. func()和@func()之间有什么区别?        第二个函数调用失败不会报错,第一个会报错   26. include()和require()函数的用法和区别是什么?include_once()和require_once()呢?        include和require出现错误后的错误级别不一样        include_once()和require_once()在加载之前要判断是否已经导入   27. 说出前置++和后置++的区别?        前置++是先将变量增加1,然后在将值赋值给原来的变量;        后置++是先返回变量的当前值,然后再将变量的当前值增加1.   28. 字符串运算符“.”与算术运算符“+”有什么区别?        当“a”“b”之间使用.时认为是连字符。如果两者间是+的时候php会认为是一次运算。        1)如果+号两边的字符串是数字组成的,那么会将字符串自动转为整型;        2)如果+号两边是纯粹的字母,那么会输出0;        3)如果+号两边的字符串是以数字开头的,那么会截取字符串开头的数字,然后进行运算。   29. 什么是三目(或三元)运算符?        根据一个表达式的结果在另两个表达式中选择一个。        例如: ($a==true) ? 'good':'bad';   30. 控制流程语句有哪些?        1:三种程序结构    顺序结构、分支结构、循环结构        2:分支: if/esle/esleif/     switch/case/default        3: switch 需要注意的:               case子句中的常量可以是整型、字符串型常量、 或者常量表达式,不允许是变量。              同一个switch子句中,case的值不能相同,否则只能取到首次出现case中的值。        4: 循环  for while   do...while          do...while 后面必须加入分号结尾。          while 和 do...while 的区别        5:break 和 continue 的区别。               break可以终止循环。               continue没有break强大,只能终止本次循环而进入到下一次循环中。   31. 数组的概念是什么?数组根据索引分为哪两种,如何区分?数组的赋值方式有哪两种?        数组是一个可以存储一组或一系列数值的变量(复合型变量)        索引数组(索引值为数字,以0开始)和关联数组(以字符串作为索引值)        数组的赋值方式有哪两种?        数组的声明方式主要有两种。        1.通过array()函数声明数组; 可以通过key=>value的方式分别定义索引和值,也可以不定义数组的索引下标,只给出数组的元素值。        2.直接为数组元素赋值,不需要调用array()函数。例如:        $arr[0] = 1;     $arr[1] = 2;        特别注意:        数组的下标如果是等价于整数的字符串值(但不能以0开头),则会被当作整数对待。        例如: $array[3] 与  $array['3'] 引用的是相同的一个元素,而 $array['03'] 引用的则就是另外的一个元素了。   32.数组如何遍历?        ①for循环        ②foreach循环  ,这是最常用的遍历方式。用法如下:foreach($arr as $key=>$value){}        ③list each 和while 配合起来循环   33. foeach数组的时候指针是如何指向的?list()/each()/while()循环数组的时候指针如何指向的呢?        当foreach开始执行的时候,数组内部的指针会自动指向第一个单元。因为foreach所操作的是指定数组的拷贝,而不是该数组本身。而each()一个数组后,数组指针将停留在数组中的下一个单元或者碰到数组结尾时停留在最后一个单元。如果要再次使用each()遍历数组,必须要使用reset().        reset()将数组的内部指针倒回到第一个单元并返回第一个数组单元的值。   34. 如何计算数组长度(或者说计算数组中所有元素的个数)?字符串怎么取长度?        count() -- 计算数组中的元素个数。        可以使用count(数组名)或者count(数组名,1),如果有第二个参数,并且是数字1,则表示递归统计数组元素的个数。如果第二个参数是数字0,则等同于只有一个参数的count()函数。        sizeof() -- count() 的别名(count — 计算数组中的单元数目或对象中的属性个数) 字符串:strlen()— 获取字符串长度         mb_strlen()— Get string length   35. 数组中相关的常用函数有哪些?        1) count --(sizeof别名)— 计算数组中的单元数目或对象中的属性个数                  例如:int count ( mixed $var [, int $mode ] )  $var 通常都是数组类型,任何其它类型都只有一个单元。  $mode 默认值为0. 1为开启递归地对数组计数        2) in_array ( mixed $needle , array $haystack [, bool $strict ] ) — 检查数组中是否存在某个值。如果needle 是字符串,则比较是区分大小写的。如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查needle 的类型是否和 haystack 中的相同。        3) array_merge(array $array1 [, array $array2 [, array $... ]] ) 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。               特别注意:如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。               如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引          4) 数组与字符串之间的转换               (1)explode ( string $separator , string $string [, int $limit ] )  使用一个分隔字符来分隔一个字符串。               (2)implode ( string $glue , array $arr )  使用一个连接符将数组中的每个单元连接为一个字符串。join为 implode 的别名        5) sort(array &$array [, int $sort_flags ]) — 对数组按照值排序,当本函数结束时数组单元将被从最低到最高重新安排。   36. 数组合并函数array_merge()和数组加法运算$arr + $arr2 的区别是什么?        array_merge()->使用array_merge(),如果是关联数组合并,如果数组的键名相同,那么后面的值将覆盖前者;如果是数字索引数组合并,则不覆盖,而是后者附加到前者后面。"+"->使用数组加法运算,与array_merge()不同,加法运算不管是关联数组还是数字索引数组,都是将相同键名的的值舍弃,也就是只保留首次出现该键名的元素,后来的具有相同键名的元素都不会被加进来。   37. 字符串定义的时候单引号和双引号有什么区别?        单引号加载速度比双引号加载速度快 38. echo(),print(),print_r()的区别?        (1)echo 是语法,Output one or more strings,没有返回值;        (2)print 是函数,不能输出数组和对象,Output a string,print有返回值;        (3)print_r 是函数,可以输出数组。print_r是个比较有意思的函数,可以输出stirng、int、float、    array、object等,输出array时会用结构表示,print_r输出成功时返回true;而且print_r可以通过print_r($str,true)来,使print_r不输出而返回print_r处理后的值。此外,对于echo和print,基本以使用echo居多,因为其效率比print要高。   39. 按照功能分类说说都有哪些字符串处理函数?这些函数的作用是什么?        A. 字符串输出函数        (1)echo $a,$b,$c......;  是一个语言结构,而不是一个真正的函数。        (2)print($a)    本函数输出字符串。若成功则返回 1,失败返回 0        (3)print_r($a)        (4)var_dump($a); 能输出类型、长度、值        B. 去除字符串首尾空格的函数: trim  ltrim  rtrim(别名:chop)   使用第二个参数,还可以去除指定的字符。        C. 转义字符串函数:addslashes()        D. 获取字符串长度的函数:strlen()        E. 截取字符串长度的的函数:substr()        F. 检索字符串函数: strstr() , strpos()        G. 替换字符串函数:str_replace()   40. 请给出以下问题的正确答案?        1).$arr = array('james', 'tom', 'symfony');请将$arr数组的值用’,’分割并合并成字符串输出?          echo implode(‘,’,$arr);        2).$str = ‘jack,james,tom,symfony’; 请将$str用’,’分割,并把分割后的值放到$arr数组中?           $arr = explode(‘,’,$str);        3).$arr = array(3,7,2,1,’d’,’abc’);   请将$arr按照从大到小的顺序排序,并保持其键值不变?          arsort($arr); print_r($arr);        4).$mail = “gaofei@163.com”;    请将此邮箱的域(163.com)取出来并打印,看最多能写出几种方法?               echo strstr($mail,'163');               echo substr($mail,7);               $arr = explode("@",$mail); echo $arr[1];        5). 如果有一个字符串,该字符串是“123,234,345,”。请问如何切割掉这个字符串最后一个逗号?        6). 获取随机数的函数有哪几个?mt_rand() 和 rand()哪个执行速度快?   41.页面字符出现乱码,怎么解决?        1.首先考虑当前文件是不是设置了字符集。查看是不是meta标签中写了charset,如果是php页面还可以看看是不是        在header()函数中指定了charset;        例如:        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />        header(“content-type:text/html;charset=utf-8”);        2.如果设置了字符集(也就是charset),那么判断当前文件保存的编码格式是否跟页面设置的字符集保持一致,        两者必须保持统一;        3.如果涉及到从数据库提取数据,那么判断数据库查询时的字符集是否跟当前页面设置的字符集一致,两者必须统一,        例如:mysql_query(“set names utf8”)。   42. 正则表达式是什么?php中有哪些常用的跟正则相关的函数?请写出一个email的正则,中国手机号码和座机号码的正则表达式?        正则表达式是用于描述字符排列模式的一种语法规则。正则表达式也叫做模式表达式。        网站开发中正则表达式最常用于表单提交信息前的客户端验证。        比如验证用户名是否输入正确,密码输入是否符合要求,email、手机号码等信息的输入是否合法        在php中正则表达式主要用于字符串的分割、匹配、查找和替换操作。               preg系列函数可以处理。具体有以下几个:        string preg_quote ( string str [, string delimiter] )        转义正则表达式字符 正则表达式的特殊字符包括:. \\ + * ? [ ^ ] $ ( ) { } = ! < > | :。        preg_replace -- 执行正则表达式的搜索和替换        mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]        preg_replace_callback -- 用回调函数执行正则表达式的搜索和替换        mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )        preg_split -- 用正则表达式分割字符串        array preg_split ( string pattern, string subject [, int limit [, int flags]] )          常用的正则表达式写法:        中文:/^[\u4E00-\u9FA5]+$/        手机号码:/^(86)?0?1\d{10}$/        EMAIL:        /^[\w-]+[\w-.]?@[\w-]+\.{1}[A-Za-z]{2,5}$/        密码(安全级别中):        /^(\d+[A-Za-z]\w*|[A-Za-z]+\d\w*)$/        密码(安全级别高):        /^(\d+[a-zA-Z~!@#$%^&(){}][\w~!@#$%^&(){}]*|[a-zA-Z~!@#$%^&(){}]+\d[\w~!@#$%^&(){}]*)$/   44. preg_replace()和 str_ireplace()两个函数在使用上有什么不同?preg_split()和split()函数如何使用?   preg_replace — 执行正则表达式的搜索和替换   str_ireplace — str_replace() 的忽略大小写版本   str_replace — 子字符串替换            preg_split — 用正则表达式分割字符串        split — 用正则表达式将字符串分割到数组中   45. 获取当前时间戳的函数主要有哪些?用PHP打印出今天的时间,格式是2010-12-10 22:21:21?        用PHP打印出前一天的时间格式是2010-12-10 22:21:21?如何把2010-12-25 10:30:25变成unix时间戳?        echo date ("Y-m-d H:i:s" ,strtotime(‘-1,days’));            date('Y-m-d H:i:s',time());          $unix_time = strtotime("2009-9-2 10:30:25");//变成unix时间戳        echo date("Y-m-d H:i:s",$unix_time);//格式化为正常时间格式   46.  在url中用get传值的时候,若中文出现乱码,应该用哪个函数对中文进行编码?        用户在网站表单提交数据的时候,为了防止脚本攻击(比如用户输入<script>alert(111);</script>),php端接收数据的时候,应该如何处理?        使用urlencode()对中文进行编码,使用urldecode()来解码。           使用htmlspecialchars($_POST[‘title’])来过滤表单传参就可以避免脚本攻击。   48. 说说mysql_fetch_row() 和mysql_fetch_assoc()和mysql_fetch_array之间有什么区别?        第一个是返回结果集中的一行作为索引数组,第二个是返回关联数组,而第三个既可以返回索引数组也可以返回关联数组,取决于它的第二个参数 MYSQL_BOTH MYSQL_NUM  MYSQL_ASSOC 默认为MYSQL_BOTH        $sql =”select * from table1”;        $result = mysql_query($sql);        mysql_fetch_array($result, MYSQL_NUM);   49. 请说出目前学过的返回是资源的函数?        答:       fopen(打开文件)                 imagecreatefromjpeg(png gif) — 从 JPEG 文件新建一图像                 imagecreatetruecolor — 新建一个真彩色图像                 imagecopymerge — 拷贝并合并图像的一部分                 imagecopyresized  — 拷贝部分图像并调整大小                 mysql_connect  — 打开一个到 MySQL 服务器的连接               mysql_query();只有这执行select的时候成功,才返回资源,失败返回FALSE               50. 打开、关闭文件分别是什么函数? 文件读写是什么函数?删除文件是哪个函数?        判断一个文件是否存在是哪个函数?新建目录是哪个函数?   51. 文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?        1.首现要在php.ini中开启文件上传;        2.在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;        3.上传表单一定要记住在form标签中写上enctype="multipart/form-data";        4. 提交方式 method 必须是 post;        5. 设定 type="file" 的表单控件;        6.要注意上传文件的大小MAX_FILE_SIZE、文件类型是否符合要求,上传后存放的路径是否存在。 可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名,这样就避免了重名。可以自己设置上传文件的保存目录,与文件名拼凑形成一个文件路径,使用move_uploaded_file(),就可以完成将文件保存到指定目录。     52. $_FILES是几维数组?第一维和第二维的索引下标分别是什么?批量上传文件的时候需要注意什么?        二维数组。第一维是上传控件的name,二维下标分别为name/type/tmp_name/size/error.   53. header()函数主要的功能有哪些?使用过程中注意什么?        答:     header()发送http头信息    -header("content-type:text/html; charset=utf-8");-------------------//当前页面输出内容是html,编码为utf-8格式    -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    -header("content-type:image/png gif jpeg");----------------------------------//当前页面输出内容的格式是图片    -header("refresh:5;url=http://www.1004javag.com/five/string.php");--//页面5秒后要跳转到新网址 -header("location:http://1004javag.com/five/string.php");-----------//页面重定向 54. 文件下载的时候如果使用header()函数?        答:header("content-type: application/octet-stream;charset=UTF-8"); //在这里加utf-8和在上面定义有什么区别?、??              header("accept-ranges: bytes");             header("accept-length: ".filesize($filedir.$filename));             header("content-disposition: attachment; filename=".$filedir.$filename);     55. 什么是ajax?ajax的原理是什么?ajax的核心技术是什么?ajax的优缺点是什么?        ajax是asynchronous javascript and xml的缩写,是javascript、xml、css、DOM等多个技术的组合。    '$'是jQuery的别名.     页面中用户的请求通过ajax引擎异步地与服务器进行通信,服务器将请求的结果返回给这个ajax引擎,   最后由这个ajax引擎来决定将返回的数据显示到页面中的指定位置。Ajax最终实现了在一个页面的指定位置可以加载另一个页面所有的输出内容。        这样就实现了一个静态页面也能获取到数据库中的返回数据信息了。所以ajax技术实现了一个静态网页在不刷新整个页面的情况下与服务器通信,        减少了用户等待时间,同时也从而降低了网络流量,增强了客户体验的友好程度。               Ajax的优点是:        1.  减轻了服务器端负担,将一部分以前由服务器负担的工作转移到客户端执行,利用客户端闲置的资源进行处理;        2.  在只局部刷新的情况下更新页面,增加了页面反应速度,使用户体验更友好。        Ajax的缺点是不利于seo推广优化,因为搜索引擎无法直接访问到ajax请求的内容。        ajax的核心技术是XMLHttpRequest,它是javascript中的一个对象。   56. jquery是什么?jquery简化ajax后的方法有哪些?        jQuery是Javascript的一种框架。        $.get(),$.post(),$.ajax()。$是jQuery对象的别名。          代码如下:        $.post(异步访问的url地址 , {'参数名' : 参数值} , function(msg){               $("#result").html(msg);        });               $.get(异步访问的url地址 , {'参数名' : 参数值} , function(msg){               $("#result").html(msg);        });          $.ajax({               type: "post",               url: loadUrl,               cache:false,               data: "参数名=" + 参数值,               success: function(msg) {                      $("#result").html(msg);               }        });     57. 什么是会话控制?        简单地说会话控制就是跟踪和识别用户信息的机制。会话控制的思想就是能够在网站中跟踪一个变量,通过这个变量,系统能识别出相应的用户信息,根据这个用户信息可以得知用户权限,从而展示给用户适合于其相应权限的页面内容。目前最主要的会话跟踪方式有cookie,session。   58. 会话跟踪的基本步骤        1).访问与当前请求相关的会话对象  2).查找与会话相关的信息        3).存储会话信息     4).废弃会话数据   59. 使用cookie的注意事项有哪些?        1) setcookie()之前不可以有任何页面输出,就是空格,空白行也不可以;        2) setcookie()后,在当前页面调用$_COOKIE['cookiename']不会有输出,必须刷新或到下一个页面才可以看到cookie值;        3) 不同的浏览器对cookie处理不同,客户端可以禁用cookie,浏览器也可以闲置cookie的数量,一个浏览器能创建的cookie数量最多300个,并且每个不可以超过4kb,        每个web站点能设置的cookie总数不能超过20个。        4) cookie是保存在客户端的,用户禁用了cookie,那么setcookie就不会起作用了。所以不可以过度依赖cookie。   60. 使用session的时候,通过什么来表示当前用户,从而与其他用户进行区分?        sessionid,通过session_id()函数可以取得当前的session_id。   61. session和cookie的使用步骤分别是什么?什么是sesssion和cookie的生命周期?session和cookie的区别是什么?        cookie是保存在客户端机器的,对于未设置过期时间的cookie,cookie值会保存在机器的内存中,只要关闭浏览器则cookie自动消失。如果设置了cookie的过期时间,那么浏览器会把cookie以文本文件的形式保存到硬盘中,当再次打开浏览器时cookie值依然有效。             session是把用户需要存储的信息保存在服务器端。每个用户的session信息就像是键值对一样存储在服务器端,其中的键就是sessionid,而值就是用户需要存储信息。服务器就是通过sessionid来区分存储的session信息是哪个用户的。              两者最大的区别就是session存储在服务器端,而cookie是在客户端。session安全性更高,而cookie安全性弱。        session在web开发中具有非常重要的份量。它可以将用户正确登录后的信息记录到服务器的内存中,当用户以此身份访问网站的管理后台时,无需再次登录即可得到身份确认。而没有正确登录的用户则不分配session空间,即便输入了管理后台的访问地址也不能看到页面内容。通过session确定了用户对页面的操作权限。           使用session的步骤:        1. 启动session:使用session_start()函数来启动。        2. 注册会话:直接给$_SESSION数组添加元素即可。        3. 使用会话:判断session是否为空或者是否已经注册,如果已经存在则像普通数组使用即可。        4. 删除会话:               1.可以使用unset删除单个session;               2.使用$_SESSION=array()的方式,一次注销所有的会话变量;               3.使用session_destroy()函数来彻底销毁session。        cookie怎么使用?        1. 记录用户访问的部分信息        2. 在页面间传递变量        3. 将所查看的internet页存储在cookies临时文件夹中,可以提高以后的浏览速度。        创建cookie:setcookie(string cookiename , string value , int expire);        读取cookie:通过超级全局数组$_COOKIE来读取浏览器端的cookie的值。        删除cookie:有两种方法        1.手工删除方法:        右击浏览器属性,可以看到删除cookies,执行操作即可将所有cookie文件删除。        2.setcookie()方法:        跟设置cookie的方法一样,不过此时将cookie的值设置为空,有效时间为0或小于当前时间戳。   62. 如何设置一个cookie的名字为username,值为jack,并且让此cookie一周后失效?        一个浏览器最多可以产生多少个cookie,每个cookie文件最大不能超过多少?        setcookie(‘username’,’jack’,time()+7*24*3600);        最多可以产生20个cookie,每个最多不超过4K   63. 设置或读取session之前,需要做什么?        可以直接在php.ini中开启session.auto_start = 1或者在页面头部用session_start();        开启session,session_start()前面不能有任何输出,包括空行。   64. 在实际开发中,session在哪些场合使用?        session用来存储用户登录信息和用在跨页面传值。        1)常用在用户登录成功后,将用户登录信息赋值给session;        2)用在验证码图片生成,当随机码生成后赋值给session。   65. 注销session会话的形式有几种?        unset()   $_SESSION=array();   session_destroy();   66. 什么是OOP?什么是类和对象?什么是类属性?        OOP(object oriented programming),即面向对象编程,其中两个最重要的概念就是类和对象。        世间万物都具有自身的属性和方法,通过这些属性和方法可以区分出不同的物质。        属性和方法的集合就形成了类,类是面向对象编程的核心和基础,        通过类就将零散的用于实现某个功能的代码有效地管理起来了。              类只是具备了某些功能和属性的抽象模型,而实际应用中需要一个一个实体,也就是需要对类进行实例化,类在实例化之后就是对象。类是对象的抽象概念,对象是类的实例化。    对象是一个高级的数组,数组是一个最原始的对象,同样的对象也可以遍历        OOP具有三大特点:         1. 封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。        2. 继承性:就是子类自动继承其父级类中的属性和方法,并可以可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。 php只支持单继承,也就是说一个子类只能有一个父类。        3. 多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。          OOP的优点:1、代码重用性高(省代码)    2、使程序的可维护性高(扩展性)  3、灵活性           67. 常用的属性的访问修饰符有哪些?分别代表什么含义?        private,protected,public。           类外:public ,var        子类中:public,protected ,var        本类中:private,protected,public ,var        如果不使用这三个关键词,也可以使用var关键字。但是var不可以跟权限修饰词一起使用。var定义的变量,子类中可以访问到,类外也可以访问到,相当于public        类前面:只能加final,abstract        属性前面:必须有访问修饰符(private,protected,public,var)        方法前面:static,final,private,protected,public ,abstract   68. $this和self、parent这三个关键词分别代表什么?在哪些场合下使用?        $this 当前对象   self  当前类   parent  当前类的父类        $this在当前类中使用,使用->调用属性和方法。        self也在当前类中使用,不过需要使用::调用。    parent在类中使用。   69.类中如何定义常量、如何类中调用常量、如何在类外调用常量。        类中的常量也就是成员常量,常量就是不会改变的量,是一个恒值。        定义常量使用关键字const.        例如:const PI = 3.1415326;        无论是类内还是类外,常量的访问和变量是不一样的,常量不需要实例化对象,        访问常量的格式都是类名加作用域操作符号(双冒号)来调用。        即:类名 :: 类常量名;   70. 作用域操作符::如何使用?都在哪些场合下使用?        调用类常量   调用静态方法   71. 什么是魔术方法?常用的魔术方法有哪几个?        以__开头的系统自定义的方法。        __construct()  __destruct()   __autoload()   __call()    __tostring()   72. 什么是构造方法和析构方法?        构造方法就是在实例化一个对象的同时自动执行的成员方法,作用就是初始化对象。        php5之前,一个跟类名完全相同的方法是构造方法,php5之后魔术方法__construct()就是构造方法。如果类中没有定义构造方法,那么php会自动生成一个,这个自动生成的构造方法没有任何参数,没有任何操作。        构造方法的格式如下:        function __construct(){}        或者:function 类名(){}        构造方法可以没有参数,也可以有多个参数。        析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。        析构方法的定义方法为:__destruct();        因为php具有垃圾回收机制,能自动清除不再使用的对象,释放内存,一般情况下可以不手动创建析构方法。   73. __autoload()方法的工作原理是什么?        使用这个魔术函数的基本条件是类文件的文件名要和类的名字保持一致。        当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时. 就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。   74. 什么是抽象类和接口?抽象类和接口有什么不同和相似的地方?        抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。        抽象类是通过关键字 abstract 来声明的。        抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少要包含一个抽象方法,        抽象方法没有方法体,该方法天生就是要被子类重写的。        抽象方法的格式为:abstract function abstractMethod();                   因为php中只支持单继承,如果想实现多重继承,就要使用接口。也就是说子类可以实现多个接口。接口类是通过interface关键字来声明的,接口类中的成员变量和方法都是public的,方法可以不写关键字public,接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。抽象类和接口实现的功能十分相似,最大的不同是接口能实现多继承。在应用中选择抽象类还是接口要看具体实现。子类继承抽象类使用extends,子类实现接口使用implements。        抽象类至少有一个抽象方法吗??????        答:如果一个类声明成抽象类,里面可以没有抽象方法            如果一个类中有抽象方法,这个类必须是抽象类   75. __call的参数有几个,类型是什么,意义是什么?        魔术方法__call()的作用是当程序调用一个不存在或不可见的成员方法时,php会先调用__call()方法,将那个不存在的方法的方法名和参数都存储下来。        __call()包含两个参数,  第一个参数是那个不存在的方法的方法名,是个字符串类型;                             第二个参数是那个不存在的方法的所有参数,是个数组类型。        本人认为__call()方法的意义更多在于调试,可以定位到错误。同时可以捕捉异常,如果某个方法不存在,则执行其它可替代方法。   76. smarty模板技术的用途是什么?        为了php与html分开,美工和程序员各司其职,互不干扰。   77. smarty配置主要有哪几项?        1. 引入smarty.class.php;        2. 实例化smarty对象;        3. 重新修改默认的模板路径;        4. 重新修改默认的编译后文件的路径;        5. 重新修改默认的配置文件的路径;        6. 重新修改默认的cache的路径。        7. 可以设置是否开启cache。        8. 可以设置左侧和右侧定界符。   78. smarty在使用过程中需要注意哪些细节?        Smarty是基于MVC概念的一种模板引擎,它将一个页面程序分成了两部分来实现:即视图层和控制层,也就是说smarty技术将用户UI与php代码分离开。这样程序员和美工各司其职,互不干扰。        smarty运用过程中要注意以下几个问题:        1.正确配置smarty。主要要实例化smarty对象,配置smarty模板文件的路径;        2.php页面中使用assign赋值 和 display显示页面;        3.smarty模板文件中不允许出现php代码段,所有的注释,变量,函数都要包含在定界符内。               A.{}               B. foreach               C. if else               D. include               E. literal   79. MVC的概念是什么?各层主要做什么工作?        MVC(即模型-视图-控制器)是一种软件设计模式或者说编程思想。        M指Model模型层,V是View视图层(显示层或者用户界面),C是Controller控制器层。        使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。        在网站开发中,        模型层一般负责对数据库表信息进行增删改查,        视图层负责显示页面内容,        控制器层在M和V之间起到调节作用,控制器层决定调用哪个model类的哪个方法,        执行完毕后由控制器层决定将结果assign到哪个view层。   81. java语言中方法重写和重载分别代表什么意思?准确说php支持方法的重载吗?很多参考书中提到的php重载实际上该如何正确理解?        答:        php不支持方法的重载,很多书里提到的PHP‘重载’应该是‘重写’   82. final关键字能定义类中的成员属性吗?        答:不能,类的成员属性只能有public ,private , protected ,var 来定义   83. final关键字定义的类能够被继承吗?        答:final定义的类不能被继承   84. 说说static关键字的使用场合?static能用在class前吗?     static可以跟public,protected,private一起使用吗?构造方法可以是static的吗?        答:       static可以在属性和方法前面使用,调用static属性或者方法时,只要将类载入就可用,不用实例化               static不能用在class的前面                   static可以跟public,protected,private一起使用,在方法的前面;               ▲构造方法不能是static   85. 接口可以实例化吗?抽象类能实例化吗?        答:接口和抽象类都不能被实例化   86. class前面能加访问修饰符吗?如果能加,只能是哪几个访问修饰符?可以是权限访问修饰符public,protected,private吗?        答:class前面可以加final,static;        class前面不能加public,protected,private   87. 类中属性前可以不加访问修饰符吗?成员变量前的修饰符只能是public,protected,private吗?还可以是哪几个?        答:类中的属性必须加修饰符,除了那3个以外,还可以加var   88. 如果echo一个数组,页面输出什么?echo一个对象呢?print一个数组或者对象呢?        答:页面只能输出“Array”;echo一个对象会出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php on line 33”            print一个数组时也只是输出“Array”,print一个对象出现“Catchable fatal error: Object of class t2 could not be converted to string in G:\php2\t2.php ”            ▲print和echo是一样的             89. __tostring()魔术方法在什么时候被自动执行? __tostring()魔术方法必须要return返回值吗?        当echo或者print一个对象时,就是自动触发。而且__tostring()必须要返回一个值        90. 什么是抽象方法?        答:在方法前面有abstract,而且方法没有方法体,连“{ }”也不能有   91. 如果一个类中有一个方法是抽象方法,而这个类没有定义成抽象类,会报错吗?           答:会,"Fatal error: Class t2 contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (t2::ee) in"   92. 如果一个类是抽象类,而类中的方法都是非抽象的方法,会报错吗?        答:不会报错,如果一个类是抽象类,其中可以没有抽象方法,但是一个类中有个方法是抽象方法,那么这个类一定是一个抽象类   94. final 关键字的应用应注意的问题?          使用final关键字定义的类,禁止继承。        使用final关键字定义的方法,禁止重写。   95. 如果一个类既要继承一个父类,又要实现多个接口,该如何写?        书写格式例如: class MaleHuman extends Human implements Animal,Life { ... }   96. 什么是单点入口呢?         所谓单点入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发,         比如说在上面我们就使用index.php作为程序的单点入口,当然这个是可以由你自己任意控制的。        单点入口有几大好处:            第一、一些系统全局处理的变量,类,方法都可以在这里进行处理。比如说你要对数据进行初步的过滤,你要模拟session处理,你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面            第二、程序的架构更加清晰明了。   97. PHP提供了2套正则表达式函数库,分别是哪两套?【        (1) PCRE   Perl兼容正则表达式         preg_   为前缀        (2) POSIX  便携式的操作系统接口       ereg_   为前缀   98. 正则表达式的组成?     由原子(普通字符,如英文字符)、     元字符(有特殊功用的字符)     模式修正字符     一个正则表达式中,至少包含一个原子   99. 不常用魔术方法的触发时机?        __isset()  __unset()的触发时机        __sleep()、 __wakeup()  在对对象进行串行化的时候调用        如果序列化对象的时候,不写__sleep()方法,则所有的成员属性都会被序列化,而定义了__sleep()方法,则只序列化指定数组中的变量。因此,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。        使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。        使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。               101.常见框架        thinkPHP  yii  ZendFramework  CakePhp  sy   102. 常用魔术方法的触发时机?        1)__autoload() :当程序实例化某个类,而该类没有在当前文件中被引入。此时会触发执行__autoload()。程序希望通过该方法,自动引入这个类文件。该方法有一个参数,即就是那个忘记引入的类的名称。__autoload()方法的工作原理是什么?当程序执行到实例化某个类的时候,如果在实例化前没有引入这个类文件,那么就自动执行__autoload()函数。这个函数会根据实例化的类的名称来查找这个类文件的路径,当判断这个类文件路径下确实存在这个类文件后,就执行include或者require来载入该类,然后程序继续执行,如果这个路径下不存在该文件时就提示错误。使用自动载入的魔术函数可以不必要写很多个include或者require函数。        2)__construct()  :这个是魔术构造方法。构造方法是实例化对象的时候自动执行的方法,作用就是初始化对象。该方法可以没有参数,也可以有多个参数。如果有参数,那么new这个对象的时候要记得写上相应的参数。在php5以前,没有魔术构造方法,普通构造方法是一个跟类名同名的方法来实现构造的。如果一个类中既写了魔术构造方法,又定义了普通构造方法。那么php5以上版本中,魔术方法起作用,普通构造方法不起作用。反之,在php5以前版本中,不认识魔术构造方法,只是把该方法当做普通的方法。        3)__destruct()  :这个是魔术析构方法。析构方法的作用和构造方法正好相反,是对象被销毁时被自动调用的,作用是释放内存。析构方法没有参数。        4)__call() :当程序调用一个不存在或不可见的成员方法时,自动触发执行__call()。它有两个参数,分别是未访问到的方法名称和方法的参数。而第二个参数是数组类型。        5)__get() :当程序调用一个未定义或不可见的成员属性时,自动触发执行__get()。它有一个参数,表示要调用的属性的名称。        6)__set():当程序试图写入一个不存在或不可见的成员属性时,PHP就会自动执行__set()。它包含两个参数,分别表示属性名称和属性值。        7)__tostring()  :当程序使用echo或print输出对象时,会自动调用该方法。目的是希望通过该方法将对象转化为字符串,再输出。__tostring() 无参数,但是该方法必须有返回值。        8)__clone()  :当程序clone一个对象的时候,能触发__clone()方法,程序希望通过这个魔术方法实现:不仅仅单纯地克隆对象,还需要克隆出来的对象拥有原来对象的所有属性和方法。   103. MVC的概念是什么?        MVC(即模型-视图-控制器)是80年代发明的一种软件设计模式或者说编程思想。        M指模型层,V是指视图层(显示层或者用户界面),C是指控制层。        使用mvc的目的是实现M和V分离,从而使得一个程序可以轻松使用不同的用户界面。        C存在的目的则是在M和V之间起到调节作用,确保M和V的同步,一旦M改变,V应该能同步更新。        将M和V分离,就可以做到同一个网页,在不同节日到来的时候能显示不同的页面风格,这只需要提前制作多个视图层模板页面,        而无需更改M层程序。        MVC做到了编程中的分工合作,代码的可重用性得到最大化体现,程序逻辑更加清晰而富有条理,便于后期维护管理。   104、     访问权限修饰符有哪几种,对比解释        答:1、public 表示公共的,在本类中和子类中以及类外,可以对其调用        2、protected表示受保护的,可以在本类中和子类中调用        3、private表示私有的,只能在本类中调用        4、var,效果等同于public 105、     Class关键词前可以有哪些修饰词        a)    Final修饰,表示该类是最终的,无法继承        b)    Abstract修饰,表示该类是抽象类   106、     作用域操作符在那些场合下使用        答:作用于操作符的使用场合        a)    本类中:               i.     self::类常量               ii.     self::静态属性               iii.    self::方法()   parent::方法()        b)    子类中:               i.     parent::类常量               ii.     parent::静态属性(public或者protected)               iii.    parent::方法()(public或者protected)        c)    类外:               i.     类名::类常量               ii.     类名::静态属性(public)               iii.    类名::静态方法(public)   107、     $this,self, parent分别代表什么?哪些场合下使用        答:$this代表的是当前对象  self代表的是当前的类  parent代表的是当前类的父类        使用场合:        $this只能使用在当前类中,通过$this->可以调用当前类中的属性和方法;        self只能在当前类中使用,通过作用域操作符::访问当前类中的类常量、当前类中的静态属性、当前类中的方法;        parent只能使用在有父类的当前类中,通过作用域操作符::访问父类中的类常量、父类中的静态属性、父类中的方法。   108、     说明是接口、抽象类二者有何相同和不同的地方?        1、接口是帮助php实现功能意义上的多继承的,用interface来声明,其方法没有方法体,使用implemens关键词来实现接口。        接口中只能包含抽象方法和类常量,不可以包含成员属性。        2、抽象类是一种不能被实例化的类,只能作父类,用abstract class来定义,抽象类和普通类可以没有区别,类中可以包含成员属性、类常量、方法。        子类得用extends来继承,而且只能是单继承。        两者相同点是都不可以被实例化,都是需要被继承才可以使用。        两者的最大区别是接口可以实现多继承,而抽象类只能是单继承。        接口中不能包含成员属性,而抽象类中可以有成员属性。        接口中的抽象方法必须是public或者无访问修饰词,接口中的抽象方法不能用abstract来修饰。        抽象类中的方法可以是普通方法,也可以是抽象方法,如果是抽象方法,一定需要使用abstract来修饰。   109、     解释PHP中单例模式?        又叫做单态模式、单元素模式、singleton pattern。单例模式指在PHP的应用程序的范围内只对指定的类创建一个实例。使用单例模式的类称为单例类。在php中单例类必须要有一个私有的构造方法,还要有一个私有的魔术克隆方法(该方法体中为空)和一个私有的静态的成员属性$_instance.私有构造方法防止除自身以外的类来实例化它。私有的方法体为空的克隆方法防止该类被克隆。$_instance用来存储被自身实例化后的对象。还必须要有一个公共的静态的方法getInstance()。该方法返回已经存储了实例对象的$_instance。   单例:一个类至始至终只能实例化一个对象,这样的类就是单例类 单例类的优点:① 节省空间 ② 节省资源 实现单例类的四个要点:①私有的构造函数②私有的__clone的方法③私有的静态属性,属性有以保存类的实例④公共的静态方法来实例化对象 无限级分类:         ①数据库设计:region_id(自增ID) region_name(地区名称) parent-id(上级地区id) region_path(全路径)        ②程序设计:全路径的作用:a根据全路径顺序取数据 b用作信息层级显示    110、   什么是SQL注入?        SQL注入攻击是黑客对数据库进行攻击的常用手段之一。一部分程序员在编写代码的时候,        没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,        程序将提交的信息拼凑生成一个完整sql语句,服务器被欺骗而执行该条恶意的SQL命令。注入者根据程序返回的结果,        成功获取一些敏感数据,甚至控制整个服务器,这就是SQL注入。   111、   如何防止SQL注入?        要对提交的信息进行过滤,对单引号进行转义。        首先可以在php.ini中设置,让所有的单引号在提交后都进行转义。或者使用addslashes().   112、     FCKEditor自动过滤的解决办法?        如果您需要编辑模板页,默认的FCK设置是会去掉<HTML></HTML><BODY></BODY>标签,而且会给你加上<P></P>标签的,如果需要保留的话,只要更改下设置可以了。        在fckconfig.js里面有:FCKConfig.FullPage = false ;        改为:FCKConfig.FullPage = true;        如果想去掉自动添加<P>的代码就可以在这里设置        默认是        FCKConfig.EnterMode = 'p' ;    // p | div | br        FCKConfig.ShiftEnterMode = 'br' ; // p | div | br        改成        FCKConfig.EnterMode = 'br' ;    // p | div | br        FCKConfig.ShiftEnterMode = 'p' ; // p | div | br   113、     $_REQUEST、$_GET、$_POST、$_COOKIE 的关系和区别:            1.关系:$_REQUEST包含了$_GET、$_POST、$_COOKIE等的所有内容,是它们的集合体。        2.通过$_REQUEST获取变量值,PHP页面因为不确定它是哪种传值方式,        因此会根据php.ini中的配置来接收值。        php.ini里可以设置,variables_order = “GPC”。其含义是GET,POST,COOKIE.        所以PHP页面会先从$_GET中获取,再从$_POST中获取,然后从$_COOKIE中获取。        新获得的值会覆盖之前获取到的值。        因此从表现形式上看,$_REQUEST最后是获取$_COOKIE中的值,如果$_COOKIE中没有值,        会获取$_POST中的值,如果$_POST没有获取到 ,就去$_GET中获取。        如果$_GET中也没有该值,那么$_REQUEST就返回null。               114、     什么是多条件查询(复合查询),如何实现多条件查询?        如何实现万能查询呢?查询的时候要填写查询条件,这些条件会通过表单进行提交。        首先需要检查提交的条件是否为空。如果不为空,就认为这个值是要被当作条件,        我们就可以使用字符串连接的方式来组合一个sql查询语句。        当执行后获取查询结果。   115.       文件上传需要注意哪些细节?怎么把文件保存到指定目录?怎么避免上传文件重名问题?        1). 首现要在php.ini中开启文件上传;        2). 在php.ini中有一个允许上传的最大值,默认是2MB。必要的时候可以更改;        3). 上传表单一定要记住在form标签中写上enctype="multipart/form-data";        4). 提交方式 method 必须是 post;        5). 设定 type="file" 的表单控件,并且必须具有name属性值;        6). 为了上传成功,必须保证上传文件的大小是否超标、文件类型是否符合要求,上传后存放的路径是否存在;        7). 表单提交到接收页面,接收页面使用$_FILES来接收上传的文件。$_FILES是个多维数组。第一维下标是上传控件的name,二维下标分别为name/type/tmp_name/size/error。分别代表文件名、文件类型、上传到临时目录下的临时文件名、文件大小、是否有错误。如果是批量上传,那么二维下标就是数组,而并非是字符串。        8). 文件上传后是被放置在服务器端临时路径下,需要使用move_uploaded_file ()函数,才可以将上传后的文件保存到指定目录。        9). 为了避免上传文件重名,可以通过上传的文件名获取到文件后缀,然后使用时间戳+文件后缀的方式为文件重新命名。   116.      使用GD2库创建图像的步骤?        1). 创建一个画布:imagecreate();        2). 设置画布背景颜色,使用RGB设置颜色:imagecolorallocate();        3). 设置文字颜色:imagecolorallocate();        4). 在画布上书写文字:imagestring();        5).  以 JPEG 格式将图像输出到浏览器或文件:【根据图片格式不同,函数还可以是imagepng()、imagegif()等】   imagejpeg();        6). 清除图像资源:imagedestroy();   117.      GD2库生成缩略图的步骤是什么?        1). 读取希望生成缩略图的源图像,创建图像对象:【根据图片格式不同,函数也相应不同】               $src_image = imagecreatefromjpeg();        2). 获取原图像的宽度和高度$srcW,$srcH,根据缩放比例计算出新图像的宽度和高度$dstW、$dstH:        3). 创建一个真色彩的图像对象,宽度和高度设置成刚才计算出的宽度和高度:               $dst_image = imagecreatetruecolor($dstW,$dstH);        4). 拷贝图像并调整大小:   imagecopyresized();        5). 将图像输出:【根据图片格式不同,函数也相应不同】  imagejpeg();        6). 清除图像资源(将源图像资源和目标图像资源都清除)   imagedestroy();   118.      GD2库给图片增加水印如何做?        1. 添加简单的文本水印:               利用imagestring()函数就可以在图片上写文本水印。        2. 增加一个图形水印:               1). 读取希望增加水印的源图片,创建图像对象:【根据图片格式不同,函数也相应不同】                      $image = imagecreatefromjpeg();               2). 创建一个水印图片的图像对象:                      $watermark = imagecreatefrompng();               3). 拷贝并合并图像:                      imagecopymerge();               4). 将图像输出:【根据图片格式不同,函数也相应不同】                      imagejpeg();               5). 清除图像资源(将源图像资源和水印图像资源都清除)                      imagedestroy();   119.      什么是事务?什么是回滚?事务的作用是什么?        事务就是组合起来的几个独立的sql操作。如果其中一项失败,那么就让这几个组合起来的sql操作都回退到未执行状态。这就是事务的回滚。mysql中MyISAM存储引擎的表不支持事务,只有InnoDB 存储引擎的表才支持事务,为了让事务正常执行,就需要让参与事务的所有数据表都设置成innoDB类型。事务被包装在了 BEGIN 和COMMIT 语句之间。在没有使用 COMMIT 语句的情况下,对数据库的操作不是永久的,一旦运行了ROLLBACK,就会被回退。只有执行了COMMIT,数据表中的信息才被改动。事务的目的就是为了保证数据的完整性。   120.      模拟SESSION机制实现数据库存放会话数据有什么作用?【备用】       如果使用默认的SESSION机制,大家都知道默认的SESSION_ID是存放在COOKIE中,用户的身份是靠SESSION_ID来识别的,而COOKIE文件是存放在用户浏览器的客户端,这样就会带来一个问题,当用户在办公室选择一些商品到购物车,在准备下订单付款的时候,用户选择了支付宝在线的支付方式,恰巧办公室的电脑上面没有安装支付宝的数字证书,而在用户家里的电脑安装过数字证书,所以呢,用户就需要回家去支付。但是回家登录商城之后,发现购物车中精心挑选的商品都不存在了。这是为什么呢?问题就在家里电脑上的并没有存放SESSION_ID的cookie文件,因而就无法正确的读取服务器上对应session文件中的数据,所以无法将原来的选择的商品息读取过来。这样的购物车功能给用户的用户体验式非常糟糕的,所以我们就需要采取模拟SESSION机制使用数据库来存放会话数据。   121.       什么是无限极分类?        要实现无限极分类,数据库建表是关键。        表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。        1. id ,当前数据的唯一标识;        2. typename ,类型名称;        3. parentid , 当前类型的上一层父类型的id;        4. path , 其中存储当前类型的id和它所有父级类型的id。        这些id之间采用“-”隔开。        5. 当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。        select * from 表名 where 条件 order by path; 无限极分类的原理是什么?        要实现无限极分类,数据库表结构是关键。        表结构中至少需要三个字段,如果想避免递归循环,那么需要四个字段。        1. id ,当前数据的唯一标识;        2. typename ,类型名称;        3. parentid , 当前类型的上一层父类型的id;        4. path , 其中存储当前类型的id和它所有父级类型的id。        这些id之间采用“-”隔开。        5. 当通过以下sql语句就可以实现,相同顶级类下的信息都在一起集中显示。         select * from 表名 where 条件 order by path;   122.    分页原理是什么?        数据分页需要以下几个条件:        1. 参与分页的总条数 【$msg_count】 ,该值通过数据库查询可以获取到;        2. 每页显示的条数【$pagesize】 ,这个数值由自己定义;        3. 当前页的页码数 【$page】,该数值通过地址栏传递和接收;        4. 可以通过以上资料计算出总页数 【$pagecount】 ,此处需要借助ceil();               【$pagecount = ceil($msg_count/$pagesize);】        5. 数据库查询借助sql语句中的【limit】来实现数据的变化:               例如:               select * from 表名 where 条件 limit $startnum , $pagesize;               而$startnum = ($page-1)*$pagesize;   123、   如何在smarty模板语言中使用php代码?        借助于两个smarty内建函数。        1. inluce_php 函数用于在模板中包含 php 脚本。例如:        {include_php file="test.php"}        2. php 标签允许在模板中直接嵌入 php 脚本。例如:        {php}               echo "这个是php内建函数的作用";        {/php}        124、   请列出至少五个smarty中的变量调节符并说明功能?        default  例如:{$arr|default:’xxxx’} ,默认变量调节器,当变量为空时显示给定的默认值        truncate   例如:{$articleTitle|truncate:10} , 切割字符串长度为指定的长度;        count_characters   例如:{$articleTitle|count_characters} ,获取字符串长度;        strip_tags   例如:  {$articleTitle|strip_tags} ,去除字符串中的所有html标签;        date_format  例如:{$smarty.now|date_format(‘’)} ,格式化时间戳。   125、   写程序实现如下功能:       a.如何判断一个字符串中是否存在一个字符?        echo strstr('abcdefgcd'  , 'cd');        echo strpos('ab0defgcd'  , 'cd');       b.如何判断一个字符串中一个字符出现的次数?        echo substr_count('abcdefgcd'  , 'cd');       c.如何去掉一个字符串的最后一个字符        echo substr('abcdefgcd'  , 0 ,  -1);   126、     如何使用smarty的缓存、步骤?什么叫单模板多缓存?        如果给整个网站开启缓存,那么$smarty->caching=1,此时缓存的时间为smarty.class.php中默认的时间,也就是3600秒。如果对每一个页面独立设置缓存,那么$smarty->caching=2 ,缓存时间就会跟display的参数模板页相挂钩,也就是可以实现对每个模板页设置不同的缓存时间。        用法例如:        if(!$smarty->is_cached('index.html')) {               //此处可以执行数据库操作               $smarty->cache_lifetime = 3600*6;        }        $smarty->display('index.html');               对于例如新闻单条这样的页面,新闻的模板都是一个,如果开启缓存,那么所有的新闻单页的缓存都是一个,根本不会随着id的变化而变换内容。所以为了区分不同的页面缓存,需要使用单模板多缓存技术。具体做法是以id作为display的第二个参数来实现。此外对于具有分页的列表页,也必须在display中使用第二个参数,可以使用新闻类型id和当前页面合并成第二个参数。   127、   写一个递归函数完成以下功能:向函数中传一个多维数组,对数组中所有的值做判断        ,如果值是’number’则设置该值为0?(提示:该题考的是递归的应用,因为传入的数组不确定是多少维的,所以需要递归判断)          function recursive_array($arr) {               if(is_array($arr)) {                      foreach($arr as $key=>$value) {                             if(is_array($value)) {                                    $arr[$key] = recursive_array($value);                             } else {                                    if($value=='number') {                                           $arr[$key] = '0';                                }                             }}}               return $arr;        }          128、   使用jquery写一个全选的例子?        //全选与取消全选        function selectAll(flag) {               for(var i=0; i<$("#fonds input").size(); i++) {                      $("#fonds input").get(i).checked=flag;               }}        //判断复选框已经被勾选了多少个?        function checkFonds() {               var count=0;               for(var i=0; i<$("#fonds input").size(); i++) {                      if($("#fonds input").get(i).checked==true) {                             count++;                      }}               alert(count);        }        //利用后代选择器和get()来获取指定的控件        $(“div a”).get(2)   129、     请说明smarty中fetch方法的功能?        Fetch方法可以获取到页面所有的内容,并且赋值到一个变量中。        如果第四个参数为true,则等同于display,直接输出到浏览器中。        如果第四个参数为false,则不输出。        Display方法就是第四个参数为true的fetch方法。        Display = Fetch() + echo()   130、   写出关于文件上传的相关函数?                    strrchr($filename , '.');      explode('.' , $filename);        end($arr);                     strrpos($filename , '.');        substr($filename , $pos+1);    pathinfo($filename , PATHINFO_EXTENSION);        date(‘YmdHis’)               time()      rand();        mt_rand()                      move_uploaded_file()   131、   如何将SESSION存放在数据库中,可以结合数据表设计说明.        默认情况下php.ini中session.save_handler = files,也就是session是以文件形 式存储的。        如果想更改为数据库或其它存储方式,那么需要更改设置,让 session.save_handler = user。        除了在php.ini中配置外,还可以在PHP页面中单独配置,用        ini_set ('session.save_handler, 'user')来设置session的存储方式,设置为用户自定义存储方式。        设置好存储方式后,需要使用session_set_save_handler()函数。        该函数是设置用户级别的session保存过程的函数。该函数有6个参数,这6个参数其实是6个自定义函数的名称,分别代表对session的开启,关闭,读,写 ,销毁,gc(垃圾回收)。        示例代码如下:        function open () { }        function close() { }        function read () { }        function write () {}        function destroy () {}        function gc () {}        session_set_save_handler ("open", "close", "read", "write", "destroy",  "gc");        session_start();        现在你就可以象往常一样地使用session了。        数据库结构如下:        Session_id , session_value ,expire_time , 分别存储sessionid的id和值以及失效时间。   132、    常用的正则表达式写法:        中文:/^[\u4E00-\u9FA5]+$/        手机号码:/^(86)?0?1\d{10}$/        EMAIL:        /^[\w-]+[\w-.]?@[\w-]+\.{1}[A-Za-z]{2,5}$/        密码(安全级别中):        /^(\d+[A-Za-z]\w*|[A-Za-z]+\d\w*)$/        密码(安全级别高):        /^(\d+[a-zA-Z~!@#$%^&(){}][\w~!@#$%^&(){}]*|[a-zA-Z~!@#$%^&(){}]+\d[\w~!@#$%^&(){}]*)$/ ——————————————————————————                     PHP初     —————————————————————————— order顺序 var(variables)变量 model典型 样式 模型 module模数;模块;组件 enctype SEO搜索引擎优化(Search Engine Optimization) Search搜索 Engine 引擎 Optimization最佳化,最优化 mod_rewrite模块重写 CMS 内容管理系统(content manage system) electronic commerce(电子商务) gc(garbage collection)垃圾回收   ---------------Apache与WAMP安装--------------- 1.wamp安装 apache (2.2版本) mysql(5.067版本)  php(5.2版本)   LAMP  Linux下的安装 负责版本控制 SVN 一台机器能安装多个apache服务 但是只能安装一个MySQL服务 -------------PHP上------------- PHP: personal home page  个人家庭主页  94年产生的 5.2.6版本 ASP: active  server page   93 JSP: java server page   类里面定义常量叫类常量 用const定义 类常量必须有初始值 define('','','false/true')里有三个参数,默认为false时区分大小写,反之不区分大小写 在类里面叫做方法  在类外叫做函数 常量默认为大小写敏感。 ::作用域操作符   标量和非标量类型的区别:标量只能存一个数据,非标量能存多个数据 (属性  变量名  类常量)区分大小写 (变量  类名  系统自带函数  自定义函数)不区分大小写  当$_POST['user_name']等没加‘’是会先当作常量来编译 3.函数 可变函数:函数的名字是一个变量 可选参数:参数有默认值 递归(recursive)函数体内有一个循环体,自己调用自己,但他跟死循环有区别,死循环是没有尽头的,     他是无限循环,递归有尽头,他最终会获得一个值 function pager( $page $msg_count $pagesize $url="?"){ }----》$url="?"即为可选参数     数组的合并 array_merge()              $arr1+$arr2 两数组相加: 只要是具有相同的下标,则只保留首次出现的元素,后者舍去 array_merge:索引数组会将后者的元素附加到前者后面;若是关联数组,相同下标,后者覆盖前者    explode() 取数组最后一个元素 8.文件的操作    mkdir新建目录    rmdir删除目录    skandir输出指定路径下的文件或目录    fopen(资源)— 打开文件或者 URL    fclose— 关闭一个已打开的文件    fgets — 一次读取一行    fgetc — 一次只读取一个字符    fgetss — 一次读取一行并过滤掉 HTML 标记    file_get_contents — 将整个文件读入一个字符串    fread-读取文件    file_put_contents— 将一个字符串写入文件    fwrite-写入文件    unlink-删除文件    pathinfo — 返回文件路径的信息 array_push — 将一个或多个单元压入数组的末尾(入栈) array_unshift — 在数组开头插入一个或多个单元 9.其它函数    输出控制函数:ob(output buffer) ob_flush    加密函数 md5    数学类函数:abs绝对值,rand随机数,ceil取整,floor,mt_rand生成更好的随机数    转换函数:explode 使用一个字符串分割另一个字符串,implode    时间函数:date(),strtotime (将字符串转换为时间戳)    处理地址栏: url_encode url_decode 10.乱码问题    ASCII(American Standard Code for Information Interchange)81年产生    ANSI 美国国家标准学会( American National Standards Institute)    utf-8(-8代表一次传输8个字符)可变字节编码(中文3个字节)(utf:Unicode转换格式(UCS Transformation Format)      utf-16(-16代表一次传输16个字符)    GBK. 国家标准扩展码(Guo-Biao Kuozhan)90年产生(双字节编码)    GB2312 因为国际排行2312位(81年产生)    BIG5    unicode (国际编码)可变字节编码    Latin_1    utf-8+ bom    ISO:国际标准化组织(International Standardization Organization)   11.数据库操作    数据库优化:char(查询速度快)               varchar        引擎:myisam(mysql indexed sequential access method)索引顺序访问方法        支持事务的引擎:BDB ,innodb        innodb:是以inno开头的一家公司的商标   表类型就是表的存储引擎     dll:动态数据连接库  封装的类库   修饰符:public,var,protected,private,static,final,abstract 访问权限修饰符:public,private,protected        public:类成员访问没有限制,多有外部成员都可以访问        protected:受保护的,不能被类外部成员访问,该类的直接子类可以访问,可以实现对成员属性的读、写操作        private:私有的,只能类里边的成员自己访问,类外部的成员都不能访问        一个属性被修饰为私有的(private),那么这个属性在类的外部是不可以读取和修改的,现在有一种方法 可以设置该属性既是私有的,还可以被类的外部成员读取即__get()和__set()    修饰class的修饰符:final,abstract(抽象) final被它修饰的类是不能被继承的 定义属性必须要加修饰符:可以是public和var 定义方法时可以有修饰符public,可以不写,默认为public   如果父类中的方法被声明为final,则子类无法覆盖该方法; 如果一个类被声明为final,则不能被继承。 final只能出现在class类和方法中   方法前可以有public,private,protected,static,final,abstract修饰。     继承性:耦合性越低越好  const修饰,一定要有初始值 ( smarty的保留变量:{$smarty.now},{$smarty.const},{$smarty.post},{$smarty.get},{$smarty.cookies},{$smarty.config},{$smarty.session},){$smarty.capture}  调用属性时,如果前有$后边就不能有,后有前不能有,如:$this->abc                                               self::$abc 当用parent调用父类方法时,将方法自动转化为静态的   多态性:由继承  重写(覆盖)(重新写一遍)(override重写)造成的             php不支持重载(重复载入),php为弱变量语言(overload重载)   抽象:一个类包含抽象方法就是抽象类,抽象类中不一定有抽象方法 抽象类的定义abstract 接口里可以有抽象类,还可以有类常量,通过interface来定义一个接口, 实现多个接口时,接口中的方法不能有重名。 接口中定义的所有方法都必须是public,这是接口的特性。 接口里的方法必须被重写 静态:static 不能与构造方法共存,static不能new对象,构造方法可以new对象,方法体中不能用$this   在php5以前的版本中,当普通构造方法和__construct(魔术方法)共存在时,它会调用普通构造方法,它对__construct(魔术方法)是不识别的,在php5以后的版本中,当共存时他会先调用__construct(魔术方法)。析构方法是最后被执行的,被自动调用的方法 单例(单态)singleton ——————————————————————————                     PHP中     —————————————————————————— 2.jQuery   包括javascript框架和prototype.js框架 选择器:   1.基本选择器:     ①、$('#result')=jQuery('#result')=document.getElementById('result')                            <div id='result'>                         <div class='result'>    ②、class选择器 $('.result')    ③、元素选择器$('div')   2.子代选择器:$('#myform < input')   3.后代选择器:$('#myform  input')   4.组合选择器:$('#myform < span < input') 3.Ajax  ajax的用处是用来异步js和xml 不仅可以获取xml数据,还可获得hmtl和json数据    ajax的优点:1.提升用户的体验2.占用带宽小3.减小服务器的负载    ajax就是把B页面的内容,显示到A页面的指定位置,实现异步传输    $.ajax() 返回其创建的 XMLHttpRequest 对象。    $.ajax({     url:,  data:,  type:,  datatype:,  success:function(这个参数里,存在被传回的页面的所有内容){}   });   $.post('请求地址','传递参数','回调函数');   $.get('请求地址','传递参数','回调函数'); post传值文件没有大小限制,保密性好,必须有form表单 get传值安全性不高,有大小限制 当地址栏里有中文时,用urlencode(编码 URL 字符串) urlencode — 编码 URL 字符串 urldecode(解码已编码的 URL 字符串)   4.会话控制         session:unset()和array() 是连同内存和session文件内容一起删除,而session_destroy只是将文件删除    cookie没有生命周期的叫会话cookie,随着浏览器的关闭,cookie消失    cookie有两种存在方式,一种是以文件形式存在,另一种是保存在内存里    cookie里面只能存字符串   会话控制主要是为了跨页面传值 序列化是把其他的类型转换成字符串类型 5.smarty 代码重用(include,require,include_once,require_once) include require 比 require_once include_once 性能高  加载类文件用 require_once(最好) include_once   6.PDO    dsn(data source name)    //数据源    $dsn = 'mysql:host=127.0.0.1;dbname=java1008a'; die('到此结束'); 等同于 echo '到此结束';die;   ----------------------------------------------------------------------------------   2.b/s与c/s简单比较,区别: --a、运行环境不同(广域网、局域网) --b、安全级别不同(低/高) --c、用户群不同(全部用户/局部用户) --d、系统升级不同(无缝升级/整体升级) --e、用户开启不同(浏览器/特制软件) --f、软件界面特点不同(信息流/用户体验)   比如:b/s就是网上的微博、博客;c/s就是在网吧打的网络游戏(奇迹、传奇等) 3.php是什么:运行在服务器端的脚本语言 --Hypertext Preprocessor --personal home page 4.php语言能做什么 --图形化用户界面程序 --服务器端运行脚本程序   3.php外部变量$_POST[]、$_GET[];     特殊运算符   '.'是连接符   ".="是连接赋值   "@"屏蔽错误信息  $link=@mySQl_connect(主机,用户名,密码) 5.流程控制(顺序、选择、循环) ****************************************************************************** ****************************************************************************** 第三单元【字符串】 1.字符串的三种定义方式(单引号、双引号、定界符) ---单引号定义(转义\'和\\) ---双引号定义(转义\n \r \t \$ \\ \") ---定界符方法<<<eof   2.函数部分 explode/implode substr()** str_replace/trim/ltrim/rtrim   strstr(str, search)获得指定字符串最开始出现到最后的内容 strrchr(str, search)获得指定字符串最后出现到最后的内容 strpos(str,  search)获得指定字符串最开始出现的位置 strrpos(str, search)获得指定字符串最后出现的位置 ucfirst(str)将字符串第一个字母大写 ucwords(str)将字符串的每个单词的第一个字母大写 strlen(str)获得字符串长度 strcmp(str1, str2)比较两个字符串大小,                 返回负数表示 str1 小于 str2;                 返回正数表示 str1 大于 str2;                 返回零表示二字符串相同   urlencode(str)替换所有非字母数字的字符,变为%后面跟两位16进制数,空格变为+号 urldecode(str)对已%##编码的URL进行解析还原 parse_url(str)解析完整的url转变为为数组 parse_str(str,out)解析请求字符串转变为数组 htmlspecialchars()转换html代码为实体代码 printf/sprintf %b %d %c %x %s %f %X –    b           整数转成二进位。 –    c            整数转成对应的 ASCII 字符。 –    d           整数转成十进位。 –    f            单倍精确度数字转成浮点数。 –    o           整数转成八进位。 –    s            转成字符串。 –    x            整数转成小写十六进位。 –    X           整数转成大写十六进位。   1.数组和栈的操作   array_push(目标数组,字符串)将字符串压入数组的最后   array_pop(目标数组)将数组最后的元素弹出并返回 2.数组和队列的操作   array_unshift(目标数组,字符串)将字符串放到数组的开始位置   array_shift(目标数组)删除数组的第一个元素并返回 3.数组和指针的操作key() current() next() prev() reset() end() 4.预定义数组($_GET $_POST $_FILES $_COOKIE $_SESSION) ****************************************************************************** ****************************************************************************** 第六单元【其他常用函数】 date(format,[timestamp])//格式化时间信息,并返回 time()//返回当前时间戳信息   mktime(hour,minute,second,month,day,year) mktime(小时,分钟,秒,月,天,年)//取得一个日期的 Unix 时间戳   max()//取得最大值 -echo max(1, 3, 5, 6, 7);  // 7 -echo max(array(2, 4, 5)); // 5 -echo max(0, '1hello');     // 1hello -echo max('hello', 0);     // hello -echo max(-1, 'hello');    // hello -echo max(array(2, 4, 8), array(2, 5, 7)); // array(2, 5, 7) -echo max('string', array(2, 5, 7), 42);   // array(2, 5, 7)数组和非数组比较数组总认为最大   mt_rand(65,94)//获得随机数 round()//四舍五入取整 flush()//输出准备区内容 urlencode('张三')//返回字符串中,除了-_.之外的所有非字母数字部分为%后接两位 16进制数,空格转化为+ urldecode()//对已经编码的部分反编码 var_dump()//输出变量的详细信息(八种数据类型数据都可以输出)   chr(mt_rand(65,94))随机获得字母 ord(chr(mt_rand(65,94)))将字母转化为数字 basename(路径名)获得路径中文件名部分 strtolower转换小写   第七单元【php连接mysql】 *mysql_connect(主机,用户名,密码) 打开一个到 MySQL 服务器的连接 *mysql_select_db(数据库,连接数据库资源) 选择 MySQL 数据库 *mysql_query("set names utf8");设定字符集          *mysql_close() 关闭 MySQL 链接 *mysql_query(语句) 发送并执行一条sql语句 mysql_fetch_row(结果资源)从结果集中取得一行结果(索引数组) mysql_fetch_assoc(结果资源)从结果集中取得一行结果(关联数组) *mysql_fetch_array(结果资源)从结果集中取得一行结果(索引/关联数组) mysql_fetch_object(结果资源)从结果集中取得一行结果(对象数组)   mysql_errno()返回错误号码 *mysql_error()返回错误信息 *mysql_num_rows(结果资源)用于计算查询结果中所得行的数目 *mysql_affected_rows()获得受影响的结果数目 *mysql_insert_id()传回最后一次使用 INSERT 指令产生的自动增长 ID 值   mysql_result(结果集,索引行,字段)指定获取结果 mysql_free_result(结果资源)释放结果集 mysql_num_fields(结果资源)用于计算查询结果中所得列的数目 mysql_fetch_field(结果资源)从结果集中取得列的结果,以对象形式返回 mysql_pconnect()永久连接数据库   1.留言板建立数据库bbs,建立两张表leave_word和back_word(留言表和回复表)   leave_word:   字段       数据类型   id        int         主键、自增   title     varchar(20) 标题   content   text        内容   itime     datetime    添加时间     back_word:   id        int         主键、自增   leave_id  int         外键(留言id)   content   text        内容   btime     datetime    回复时间 4.删除留言,对无效、无用的留言实现删除功能(这时需要用get方式传递被删除留言id值) 5.修改留言,对需要修改(get方式传递被删除留言id值,再利用隐藏域方式传递给接收页面) 6.留言详细显示功能,有的留言内容比较多,在明细页面不可能全部显示出来(这时利用get方式传递留言id) 7.在详细页面可以实现回复功能和回复留言展示,步骤:制作一个回复表单和接收数据页面        3.构造方法和析构方法        构造函数:实例化对象首先第一个需要做的事情就是构造函数。一个小孩出生到5岁之前,所有的事情都是父母帮助做的,包括起名字、穿衣服、吃饭等等。        析构函数:一个对象被使用完后需要做一些善后工作,这些善后工作是不需要人为干预的,例如资源释放、变量删除等。例如:一个小狗死后,主人非常爱惜它,就把它埋在了家后园的一颗树下。小狗被埋这件事情是主人做的,不是狗做的。这就是析构函数。        3.类的重写        子类和父类之间的事情,就是说父类有的方法,子类不但可以直接使用,还可以在子类中        重新定义具体内容,例如有一个父亲会驾驶汽车,那么他的儿子也会驾驶汽车,但他的儿子        可以不驾驶汽车,而驾驶飞机,这就是类方法的重写。      D    1.final(最后的)关键字使用        该关键字修饰的类不能被继承        该关键字修饰的方法不能被重写      2.static(静态)关键字使用(类的内部、外部、子类)        实例化对象在内存中的分配有讲到大的数据在内存被分配到堆空间里边。现在有一个例子:有一个        "学生"这个类,里边有一个成员属性是"国家",标识该对象是属于哪个国家的,比如美国、英国、德国等 ,这个类在实例化对象时候,每个对象在内存中都会分配一个空间用于存放国家这个成员属性,如果      有100个对象,那么在内容中会分配100个相应的空间。如果这个类的使用对象是在"中国"境内,那么      每个对象的国家属性就会是一样的,即"中国",相应的在内存中会有100个空间存放100个相同的内容      这会造成空间浪费,其实到这里我们可以知道100个相同的内容用一个空间存放就可以,反正都是一样的,        这就产生了静态化概念"static"。        用static修饰的成员属性,该属性就不是对象的,而是类的。      3.self和parent关键字使用        在类的内部访问类中的成员(属性和方法),可以用"$this",该关键字泛指对象,这是访问一般的类        成员,如果访问的成员是用static关键字修饰的,就不能用"$this"了,因为用static修饰的类        成员是被类本身拥有,不属于任何对象了,这时候需要用"self"关键字修饰 self::成员        在类的外部访问类本身拥有的成员可以这样  类名::成员属性。        在子类中访问父类拥有的成员可以用parent关键字  parent::成员属性      4.const(常量)关键字使用        在php中可以定义常量,类外部用define定义,类内部用const定义。        常量的拥有者是类本身,类内部访问常量用 self::常量                       类外部访问常量用 类名::常量                     子类访问常量    parent::常量      6.魔术方法clone、__call、__autoload使用      clone:在一个项目里边我们有时候需要两个或多个完全一样的初始化对象,这时候可以使用clone技术      不用clone技术也可以,不过每个新的对象都需要初始化属性值,这样比较繁琐,也容易出错, 使用clone就比较简单,克隆出来的多个对象彼此是独立的,互不相干。            $p2 = clone $p1;    __call:在类的使用过程中,如果一个对象调用的方法不在类里边,那么这时候程序要报错,然后程序退           出不能继续运行。这样做用户体验非常不好,如果有一种方法可以使得程序报错完后可以继续运 行,这样的程序给人更智能、用户体验更好的感觉,这时候就可以用__call              public function __call($method_name,$args){               echo "你访问的方法:";               echo $method_name;               echo "参数:";               print_r($args);               echo "不存在";              }        __autoload:开发一个软件系统,往往里边会有很多类,在初始化类对象之前需要先include这个对                 象对应的类文件。所有的类不能都放到一个文件(文件臃肿,不易维护),这样就会在程               序开始处有很多的include列表,这样做非常繁琐,出现一个新的类就需要被include,               有没有一种方法可以使得被include的类文件在实例化对象时候才引入,否则不动作,               答案是有的,这时候可以用魔术方法__autoload                 function __autoload($className){                      include($className.'.php');                 }      8.子类继承父类时候成员修饰符限制,子类的修饰级别大于父类。例如父类的修饰符是protected,        则子类修饰级别是protected或public。父类是public的,子类也必须是public的       1.抽象类        在类里边定义的没有方法体的方法就是抽象方法,有抽象方法的类被称为抽象类。抽象类不能实例化对象。        所谓没有方法体就是方法在声明时候没有花括号和里边的内容。        作用之处:          例如:我有一个类"动物",里边有方法"吃食"(还可以有许多其他的方法)         动物这个类可以有许多子类例如:狗、鱼、鸟等,这些子类有一个共性就是都有吃食这个方法         一般的解决方法是:定义3个类,里边都有吃食方法。这样实现没有问题的,但是如果其中一个         类没有吃食方法,这时候程序是不给报错的。我们现在要做的就是3个类中任何一个没有吃食方法           系统就要报错。这时候就需要用到抽象类了。        抽象类按照字面意思理解就是对3个类的进一步抽象。抽象出来吃食方法。        抽象类技术特性:        a、抽象类不能实例化        b、类的成员方法是抽象的,则这个类也是抽象的        c、抽象方法体内没有实现细节,具体实现留给子类实现        d、继承抽象类的子类必须实现父类的抽象类,除非自己也是抽象类。             2.接口(插座实例)        当一个抽象类里边的全部方法都是抽象方法时候,这个抽象类就是"接口"。        接口技术特性:        a、interface声明        b、全部接口方法是public的,因此可以省略        c、接口只定义方法,没有具体方法实现        d、实现类用implements实现接口,全部接口方法都要实现        e、接口可以多实现,中间用逗号分开        f、接口是对抽象类的抽象,抽象类是对类的抽象,类是对事物的抽象。        g、接口不能实例化        (1)、抽象类和接口有什么不同         抽象类只能单继承,接口可以多实现         抽象类里面可以有抽象方法和普通方法,而接口里只有抽象方法         抽象类里面可以有自己的属性,而接口里面只能有常量         接口里面的方法必须是public的,而抽象类不同        (2)、抽象类和接口的相似之处         抽象类里面的抽象方法在继承的时候必须都要重写,接口里面的方法也必须都要实现。         抽象类和接口都不能直接实例化,        抽象类需要继承(extends),接口需要实现(implements)。         抽象类和接口都体现了多态的特性。   3.jquery        jquery是js的封装包,里边有很多集成的函数可以让我们使用,jquery的宗旨就是写更少的代码实现更多的功能        使用的方法:        1.引进jquery包               <script type="text/javascript" src='jquery-1.4.2.js'><script>        2.测试jquery是否加载成功               $(function(){                      alert("jquey加载成功");               })        3.获取页面的元素               $('#div');通过id获取页面元素                 $('.div');通过class获取页面元素        jquery中的事件        1.$('#mydiv').click(function(){});鼠标点击事件【要写在onload事件里边】        2.$('#mydiv').hover(function(){},function(){});鼠标移动到对象事件        3.$('#mydiv').attr();获得对象属性信息        4.$('#mydiv').attr('checked');查看单复选框的选定情况!        5.$('#mydiv').css();获得对象的属性信息        6.$('#mydiv').css(样式,值);给对象赋予样式        7.$('#mydiv').addClass('trb');给元素class属性赋值trb;        8.$('#mydiv').removeClass('trb');使元素失去class属性;        9.$('#mydiv').submit(function(){});提交事件;        10.$('#mydiv').keyup(function(){});键盘敲击事件;             在项目中的使用:表单的验证   20.  * 什么是单一入口(单点入口)呢?         所谓单一入口就是整个应用程序只有一个入口,所有的实现都通过这个入口来转发,         比如说在上面我们就使用index.php作为程序的单点入口,        当然这个入口文件的名字是可以由自己任意定义的。        单点入口有几大好处:            第一、一些系统全局变量,都可以在这里定义。            比如说你要对数据进行初步的过滤,你要模拟session处理,            你要定义一些全局变量,甚至你要注册一些对象或者变量到注册器里面            第二、程序的架构更加清晰明了。  
文章
存储  ·  前端开发  ·  PHP  ·  数据库  ·  索引
2016-03-24
开发与运维
5197 人关注 | 125229 讨论 | 188524 内容
+ 订阅
  • VsCode 运行Java Web 项目(Tomcat)
  • 再议C++单例
  • Python学习笔记180
查看更多 >
数据库
248862 人关注 | 44343 讨论 | 57204 内容
+ 订阅
  • 学弟学妹要的Java学习路线我终于写完了
  • 前端周刊第二十一期
  • Entity Framework基础01
查看更多 >
大数据
184049 人关注 | 22893 讨论 | 52500 内容
+ 订阅
  • 前端周刊第二十一期
  • 【MyBatis系列1】基础知识(上)
  • 【Spring基础系列5】Spring AOP基础(下)
查看更多 >
安全
1035 人关注 | 23268 讨论 | 53063 内容
+ 订阅
  • 初次使用阿里云服务器的体验
  • H3C CAS系列 二、CAS环境搭建(虚拟机搭建)
  • C++的单例模式为什么不直接全部使用static,而是非要实例化一个对象?
查看更多 >
人工智能
2599 人关注 | 9268 讨论 | 62830 内容
+ 订阅
  • GPU服务器初体验:从零搭建Pytorch GPU开发环境
  • 学弟学妹要的Java学习路线我终于写完了
  • 『图解Java并发编程系列』10张图告诉你Java并发多线程那些破事
查看更多 >