高频phpjs面试题及答案_第1页
高频phpjs面试题及答案_第2页
高频phpjs面试题及答案_第3页
高频phpjs面试题及答案_第4页
高频phpjs面试题及答案_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高频phpjs面试题及答案Q:PHP中如何实现对象的深拷贝?A:PHP默认的对象赋值是浅拷贝(引用传递),若要实现深拷贝需使用`clone`关键字并配合`__clone()`魔术方法。当对象包含其他对象属性时,仅用`clone`会导致内部对象仍为引用,此时需在`__clone()`方法内手动对内部对象调用`clone`。例如:```phpclassSubObj{public$val=1;}classMainObj{public$sub;publicfunction__construct(){$this->sub=newSubObj();}publicfunction__clone(){$this->sub=clone$this->sub;//手动深拷贝内部对象}}$obj1=newMainObj();$obj2=clone$obj1;$obj2->sub->val=2;//修改$obj2的sub属性不会影响$obj1的sub```需注意,若对象属性包含资源类型(如文件句柄),需在`__clone()`中重新初始化资源,避免资源共享导致的问题。Q:JavaScript中`let`、`const`和`var`的区别是什么?A:三者均用于声明变量,但作用域和特性差异显著:1.作用域:`var`是函数作用域(或全局),`let`和`const`是块级作用域(`{}`内有效)。例如循环中用`var`声明的变量会泄漏到循环外,而`let`不会。2.变量提升:`var`存在变量提升(声明提前,赋值不提前),`let`和`const`存在“暂时性死区”(TDZ),在声明前访问会报错。3.重新赋值:`var`和`let`可重新赋值,`const`声明时必须初始化且不可重新赋值(但对象/数组的属性可修改)。示例:```javascript//var的函数作用域functiontestVar(){if(true){vara=1;}console.log(a);//1(泄漏到函数作用域)}//let的块级作用域functiontestLet(){if(true){letb=2;}console.log(b);//ReferenceError:bisnotdefined}//const不可重新赋值constc=3;c=4;//TypeError:Assignmenttoconstantvariable```Q:PHP中如何防止SQL注入?A:SQL注入的核心是用户输入未经过滤直接拼接至SQL语句。防范方法包括:1.预处理语句(PreparedStatements):使用PDO或mysqli的预处理功能,通过占位符绑定参数。PDO示例:```php$pdo=newPDO("mysql:host=localhost;dbname=test","user","pass");$stmt=$pdo->prepare("SELECTFROMusersWHEREusername=:username");$stmt->execute(['username'=>$_POST['username']]);//参数自动转义```2.转义函数:若无法使用预处理,可用`mysqli_real_escape_string()`(mysqli扩展)或`PDO::quote()`(PDO)转义用户输入,但需注意数据库连接字符集需正确设置(如`utf8mb4`)。3.避免动态拼接SQL:禁止直接将用户输入拼接至SQL语句,尤其是`WHERE`、`ORDERBY`等敏感位置。4.使用ORM框架:如Laravel的Eloquent,自动处理参数绑定,降低注入风险。Q:JavaScript中`call`、`apply`和`bind`的区别及应用场景?A:三者均用于改变函数的`this`指向,但调用方式和返回值不同:call:立即执行函数,参数以逗号分隔传递。apply:立即执行函数,参数以数组形式传递。bind:返回一个新函数,原函数的`this`被绑定,参数可部分预传递(柯里化)。示例:```javascriptconstobj={name:'Alice'};functiongreet(age){console.log(`Hello,${},age${age}`);}//call传递单个参数greet.call(obj,25);//Hello,Alice,age25//apply传递数组参数greet.apply(obj,[25]);//同上//bind返回绑定后的函数,延迟执行constboundGreet=greet.bind(obj,25);boundGreet();//Hello,Alice,age25```应用场景:`call`/`apply`用于需要立即执行且动态改变`this`的场景(如继承中调用父类构造函数);`bind`用于创建固定`this`的函数(如事件处理函数需要绑定组件实例)。Q:PHP中Session和Cookie的区别及如何配合使用?A:核心区别:1.存储位置:Session数据存储在服务器端(默认文件/数据库/Redis),Cookie存储在客户端(浏览器)。2.安全性:Session更安全(数据不在客户端暴露),Cookie易被篡改(需配合`HttpOnly`、`Secure`等属性增强安全)。3.存储容量:Session无固定限制(取决于服务器配置),Cookie通常限制4KB左右。4.生命周期:Session默认随浏览器关闭失效(可通过`session_set_cookie_params()`设置持久化),Cookie可设置过期时间长期存储。配合使用场景:Session通过Cookie传递`PHPSESSID`(会话ID),若客户端禁用Cookie,需通过URL重写(如`session_use_trans_sid()`)传递`PHPSESSID`。示例:```phpsession_start();//自动发送PHPSESSID到客户端Cookie$_SESSION['user_id']=123;//服务器端存储用户ID//客户端Cookie中查看PHPSESSID=abc123...```Q:JavaScript中如何实现数组去重?至少写出3种方法。A:常见方法:1.Set数据结构(ES6):利用`Set`成员唯一性,转换为数组。```javascriptconstarr=[1,2,2,3,3,3];constuniqueArr=[...newSet(arr)];//[1,2,3]```2.filter+indexOf:过滤掉非首次出现的元素。```javascriptconstuniqueArr=arr.filter((item,index)=>arr.indexOf(item)===index);```3.对象属性唯一性:遍历数组,用对象键存储已出现元素。```javascriptconstobj={};constuniqueArr=[];for(constitemofarr){if(!obj.hasOwnProperty(item)){obj[item]=true;uniqueArr.push(item);}}```4.reduce+includes(适合小规模数组):```javascriptconstuniqueArr=arr.reduce((acc,cur)=>{!acc.includes(cur)&&acc.push(cur);returnacc;},[]);```Q:PHP中`require`、`include`、`require_once`、`include_once`的区别?A:加载文件的核心差异:requirevsinclude:`require`在文件不存在时抛出致命错误(`E_COMPILE_ERROR`),程序终止;`include`抛出警告(`E_WARNING`),程序继续执行。once后缀:`require_once`和`include_once`会先检查文件是否已加载,避免重复包含(通过文件路径的哈希值判断),适合加载配置文件或类库时防止重复定义。使用建议:加载必须存在的文件(如框架核心类)用`require`;可选文件(如插件)用`include`;需避免重复加载时用`_once`系列(注意性能:每次检查哈希可能影响效率,可手动控制加载逻辑替代)。Q:JavaScript中事件冒泡和事件捕获的区别?如何阻止?A:事件流分为三个阶段:捕获阶段(从window到目标元素)、目标阶段(目标元素自身)、冒泡阶段(从目标元素到window)。默认事件处理函数在冒泡阶段触发。事件冒泡:事件从目标元素向上传播至父元素,直至window。例如点击子div,其父div的点击事件会被触发。事件捕获:事件从window向下传播至目标元素,需在`addEventListener`的第三个参数设为`true`(或`{capture:true}`)触发。阻止方法:阻止冒泡:`event.stopPropagation()`(不影响其他同阶段监听器)或`event.cancelBubble=true`(IE旧语法)。阻止捕获:同上,因捕获和冒泡是同一事件流的不同阶段,`stopPropagation`会同时阻止后续阶段。阻止默认行为:`event.preventDefault()`(如阻止a标签跳转)或`returnfalse`(仅在DOM0级事件中有效)。示例:```javascript//冒泡阶段监听(默认)parentDiv.addEventListener('click',()=>console.log('父元素冒泡'),false);//捕获阶段监听childDiv.addEventListener('click',(e)=>{e.stopPropagation();//阻止后续冒泡/捕获console.log('子元素捕获');},true);```Q:PHP中如何实现MVC模式?各部分的职责是什么?A:MVC(模型-视图-控制器)是一种架构模式,PHP中通过分离代码职责实现:模型(Model):处理数据逻辑,负责数据库操作、业务规则(如验证、计算)。例如用户模型处理用户数据的增删改查。视图(View):负责数据展示,提供HTML/JSON等输出。通常是模板文件(如`.php`、`.twig`),仅包含展示逻辑(无业务逻辑)。控制器(Controller):接收用户请求(如URL参数),调用模型获取数据,传递给视图渲染。是模型和视图的协调者。示例流程:用户访问`/user/profile`→路由指向`UserController`的`profileAction`→控制器调用`UserModel`获取用户数据→控制器将数据传递给`profile.php`视图→视图渲染后输出。注意:现代框架(如Laravel、Symfony)已内置MVC支持,开发者只需按规范编写模型、控制器和视图即可,无需手动实现路由分发等基础逻辑。Q:JavaScript中`Promise`的状态有哪些?如何处理异常?A:`Promise`有三种状态,一旦变化不可逆:pending(初始状态):未完成也未拒绝。fulfilled(已成功):操作完成,有返回值。rejected(已失败):操作失败,有错误原因。异常处理方式:1.catch方法:在`Promise`链末尾调用`catch`捕获前面所有未处理的错误。```javascriptfetchData().then(res=>process(res)).catch(err=>console.error('错误:',err));```2.reject回调:在`then`的第二个参数中处理错误(不推荐,因无法捕获后续链中的错误)。```javascriptfetchData().then(res=>process(res),err=>console.error('错误:',err));```3.async/await配合try-catch(ES2017+):更接近同步代码的错误处理。```javascriptasyncfunctiongetData(){try{constres=awaitfetchData();returnprocess(res);}catch(err){console.error('错误:',err);}}```需注意,`Promise`内部的错误若未被捕获,会导致未处理的拒绝(UnhandledRejection),可能引发程序崩溃(Node.js中)或浏览器控制台警告。Q:PHP中`$_GET`、`$_POST`、`$_REQUEST`的区别?A:三者均为超全局数组,存储用户输入数据:$_GET:获取URL查询参数(`?key=val`),数据显示在URL中,长度受浏览器限制(通常2KB),适合传递非敏感信息。$_POST:获取HTTPPOST请求体数据,数据不显示在URL中,长度受服务器`post_max_size`限制(默认8M),适合提交表单或大文件。$_REQUEST:包含`$_GET`、`$_POST`和`$_COOKIE`的数据(默认顺序:COOKIE→GET→POST,后覆盖前)。其作用域更广,但因包含Cookie可能引入安全风险(如CSRF),不推荐直接使用。示例:```php//URL:/test.php?name=Aliceecho$_GET['name'];//Alice//POST数据:age=25(Content-Type:application/x-www-form-urlencoded)echo$_POST['age'];//25//$_REQUEST包含name和age(假设无同名Cookie)echo$_REQUEST['name'];//Aliceecho$_REQUEST['age'];//25```Q:JavaScript中如何实现继承?至少写出2种方式。A:ES6前通过原型链实现,ES6引入`class`和`extends`语法糖,常见方法:1.原型链继承:子构造函数的原型指向父构造函数的实例。```javascriptfunctionParent(){='Parent';}Ptotype.sayHi=function(){console.log('Hi,'+);};functionChild(){}Ctotype=newParent();//子原型指向父实例Ctotype.constructor=Child;//修正constructorconstchild=newChild();child.sayHi();//Hi,Parent(问题:父实例属性会被所有子实例共享)```2.构造函数继承(借用构造函数):在子构造函数中调用父构造函数,使用`call`/`apply`绑定`this`。```javascriptfunctionParent(name){=name;}functionChild(name){Parent.call(this,name);//继承父的实例属性this.age=25;}constchild=newChild('Child');console.log();//Child(解决了原型链继承的属性共享问题,但无法继承父原型方法)```3.组合继承(原型链+构造函数):结合两者,父实例属性通过`call`继承,父原型方法通过原型链继承。```javascriptfunctionParent(name){=name;}Ptotype.sayHi=function(){/.../};functionChild(name){Parent.call(this,name);//继承实例属性}Ctotype=newParent();//继承原型方法Ctotype.constructor=Child;```4.ES6类继承(推荐):使用`class`和`extends`,底层仍基于原型链。```javascriptclassParent{constructor(name){=name;}sayHi(){console.log('Hi,'+);}}classChildextendsParent{constructor(name,age){super(name);//调用父构造函数this.age=age;}}```Q:PHP中如何优化数据库查询性能?A:优化方向包括SQL语句、索引、服务器配置和代码逻辑:1.优化SQL语句:避免`SELECT`(只取需要字段),减少`JOIN`表数量,避免子查询(用`JOIN`替代),合理使用`EXPLAIN`分析执行计划(查看是否全表扫描、索引是否生效)。2.索引优化:为`WHERE`、`JOIN`、`ORDERBY`、`GROUPBY`涉及的字段添加索引(避免在低基数列如性别字段建索引),复合索引遵循“最左前缀”原则,定期重建/分析索引(`ANALYZETABLE`)。3.减少数据库交互:批量插入(`INSERTINTO...VALUES(...),(...)`),使用`LIMIT`分页(避免`SELECTCOUNT()`全表统计,可用近似值或缓存),开启查询缓存(MySQL8.0已移除,可用Redis缓存热点数据)。4.分库分表:数据量过大时,按业务(如用户库、订单库)分库,按时间或ID哈希分表(如`user_001`、`user_002`)。5.使用连接池:PHP-FPM配合持久化连接(`pdo_mysql.persistence`)减少连接开销(需注意长连接可能导致的线程安全问题)。示例:慢查询优化前:```sqlSELECTFROMordersWHEREuser_id=123ORDERBYcreate_timeDESC;```若`user_id`无索引,会全表扫描。优化:为`(user_id,create_time)`添加复合索引,SQL改为:```sqlSELECTid,amountFROMordersWHEREuser_id=123ORDERBYcreate_timeDESCLIMIT10;```Q:JavaScript中`typeof`和`instanceof`的区别?A:`typeof`返回变量的原始类型(字符串形式),`instanceof`判断对象是否是某个构造函数的实例(基于原型链)。typeof:对基本类型:`number`、`string`、`boolean`、`undefined`、`symbol`、`bigint`。对对象:`object`(函数返回`function`)。示例:`typeofnull`返回`object`(历史遗留问题),`typeof[]`返回`object`。instanceof:检查对象的`[[Prototype]]`链是否包含构造函数的`prototype`属性。示例:`[]instanceofArray`为`true`,`[]instanceofObject`也为`true`(因数组原型链指向`Ototype`)。注意:`typeof`无法区分对象类型(如数组、日期),`instanceof`无法判断基本类型(需先包装为对象,如`newString('a')instanceofString`)。Q:PHP中`session_start()`为什么通常放在文件顶部?A:原因有三:1.Cookie发送限制:`session_start()`会发送`Set-Cookie`头(传递`PHPSESSID`),而HTTP头必须在任何输出(包括空格、HTML标签)之前发送。若文件顶部有输出,会导致`Headersalreadysent`错误。2.会话数据读取:`session_start()`会读取当前会话数据(从文件/Redis等存储),若在业务逻辑中间调用,可能导致之前的代码无法访问会话变量。3.性能优化:尽早启动会话可避免重复启动(如包含其他文件时),减少不必要的开销。若必须在输出后启动会话,可通过`ob_start()`开启输出缓冲(缓存输出,待头信息发送后再输出内容),但需注意缓冲可能增加内存消耗。Q:JavaScript中如何实现函数防抖(debounce)和节流(throttle)?A:两者均用于限制函数执行频率,适用于滚动、输入框搜索等场景:防抖(debounce):在事件连续触发时,仅最后一次触发后延迟执行。例如搜索框输入,用户停止输入300ms后再请求接口。实现:```javascriptfunctiondebounce(fn,delay=300){lettimer=null;returnfunction(...args){clearTimeout(timer);//每次触发时重置定时器timer=setTimeout(()=>fn.apply(this,args),delay);};}//使用:input.addEventListener('input',debounce(search,300));```节流(throttle):在固定时间间隔内只执行一次。例如滚动事件,每200ms执行一次处理函数。实现(时间戳版):```javascriptfunctionthrottle(fn,interval=200){letlastTime=0;returnfunction(...args){constnow=Date.now();if(nowlastTime>=interval){fn.apply(this,args);lastTime=now;}};}//或定时器版(延迟执行最后一次)```区别:防抖关注“停止触发后执行”,节流关注“固定频率执行”。Q:PHP中`final`、`abstract`、`static`关键字的作用?A:final:修饰类时,类不可被继承;修饰方法时,方法不可被子类重写。用于限制扩展(如核心工具类)。```phpfinalclassMyClass{/不可被继承/}classParentClass{finalpublicfunctiontest(){/不可被重写/}}```abstract:修饰类时为抽象类(不可实例化,需子类实现抽象方法);修饰方法时为抽象方法(无方法体,子类必须实现)。用于定义接口规范。```phpabstractclassAnimal{abstractpublicfunctionsound();//抽象方法}classDogextendsAnimal{publicfunctionsound(){echo'汪汪';}//必须实现}```static:修饰属性/方法时,属于类本身(而非实例),可通过`类名::`直接访问。静态属性在类加载时初始化,所有实例共享同一值。```phpclassCounter{publicstatic$count=0;publicstaticfunctionincrement(){self::$count++;}}Counter::increment();echoCounter::$count;//1```Q:JavaScript中`async/await`的原理是什么?如何处理多个异步操作?A:`async/await`是基于`Promise`的语法糖,通过`async`声明函数返回`Promise`,`await`暂停执行并等待`Promise`解决(或抛出错误)。其原理是利用提供器(Generator)和自动执行器,将异步代码转换为类似同步的线性结构。处理多个异步操作:1.顺序执行:`await`逐个调用,前一个完成后执行下一个。```javascriptasyncfunctionfetchData(){constres1=awaitfetch('/api1');constres2=awaitfetch('/api2');//等待res1完成return[res1,res2];}```2.并行执行:用`Promise.all`同时启动,等待所有完成(适合无依赖的异步操作)。```javascriptasyncfunctionfetchData(){const[res1,res2]=awaitPromise.all([fetch('/api1'),fetch('/api2')]);return[res1,res2];}```3.竞态执行:用`Promise.race`取最先完成的结果(如超时处理)。```javascriptasyncfunctionfetchWithTimeout(){consttimeout=newPromise((_,reject)=>setTimeout(()=>reject('超时'),5000));constres=awaitPromise.race([fetch('/api'),timeout]);returnres;}```注意:`await`后若不是`Promise`会隐式转换为`Promise.resolve()`,错误需用`try-catch`捕获。Q:PHP中如何处理大文件上传?需要注意哪些配置?A:大文件上传需调整PHP和Web服务器配置,并优化代码逻辑:1.PHP配置:`upload_max_filesize`:单个文件最大大小(默认2M)。`post_max_size`:POST请求总数据大小(需大于`upload_max_filesize`,默认8M)。`max_execution_time`:脚本最大执行时间(默认30秒,上传大文件需延长)。`memory_limit`:脚本内存限制(上传时可能需要更多内存处理文件,如`128M`)。2.Nginx/Apache配置:Nginx:`client_max_body_size`设置请求体大小(默认1M)。Apache:`LimitRequestBody`设置请求体大小(需启用`mod_request`模块)。3.分块上传:将文件切分为小片段(如1MB/片),依次上传后合并。前端用`FormData`或`Blob.slice`分片,后端用`file_put_contents($path,$chunk,FILE_APPEND)`追加写入。4.进度跟踪:前端用`XMLHttpRequest.upload.onprogress`事件获取上传进度;后端用`$_SESSION`记录已上传分片(需注意并发问题,可用Redis替代Session)。5.临时文件清理:上传失败时删除临时分片,避免磁盘空间浪费。示例分块上传后端逻辑(PHP):```php$chunk=$_FILES['chunk']['tmp_name'];$filename=$_POST['filename'];$chunkInde

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论