快手评论点赞网站建设专业分站,创艺装饰公司,高端网站建设制作,建湖网站开发目录
1#xff09;html#xff0c;http#xff0c;web基础篇
进程和线程的区别#xff1f;
如何理解html语义化#xff1f;用过哪些html标签#xff1f;
h5新特性
canvas相关
cookie,session,localStorage区别#xff0c;cookie的长度限制
什么是cookie隔离…目录1htmlhttpweb基础篇进程和线程的区别如何理解html语义化用过哪些html标签h5新特性canvas相关cookie,session,localStorage区别cookie的长度限制什么是cookie隔离请求资源时不要带cookie怎么做?cookie和session有哪些区别cookie和token的区别 ?登陆后前端做了哪些工作如何得知已登录前端性能优化方法浏览器输入url后发生了什么css加载会造成阻塞吗为什么js会阻塞页面加载websocket了解浏览器缓存机制吗强缓存 协商缓存(136)常见的块元素行内元素行内块元素懒加载和预加载常见的网络攻击方式有哪些什么是xss攻击什么是csrf攻击同源策略什么是跨域为什么浏览器要使用同源策略跨域的几种解决方案了解预检请求吗了解CDN么为什么要用CDNCDN的核心是什么dns 域名解析osi七层模型常用端口号2css篇link和import的区别盒模型display:nonevisibility:hidden和opcatity:0的区别BFC相关margin塌陷清除浮动选择器优先级absolute定位是基于什么的水平垂直居中css做圆形三角形媒介查询相关的自适应布局重排(回流/reflow)和重绘(repaint或redraw)该怎么优化怎么减少回流动画相关高性能动画是什么衡量它的标准是什么flex布局精灵图伪类和伪元素3js篇script放在head会造成什么问题如何解决script 引入方式什么是windows对象什么是document对象bom和dom介绍一下JavaScript的执行上下文(50)迭代器的原理如何实现闭包内存泄漏使用闭包应该注意什么闭包的this指向作用域链变量提升letvarconst常用数组字符串方法map和forEach区别js事件循环机制宏任务微任务async/await,读代码运行顺序原型、构造函数实例介绍一下JavaScript的原型链js原型链的顶端是什么Object的原型是什么对象继承方法讲讲继承多态new做了什么操作箭头函数的特性谈谈对this的理解bind,call,apply的区别手撕源码this指向设计模式应用场景手撕源码什么是单例模式什么是简单工厂模式get和post为什么javascript是单线程与异步有冲突吗同步和异步的区别说一下promise解决了什么问题。他的底层逻辑如何实现没有promise该怎么办延时和异步如何解决异步回调地狱defer和async的区别async/await具体该怎么用promise和async/await的关系promisepromise.all,promise.race源码手撕让你写一个请求5秒内执行完就返回执行结果否则返回超时ajax和axiosfetch的区别是什么requestJS的核心原理是什么如何动态加载的如何避免多次重复加载如何缓存垃圾回收基本数据类型 和的区别js动画和css动画区别 为什么css动画比JavaScript高效dom0级事件dom2级事件模块化防抖节流深浅拷贝什么是事件监听说说前端中的事件流如何阻止事件冒泡事件委托浏览器渲染过程generator如何判断数组在数组原型链上实现删除数组重复数据的方法。数组去重有哪些方法数组展平typeof 和instance of为什么0.10.20.34webpack篇怎么打包 webpack是用来干什么的 除了webpack用过其他打包工具吗webpack热更新原理loader和plugin5vuejs篇双向绑定原理手撕简单源码6react及react native篇Vue和React的区别react 路由模式react单向数据流的好处 ?react和vue的区别说一下什么是虚拟DOM?为什么要使用虚拟DOM虚拟DOM是怎么工作的为什么操作 DOM 慢?diff算法setstate同步还是异步具体过程redux原理ReactHookReact生命周期容器组件和展示组件父子组件通信非父子通信高阶组件高阶组件不是组件shouldComponentUpdate 可以避免不必要的render7计算机网络http和https的区别是什么http特点B/S架构。为什么要用httpshttps的缺点HTTPS为什么要使用一个对称加密和非对称加密相结合的一个方式http1.0,1.1,2.0,3.0特性http状态码尤其301和302区别304。http请求几种方法及区别尤其get/post的幂等性TCP 和 UDP有什么特点有哪些区别大概适用于什么样的场合。TCP的三次握手和四次挥手2MSL是为啥TCP的拥塞控制8其他9主管/hr面问题职业规划你有什么优点与众不同的东西你有什么缺点别傻傻的光说缺点说说你是怎么克服或者绕开它们的呀10反问环节的参考提问讲讲前端工程化场景1htmlhttpweb基础篇进程和线程的区别做个简单的比喻进程火车线程车厢线程在进程下行进单纯的车厢无法运行一个进程可以包含多个线程一辆火车可以有多个车厢不同进程间数据很难共享一辆火车上的乘客很难换到另外一辆火车比如站点换乘同一进程下不同线程间数据很易共享A车厢换到B车厢很容易进程要比线程消耗更多的计算机资源采用多列火车相比多个车厢更耗资源进程间不会相互影响一个线程挂掉将导致整个进程挂掉一列火车不会影响到另外一列火车但是如果一列火车上中间的一节车厢着火了将影响到所有车厢进程可以拓展到多机进程最多适合多核不同火车可以开在多个轨道上同一火车的车厢不能在行进的不同的轨道上进程使用的内存地址可以上锁即一个线程使用某些共享内存时其他线程必须等它结束才能使用这一块内存。比如火车上的洗手间互斥锁进程使用的内存地址可以限定使用量比如火车上的餐厅最多只允许多少人进入如果满了需要在门口等等有人出来了才能进去“信号量”如何理解html语义化用过哪些html标签html语义化是说用正确的标签做正确的事。html标签可以分为块级标签行内标签内联块状标签行内元素与块级函数可以相互转换通过修改display属性值来切换块级元素和行内元素行内元素displayinline块级元素displayblock。块级标签标签独占一行宽度与高度撑满父元素。、、...、、、、、、、行内标签标签在一行内宽度与高度由内容决定只有在内容超过HTML的宽度时才会换行。、、、、、、、、、内联块状标签内联块状元素inline-block就是同时具备内联元素、块状元素的特点代码display:inline-block就是将元素设置为内联块状元素。(css2.1新增)、标签就是这种内联块状标签h5新特性1. HTML语义化,有助于爬虫抓取更多的有效信息爬虫是依赖于标签来确定上下文和各个关键字的权重.2. 本地存储h5提供了sessionStorage、localStorage和cookie使用之前应该先判断支持情况。注意localStorage存储的数据是不能跨浏览器共用的一个浏览器只能读取各自浏览器的数据,储存空间5M。3. 离线web应用4.表单新增功能。以往input中的name和value要随着form表单一起提交form表单必须包裹input , 而现在可以通过input的form属性綁定.5.地理定位h5提供了Geolocation API访问地理位置即通过window.navigator.geolocation来实现访问。这个对象有三个方法:getCurrentPosition()、watchPosition()、clearWatch()页面第一次使用这个api需要获得用户许可, watchPosition可以对位置变化事件进行监听。canvas相关绘制一个绿色的长方形cookie,session,localStorage区别cookie的长度限制localStorage本地存储和sessionStorage会话存储不会自动把数据发给服务器localStorage长期存储数据浏览器关闭数据后不丢失仅在本地保存大小为一般为5MBsessionStorage仅在当前会话下有效关闭页面或浏览器后被清除。存放数据大小为一般为5MB如果两个页面存在关系则可以共享sessionStoragecookie是网站为了标识用户身份而存储在用户本地终端Client Side上的数据通常经过加密。cookie始终在同源的http请求中携带即使不需要都会在浏览器和服务器端间来回传递cookie数据大小不会超过4K。有期时间localStorage存储持久数据浏览器关闭后数据不丢失除非自动删除数据。sessionStorage数据在当前浏览器窗口关闭后自动删除。cookie 设置的cookie过期时间之前一直有效即使窗口或者浏览器关闭cookie和session的区别1、cookie数据存放在客户的浏览器上session数据放在服务器上2、session保存在服务器客户端不知道其中的信息cookie保存在客户端服务器能够知道其中的信息3、session中保存的是对象cookie中保存的是字符串4、cookie不是很安全别人可以分析存放在本地的cookie并进行cookie欺骗考虑*到安全应当使用session5、session会在一定时间内保存在服务器上当访问增多会比较占用你服务器的性能考虑到减轻服务器性能方面应当使用cookie6、单个cookie保存的数*据不能超过4K很多浏览器都限制一个站点最多保存20个cookie7、建议将登录信息等重要信息存放为session其他信息如果需要保留可以放在cookie中8、session不能区分路径同一个用户在访问一个网站期间所有的session在任何一个地方都可以访问到而cookie中如果设置了路径参数那么同一个网站中不同路径下的cookie互相是访问不到的。9、COOKIE:是服务端向客户端写入的小的片段信息。cookie信息保存在服务器缓存区不会在客户端显现。当你第一次登陆一个网站服务器向你的机器写得片段信息。你可以在Internet选项中找到存放cookie的文件夹。如果不删除cookie就一直在这个文件夹中。10、session需要借助cookie才能正常工作。如果客户端完全禁止cookiesession将失效。 但是如果服务器端启用了url编码也就是用 URLEncoder.encode()把所有的url编码了则会在url后面出现如下类似的东西 index.jsp:jsessionidfdsaffjdlks;jaf;lkdjsf 服务器通过这个进行session的判断.11.Cookie支持跨域名访问例如将domain属性设置为“.biaodianfu.com”则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中例如Google、Baidu、Sina等,而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。仅运用Cookie或者仅运用Session可能完成不了理想的效果。这时应该尝试一下同时运用Cookie与Session。Cookie与Session的搭配运用在实践项目中会完成很多意想不到的效果。什么是cookie隔离请求资源时不要带cookie怎么做?如果静态文件都放在主域名下那静态文件请求的时候都带有的cookie的数据提交给server的非常浪费流量所以不如隔离开。因为cookie有域的限制因此不能跨域提交请求故使用非主要域名的时候请求头中就不会带有cookie数据这样可以降低请求头的大小降低请求时间从而达到降低整体请求延时的目的。同时这种方式不会将cookie传入server也减少了server对cookie的处理分析环节提高了server的http请求的解析速度。cookie和session有哪些区别Cookie是存放在客户端浏览器Session是保存在服务端。Cookie是客户端保存用户信息的一种机制用来记录用户的一些信息。可以设置有效期Session是服务端记录用户状态时用于标识具体用户。在浏览器窗口关闭后这次的Session就消失了。Cookie的安全性不如SessionSession如果过多会对服务端产生较大的压力不是特别重要的数据可以考虑使用Cookie存放cookie和token的区别 ?token和cookie一样都是首次登陆时由服务器下发都是当交互时进行验证的功能作用都是为无状态的HTTP提供的持久机制。token存在哪儿都行localstorage或者cookie。当用户退出登录的时候cookie和服务器的session都会注销但是用户退出登录的时候token只是注销浏览器信息不查库。登陆后前端做了哪些工作如何得知已登录前端存放服务端下发的cookie, 简单说就是写一个字段在cookie中表明已登录, 并设置失效日期或使用后端返回的token, 每次ajax请求将token携带在请求头中, 这也是防范csrf的手段之一。前端性能优化方法1浏览器渲染机制减少重绘重排2事件处理程序使用事件委托3网络请求优化善用缓存不重复加载相同的资源减少 HTTP 请求使用http2.04静态资源使用 内容分发网络CDN是一组分布在多个不同地理位置的 Web 服务器。我们都知道当服务器离用户越远时延迟越高。CDN 就是为了解决这一问题在多个位置部署服务器让用户离服务器更近从而缩短请求时间。浏览器输入url后发生了什么DNS 解析:将域名解析成 IP 地址TCP 连接TCP 三次握手发送 HTTP 请求服务器处理请求并返回 HTTP 报文html浏览器解析渲染页面断开连接TCP 四次挥手TCP 三次握手结束后开始发送 HTTP 请求报文。根据 HTML 解析出 DOM 树根据 CSS 解析生成 CSS 规则树结合 DOM 树和 CSS 规则树生成渲染树根据渲染树计算每一个节点的信息。请求报文由请求行request line、请求头header、请求体 构成。1.请求行包含请求方法、URL、协议版本2.请求头包含请求的附加信息由关键 字/值对组成每行一对关键字和值用英文冒号“:”分隔。 比如Host表示主机名虚拟主机Connection,HTTP/1.1 增加的使用 keepalive即持久 连接一个连接可以发多个请求User-Agent请求发出者兼容性以及定制化 需求。3.请求体可以承载多个请求参数的数据包含回车符、换行符和请求数据并不是所有请求都具有请求数据。css加载会造成阻塞吗CSS 不会阻塞 DOM 解析但会阻塞 DOM 渲染。CSS 会阻塞 JS 执行并不会阻塞 JS 文件下载CSSOM 作用第一个是提供给 JavaScript 操作样式表的能力第二个是为布局树的合成提供基础的样式信息 这个 CSSOM 体现在 DOM 中就是 document.styleSheets。由之前讲过的浏览器渲染流程我们可以看出 DOM 和 CSSOM 通常是并行构建的所以「CSS 加载不会阻塞 DOM 的解析」。 然而由于 Render Tree 是依赖 DOM Tree 和 CSSOM Tree 的所以它必须等到两 者都加载完毕后完成相应的构建才开始渲染因此「CSS 加载会阻塞 DOM 渲染」。由于 JavaScript 是可操纵 DOM 和 css 样式 的,如果在修改这些元素属性同 时渲染界面即 JavaScript 线程和 UI 线程同时运行,那么渲染线程前后获 得的元素数据就可能不一致了。 因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与 JavaScript 引擎为互斥」的关系。有个需要注意的点就是 「有时候 JS 需要等到 CSS 的下载这是为什么呢」 仔细思考一下其实这样做是有道理的如果脚本的内容是获取元素的样式宽 高等 CSS 控制的属性浏览器是需要计算的也就是依赖于 CSS。浏览器也无法 感知脚本内容到底是什么为避免样式获取因而只好等前面所有的样式下载完 后再执行 JS。JS 文件下载和 CSS 文件下载是并行的有时候 CSS 文件很大所以 JS 需要等待。 因此,样式表会在后面的 js 执行前先加载执行完毕,所以「css 会阻塞后面 js 的执行」。为什么js会阻塞页面加载1. 现代浏览器会并行加载js文件。2.加载或者执行js时会阻塞对标签的解析也就是阻塞了dom树的形成只有等到js执行完毕浏览器才会继续解析标签。没有dom树浏览器就无法渲染所以当加载很大的js文件时可以看到页面很长时间是一片空白。所以会阻塞对标签的解析是因为加载的js中可能会创建删除节点等这些操作会对dom树产生影响如果不阻塞等浏览器解析完标签生成dom树后js修改了某些节点那么浏览器又得重新解析然后生成dom树性能比较差。websocketHTTP 协议有一个缺陷通信只能由客户端发起做不到服务器主动向客户端推送信息。1建立在 TCP 协议之上服务器端的实现比较容易。2与 HTTP 协议有着良好的兼容性。默认端口也是80和443并且握手阶段采用 HTTP 协议因此握手时不容易屏蔽能通过各种 HTTP 代理服务器。3数据格式比较轻量性能开销小通信高效。4可以发送文本也可以发送二进制数据。5没有同源限制客户端可以与任意服务器通信。6协议标识符是ws如果加密则为wss服务器网址就是 URL。了解浏览器缓存机制吗强缓存 协商缓存(136)浏览器缓存就是把一个已经请求过的资源拷贝一份存储起来当下次需要该资源时浏览器会根据缓存机制决定直接使用缓存资源还是再次向服务器发送请求。作用: 减少网络传输的损耗以及降低服务器压力。强制缓存本地缓存给资源设置过期时间客户端每次请求资源时都会查看是否过期如果过期则向服务器再次发送请求。协商缓存当强缓存过期时客户端向服务器发送请求时可以设置协商缓存请求资源时把本地该资源的唯一ID携带发给服务器服务器和最新资源做对比资源没变返回304浏览器读取本地缓存。资源改变返回200返回最新资源。优先级: 强制缓存 协商缓存;1强缓存为什么要有两个呢 Expires, Cache-Control?Cache-Control有哪些属性?分别表示什么意思两者作用差不多区别就在于 Expires 是http1.0的产物Cache-Control是http1.1的产物两者同时存在的话Cache-Control优先级高于ExpiresExpires过期时间浏览器再次加载资源时如果在这个过期时间内则命中强缓存。Cache-Control:则代表在这个请求正确返回时间浏览器也会记录下来的5分钟内再次加载资源就会命中强缓存。2协商缓存出于什么原因有Last-Modified,Etag? etag的原理?Etag是上一次加载资源时该资源的一种唯一标识只要资源有变化Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时会将上一次返回的Etag值放到request 会拿来跟该资源文件的Etag值做比较如果相同则表示资源文件没有发生改变命中协商缓存。Last-Modified是该资源文件最后一次更改时间服务器会在response header里返回同时浏览器会将这个值保存起来在下一次发送请求时放到request header里的If-Modified-Since里服务器在接收到后也会做比对如果相同则命中协商缓存。常见的块元素行内元素行内块元素display 属性在块级元素和行内元素的转换display 有三个值inline:值为 inline 将变成行内元素比如 div。不能设置宽高和行内元素并排block:值为 block 的比如 span。能设置宽高填充父级独占一行。inline-block值为 inline-block 也就是变成行内块元素1块级元素块元素通常会独占一行或者多行它的宽高边距等都可以设置。定义表格标题定义地址定义列表中定义条目定义文档中的分区或节定义列表 定义列表中的项目 定义一个框架集 创建 HTML 表单~定义标题定义一条水平线定义段落定义表格标签定义列表项目定义无序列表定义有序列表2行内元素又称为内联元素行内元素的大小是靠本身内容的大小宽高都设置无效。标签定义超链接表示一缩写形式定义只取首字母缩写定义字体缩写可覆盖默认的文本方向定义大号字体加粗定义换行定义计算机代码文本标签创建单选或多选菜单组合文档中的行内元素3行内块元素行内块元素从文字上看像块级元素和行内元素结合似的其实比较特殊比如可以设置宽高属性这种就称为行内块元素。懒加载和预加载预加载提前加载图片当用户需要查看时可直接从本地缓存中渲染。懒加载懒加载的主要目的是作为服务器前端的优化减少请求数或延迟请求数。1.第一种是纯粹的延迟加载使用setTimeOut或setInterval进行加载延迟.2.第二种是条件加载符合某些条件或触发了某些事件才开始异步下载。3.第三种是可视区加载即仅加载用户可以看到的区域这个主要由监控滚动条来实现一般会在距用户看到某图片前一定距离遍开始加载这样能保证用户拉下时正好能看到图片。两种技术的本质两者的行为是相反的一个是提前加载一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用预加载则会增加服务器前端压力。常见的网络攻击方式有哪些什么是xss攻击什么是csrf攻击Xss(cross-site scripting) 攻击全称跨站脚本攻击攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候那么嵌入到web页面中script代码会执行因此会达到恶意攻击用户的目的。CSRF (Cross Site Request Forgery)跨站请求伪造攻击者借助用户的 Cookie 骗取服务器的信任以用户名义伪造请求发送给服务器。如在请求的 url 后加入一些恶意的参数。防范CSRF添加 token 验证在 HTTP 请求中以参数的形式加入一个随机产生的 token并在服务器端建立一个拦截器来验证这个 token若请求无 token 或者 token 不正确则认为可能是 CSRF 攻击而拒绝该请求。同源策略什么是跨域为什么浏览器要使用同源策略跨域的几种解决方案了解预检请求吗同源策略: 协议/主机/端口我们来看下面的页面是否与 http://store.company.com/dir/index.html 是同源的http://store.company.com/dir/index2.html 同源http://store.company.com/dir2/index3.html 同源 虽然在不同文件夹下https://store.company.com/secure.html 不同源 不同的协议(https)http://store.company.com:81/dir/index.html 不同源 不同的端口(81)http://news.company.com/dir/other.html 不同源 不同的主机(news)浏览器使用同源策略主要是为了安全比如如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取。防止 XSS、CSFR 等攻击。跨域是指一个域下的文档或脚本试图去请求另一个域下的资源。跨域并不是请求发不出去请求能发出去服务端能收到请求并正常返回结果只是结果被浏览器拦截了。解决方案1jsonpajax受同源影响利用JS中src属性连接访问跨域JS。不安全可能会遭受 XSS 攻击。只能get不安全、有缓存、大小限制。2CORS:服务端设置。3nginx 反向代理搭建一个中转 nginx 服务器用于转发请求。4webpack添加proxy5location.hash:a与b跨域通过中间页c不同域location.hash传值。不同域js。预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器以获知服务器是否允许该实际请求。预检请求“的使用可以避免跨域请求对服务器的用户数据产生未预期的影响。了解CDN么为什么要用CDNCDN的核心是什么和西天取经一个道理唐僧取经之前国内想看经书只能跑老远去西天看经书唐僧取经回来再去国内各地传播之后各地的人想听佛法就去最近的寺庙听就好了CDN 内容分发网络CDN的核心点有两个一个是缓存一个是回源。静态资源本身具有访问频率高、承接流量大的特点因此静态资源加载速度始终是前端性能的一个非常关键的指标。CDN 是静态资源提速的重要手段在许多一线的互联网公司“静态资源走 CDN”并不是一个建议而是一个规定dns 域名解析DNS 主要的作用就是将人们所熟悉的网址 (域名) “翻译”成电脑可以理解的 IP 地址这个过程叫做 DNS 域名解析一个域名往往对应多个DNS地址。DNS的规范规定了2种类型的DNS服务器一个叫主DNS服务器一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时它需要与主DNS服务器通信并加载数据信息这就叫做区域传送zone transfer。 这种情况下使用TCP协议。为什么域名解析用UDP协议?因为UDP快啊UDP的DNS协议只要一个请求、一个应答就好了。而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手。但是UDP协议传输内容不能超过512字节。不过客户端向DNS服务器查询域名一般返回的内容都不超过512字节用UDP传输即可。为什么区域传送用TCP协议因为TCP协议可靠性好啊你要从主DNS上复制内容啊你用不可靠的UDP 因为TCP协议传输的内容大啊你用最大只能传512字节的UDP协议万一同步的数据大于512字节你怎么办osi七层模型物理层作用通过媒介输出比特bit协议RJ45、CLOCK、IEEE802.3设备中继器、集线器数据链路层作用将比特组装成帧Frame和点对点传递协议PPP FR HDLC VLAN MAC设备网桥、交换机数据链路层在概念上分为两个子层逻辑链路控制子层LLC和媒体访问控制子层MAC。数据链路层负责分配MAC地址或称为物理地址由48比特长12个16进制数字组成0~23位。是厂商向IETF等机构申请用来标识厂商的代码。网络层作用负责数据包从源到宿的传递和网际交互协议IP IPX ICMP IGMP ARP RARP OSPF设备网络层中继系统路由器网络层以上的中继系统网关传输层作用提供端到端的可靠报文传递和错误恢复协议TCP (传输控制协议面向连接的数据传输的单位是报文段提供可靠的交付)UDP用户控制协议它是无连接的数据传输的单位是用户数据报它不能保证提供可靠的交付SCTP (流控制传输协议 Stream Control Transmission Protocol )会话层作用建立管理和终止会话会话协议的数据单元SPDU协议NFS SQL NETBIOS RPC表示层作用数据翻译、解密和压缩表示协议数据单元PPDU协议JPEG MPEG ASII应用层作用允许访问OSI环境的手段应用协议数据单元APDU协议FTP文件传输协议、DNS域名解析协议、Telnet虚拟终端协议、SMTP电子邮件协议、HTTP超文本传输协议、www、NFS常用端口号端口号小于256的一般为常用端口号HTTP协议代理服务器常用端口号80/8080/3128/8081/9098FTP文件传输协议代理服务器常用端口号21TOMCAT默认端口号为8080Oracle 数据库默认的端口号为15212css篇link和import的区别import是 CSS 提供的语法规则只有导入样式表的作用link是HTML提供的标签不仅可以加载 CSS 文件还可以定义 RSS、rel 连接属性等盒模型w3c宽度内容的宽度content border padding marginIE 宽度内容宽度contentborderpadding margindisplay:nonevisibility:hidden和opcatity:0的区别display:none隐藏后不占据额外空间它会产生回流和重绘而visibility:hidden和opacity:0元素虽然隐藏了但它们仍然占据着空间它们俩只会引起页面重绘。display:none不会被子元素继承但是父元素都不在了子元素自然也就不会显示了皮之不存毛之安附~~visibility:hidden 会被子元素继承可以通过设置子元素visibility:visible 使子元素显示出来opacity: 0 也会被子元素继承但是不能通过设置子元素opacity: 0使其重新显BFC相关BFC就是让元素成为一个个独立的块他们之间互不影响。 bfc是块级格式上下文它是页面中的一块渲染区域并且有一套渲染规则它决定了其子元素将如何定位以及和其他元素的关系和相互作用。通俗一点来讲可以把 BFC 理解为一个封闭的大箱子箱子内部的元素无论如何翻江倒海都不会影响到外部。影响同一个BFC下外边距会发生重叠在网页制作过程中由于浏览器加载是自上而下的原因外边距上下会取最大值左右不受影响。解决此处用个div给包住只通过一行代码(给外层的div 添加属性position:absolute) ps:inherit除外margin塌陷第一种情况两个同级元素垂直排列上面的盒子给margin-bottom下面的盒子给margin-top那么他们两个的间距会重叠以大的那个计算。解决这种情况的方法为(1)两个外边距不同时出现.(2)用个div给包住给外层的div 添加属性position:absolute第二种情况两个父子元素内部的盒子给margin-top其父级也会受到影响同时产生上边距父子元素会进行粘连。解决这种情况的方法为父级添加一个css属性overflow: hidden禁止超出外边距重叠就是margin-collapse。解决方案1、为父盒子设置border为外层添加border后父子盒子就不是真正意义上的贴合(可以设置成透明border1px solid ansparent);2、为父盒子添加overflow: hidden;3、为父盒子设定padding值;4、为父盒子添加position: fixed;5、为父盒子添加 display: table;6、利用伪元素给父元素的前面添加一个空元素。清除浮动清除浮动主要是为了解决父元素因为子级元素浮动引起的内部高度为0的问题当父元素不给高度的时候内部元素不浮动时会撑开而浮动的时候父元素变成一条线。解决方法1使用after伪元素清除浮动推荐使用.clearfix:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/content: “”;display: block;height: 0;clear:both;visibility: hidden;}2使用before和after双伪元素清除浮动。3父级添加overflow属性父元素添加overflow:hidden不推荐4额外标签法在最后一个浮动标签后新加一个标签给其设置clearboth不推荐选择器优先级在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式。作为style属性写在元素内的样式id选择器类选择器标签选择器通配符选择器浏览器自定义或继承!important 行内样式ID选择器 类选择器 标签 通配符 继承 浏览器默认属性。同一级别中后写的会覆盖先写的样式absolute定位是基于什么的相对定位relative相对定位的块状元素相对于原来位置移动移动后仍然占据文档流的位置不影响其他元素的布局绝对定位absolute被绝对定位的对象将从文档流中脱离绝对定位的参照位置看它的上级或上上级有没有定位了如果父级没有设置定位属性则会相对于html根元素进行定位水平垂直居中水平居中(1)text-aligncenter(2)flex垂直居中(1)flexcss做圆形三角形媒介查询相关的自适应布局pxemrempx像素em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置则相对于浏览器的默认字体尺寸。em是CSS3新增的一个相对单位root em根em使用rem为元素设定字体大小时相对的是HTML根元素。可以做到只修改根元素就成比例地调整所有字体大小又可以避免字体大小逐层复合的连锁反应。重排(回流/reflow)和重绘(repaint或redraw)该怎么优化怎么减少回流重排必重绘重排(回流/reflow)对DOM树进行渲染只要DOM树上的属性改变了浏览器布局就会触发reflowreflow的时候浏览器会使被改变的那部分DOM树失效并重新构造这部分。重绘(repaint)当渲染树中的一些元素需要更新但更新的属性不会改变浏览器布局位置的操作直接可以为该元素绘制新的样式跳过了回流环节这个过程就叫重绘。如何减少回流、重绘减少回流、重绘就是减少对DOM的操作1.IE中避免使用javascript表达式2.如果动态改变样式直接改变className3. 使用 transform 替代 top实现动画性能更好因为使用transform页面没有回流了.4.让要操作的元素进行“离线处理”处理完后一起更新当使用DocumentFragment进行缓存操作引发一次回流和重绘使用display:none 技术只引发两次回流和重绘使用cloneNode(true or false)和replaceChild技术引发一次回流和重绘5.不要经常访问会引起浏览器flush队列的属性如果你确实要访问利用缓存6.让元素脱离动画流减少render 树的规模7.牺牲平滑度换取速度8.避免使用table布局动画相关CSS3 中有三个关于动画的样式属性transform、transition和animation1transformtransform可以用来设置元素的形状改变。主要有以下几种变形rotate旋转、scale缩放、skew扭曲、translate移动和matrix矩阵变形。2transitiontransition是用来设置样式的属性值是如何从从一种状态变平滑过渡到另外一种状态它有四个属性transition-property变换的属性即那种形式的变换大小、位置、扭曲等transition-duration变换延续的时间transition-timing-function变换的速率transition-delay变换的延时3animationanimation比较类似于 flash 中的逐帧动画逐帧动画就像电影的播放一样表现非常细腻并且有非常大的灵活性。然而transition只是指定了开始和结束态整个动画的过程也是由特定的函数控制。学习过 flash 的同学知道这种逐帧动画是由关键帧组成很多个关键帧连续的播放就组成了动画在 CSS3 中是由属性keyframes来完成逐帧动画的。animationName动画名称开发人员自己命名percentage为百分比值可以添加多个百分比值properties样式属性名称例如color、left、width等等。高性能动画是什么衡量它的标准是什么动画帧率可以作为衡量标准一般来说画面在 60fps 的帧率下效果比较好。flex布局flex-direction: row || column;justify-content: 控制 flex 项在主轴上的位置。centerflex-startflex-endspace-around(沿着主轴均匀地分布,两端留下空间。)space-between(沿着主轴均匀地分布,两端不留空间。)align-items:控制 flex 项在交叉轴上的位置。centerflex-startflex-end精灵图所谓精灵图就是把很多的小图片合并到一张较大的图片里所以在首次加载页面的时候就不用加载过多的小图片只需要加载出来将小图片合并起来的那一张大图片也就是精灵图即可这样在一定程度上减少了页面的加载速度也一定程度上缓解了服务器的压力。例如王者荣耀页面里的几个小logo。其实说白了就是将精灵图设为一个大背景然后通过background-position来移动背景图从而显示出我们想要显示出来的部分。精灵图虽然实现了缓解服务器压力以及用户体验等问题但还是有一个很大的不足那就是牵一发而动全身。这些图片的背景都是我们详细测量而得出来的如果需要改动页面将会是很麻烦的一项工作。。。伪类和伪元素用于向某些选择器添加特殊的效果。伪类通过选择器找到那些不存在于DOM树中的信息以及不能被常规CSS选择器获取到的信息。伪元素创建了一些抽象元素这些抽象元素是不存在于文档语言里的可以理解为html源码。比如常见的::before,::after。3js篇script放在head会造成什么问题如何解决但是放到head中没有任何效果。原因是因为文档还没加载就读了jsjs就不起作用了想在head里用的话利用 window.onload function(){} 代码包裹文档加载之后再执行建议把js代码放到body的最底部因为浏览器生成Dom树的时候是一行一行读HTML代码的script标签放在最后面就不会影响前面的页面的渲染。代码window.onload() //在网页加载完毕后立刻执行的操作script 引入方式什么是windows对象什么是document对象bom和domwindow对象代表浏览器中打开的一个窗口。也被称为BOM对象常用的比如history对象是window对象的一部分包含用户在当前浏览器窗口中访问过的URL。document对象代表整个 html 文档也被称为DOM对象document对象使我们可以从脚本中对HTML页面中的所有元素进行访问。 实际上document 对象是 window 对象的一个属性。介绍一下JavaScript的执行上下文(50)JavaScript 中运行任何的代码都是在执行上下文中运行。执行上下文有三种类型: (1)全局执行上下文 (2)函数执行上下文 (3)eval 执行上下文代码执行过程:在首次运行js的时候浏览器引擎会创建一个全局上下文并添加到执行栈中在退出浏览器的时候从执行栈中移除全局上下文。js代码逐行 自上而下 执行。遇到函数时函数执行上下文 (callee) 被 push 到执行栈顶层全局执行上下文被挂起控制权交给函数执行上下文。开始执行函数中的代码。函数执行完后函数执行上下文被 pop 移除出执行栈控制权交还全局上下文继续执行迭代器的原理如何实现迭代器的本身是一个对象这个对象有 next( ) 方法返回结果对象这个结果对象有下一个返回值 value、迭代完成布尔值 done。闭包内存泄漏闭包是有权限访问其他函数作用域的局部变量的一个函数具体解释由于在JS中变量的作用域属于函数作用域在函数执行后作用域就会被清理、内存也随之被收回但是由于闭包是建立在一个函数内部的子函数由于其可访问上级作用域的原因即使上级函数执行完作用域也不会随之销毁这时的子函数—也就是闭包便拥有了访问上级作用域中的变量的权限即使上级函数执行完后作用域内的值也不会被销毁。闭包解决了什么闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包随处可见一个 Ajax 请求的成功回调一个事件绑定的回调方法一个 setTimeout 的延时回调或者一个函数内部返回另一个匿名函数这些都是闭包。简而言之无论使用何种方式对函数类型的值进行传递当函数在别处被调用时都有闭包的身影1 一个是可以读取函数内部的变量2 另一个就是让这些变量的值始终保存在内存中。使用闭包应该注意什么1代码难以维护闭包内部是可以访问上级作用域而如果闭包又是异步执行的话一定要清楚上级作用域都发生了什么而这样就需要对代码的运行逻辑和JS运行机制相当了解才能弄明白究竟发生了什么。2使用闭包的注意点由于闭包会使得函数中的变量都保存在内存中内存消耗很大所以不能滥用闭包否则会造成网页的性能问题在IE中可能导致内存泄漏虽然实际开发中从没遇到过内存泄漏的情况。解决方法是在退出函数之前将不使用的局部变量全部删除。3内存泄漏程序的运行需要内存。对于持续运行的服务进程必须及时释放不再用到的内存否则占用越来越高轻则影响系统性能重则导致进程崩溃。不再用到的内存没有及时释放就叫做内存泄漏。闭包的this指向闭包的this指向的是window作用域链变量提升1、作用域作用域就是一个变量和函数可以使用的范围主要分为全局作用域和局部函数作用域全局作用域就是Js中最外层的作用域。ES5中作用域有全局作用域、函数作用域。没有块作用域的概念。因此也有一系列的问题。ECMAScript 6(简称ES6)中新增了块级作用域。块作用域由{ }包括if语句和for语句里面的{ }也属于块作用域。2、全局变量、局部变量1.全局变量在全局范围内声明的变量如var a1;只有赋值没有声明的值如a2; 注如果a2在函数环境中也是全局变量2局部变量写入函数中的变量叫做局部变量。3作用程序的安全。内存的释放。3、自由变量当前作用域外的变量都是自由变量作用域链:一个变量在当前作用域没有定义但是被使用了就会向上级作用域一层一层依次查找直至找到为止找到这个变量后就会停止不会继续查找这个变量如果全局作用域都没有找到这个变量就会报错。这个自由变量查找的过程就是作用域链。4、变量提升:每个var声明的变量function声明的函数存在变量提升。let const不存在变量提升只提升声明不提升赋值。javascript中声明并定义一个变量时会把声明提前以下会先打印出undefined再打印出10console.log(a)var a 10console.log(a)//undefinedletvarconst说一下ES6的新特性let const var的区别什么是块级作用域如何用ES6的方法实现块级作用域在 ES5 只有全局作用域和函数作用域没有块级作用域{}var 声明的变量是全局或者整个函数块的var 声明的变量存在变量提升let,const 声明的变量是块级的变量不存在变量提升。let 声明的变量允许重新赋值const 不允许。常用数组字符串方法Array.from(new Set(arr)) 数组去重Math.max(arr) 数组最大值arr.reverse() 反转数组arr.slice() 截取数组push() 在数组末尾添加一个或多个元素并返回新数组长度pop() 从数组末尾删除1个元素, 并返回被删除的元素shift() 在数组开始添加一个或多个元素并返回新数组长度unshift() 在数组开始删除一个元素(删且只删除1个),并返回 被删除的元素arr.toString() || arr.flat(Infinity)) 数组变一维arr.sort((a,b)a-b) 数组升序排列arr.sort((a,b)b-a) 数组降序排列arr.indexOf(el) 返回目标元素在数组中的下标找不到返回-1arr.splice(i, j, “k”) 在数组的第i位开始删除j位元素添加“k”arr.join( ) 数组内元素连接成字符串arr1.concat(arr2) 连接数组/字符串str.split(“”) 字符串分割为数组JSON.parse(JSON.stringfy(obj)) 拷贝对象// 数学parseInt(5.1234); // 将一个字符串转换为整数Math.floor(5.1234); // 向下取整 该数值的最大整数Math.ceil(5.1234); // 向上取整有小数整数部分就1Math.round(5.1234); // 四舍五入小数部分Math.max(…arr) // 求数组最大值Object.prototype.toString.call(A) // 判断类型for(item in arr){} 遍历keyfor(item of arr){} 遍历value.reduce(function(返回值acc, 当前值el, 当前索引index, 调用的数组arr){},返回值的初始值init)// /对数组中每个元素执行提供的函数将其结果汇总为单个返回值。.filter(function(当前值el, 当前索引index, 调用的数组arr){})//创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。.map(function(当前值el, 当前索引index, 调用的数组arr){})//创建一个新数组其结果是该数组中的每个元素都调用一个提供的函数后 返回 的结果。.forEach(function(当前值el, 当前索引index, 调用的数组arr){})// 会改变原数组依次执行提供的回调函数。for(let el in arr) // 遍历数组中的keyfor(let el of arr) // 遍历数组中的valueswitch(表达式) {case n:代码块break;case n:代码块break;default:默认代码块}map和forEach区别forEach(): 针对每一个元素执行提供的函数。map(): 创建一个新的数组其中每一个元素由调用数组中的每一个元素执行提供的函数得来js事件循环机制宏任务微任务async/await,读代码运行顺序1、Js 是单线程高耗时操作就带来了进程阻塞问题。所以Js 有两种任务的执行模式同步模式和异步模式。2、异步任务主要分为宏任务Task与微任务(Jobs)两种。3、宏任务由宿主浏览器、Node发起微任务由 JS 自身发起。4、宏任务和微任务都是队列先进先出宏任务有script、setTimeout、setInterval等微任务有Promise.then/ catch/finally、process.nextTick等。5、一个宏任务执行完判断是否有可执行的微任务有则执行完所有微任务否则执行下一个宏任务。6、当程序执行到await方法时会阻塞await方法后面的程序进入await方法内部并执行到return前然后跳出该async方法执行与该async方法并列的同步任务。async function test1() {console.log(‘1’);console.log(await test2());console.log(‘2’);}async function test2() {console.log(‘3’);return await ‘4’}test1();console.log(‘5’);setTimeout(() {console.log(‘6’);}, 0);new Promise((resolve, reject) {console.log(‘7’);resolve();}).then(() {console.log(‘8’);});console.log(‘9’);输出结果135798426原型、构造函数实例原型(prototype): 可以简单的理解成对象的爹。在 Firefox 和 Chrome 中每个 JavaScript 对象中都包含一个 __proto__ (非标准)的属性指向它爹(该对象的原型)可 obj.__proto__进行访问。构造函数: 可以通过 new 来新建一个对象的函数。实例: 通过构造函数和 new 创建出来的对象便是实例。 实例通过__proto__ 指向原型通过 constructor 指向构造函数介绍一下JavaScript的原型链js原型链的顶端是什么Object的原型是什么原型链是由原型对象组成每个对象都有 __proto__ 属性指向了创建该对象 的构造函数的原型__proto__ 将对象连接起来组成了原型链。是一个用来实现 继承和共享属性的有限的对象链。属性查找机制: 当查找对象的属性时如果实例对象自身不存在该属性则沿着 原型链往上一级查找找到时则输出不存在时则继续沿着原型链往上一级查 找直至最顶级的原型对象 Object.prototype如还是没找到则输出 undefined属性修改机制: 只会修改实例对象本身的属性如果不存在则进行添加该属性 如果需要修改原型的属性时则可以用: b.prototype.x 2但是这样会造成 所有继承于该对象的实例的属性发生改变。对象继承方法原型链function A () {};A.prototype.sayhi () {// …}function B () {};B.prototype new A();var b new B(); b.sayhi();构造函数通过call()或apply()来传递实例对象function A () {this.friends: [‘liu’, ‘chen’, ‘lin’]}function B () {A.call(this);}var b1 new B();var b2 new B();b1.friends.push(‘zhang’);b2.friends; // “liu”, “chen”, “lin”ES6 class类的继承class A {};class B extends A {};讲讲继承多态同一操作作用于不同的对象上可以产生不同的解释和不同的执行结果。class Person{// 定义一个Person类属性有姓名年龄。方法有介绍自己constructor(name,age){this.name name;this.age age;}introduce function(){return(My name is this.name. I am this.age years old.)}}class Student extends Person{// 定义一个Student类继承Person类属性有姓名年龄班级。方法有介绍自己constructor(name,age,klass){super(name,age);this.klass klass;}introduce function(){return(My name is this.name. I am this.age years old. I am a Student. I am at Class this.klass.)}}new做了什么操作1创建一个空对象。var obj new Object()2将空对象的原型赋值给构造函数的原型。Person.prototype obj.proto3执行构造函数的代码为空对象添加属性Person.call(obj),也可以理解为将构造函数内部的this指针指向新建的空对象。4返回添加后的对象箭头函数的特性箭头函数与普通函数的区别在于1、箭头函数没有 this所以需要通过查找作用域链来确定 this 的值这就意味着如果箭头函数被非箭头函数包含this 绑定的就是最近一层非箭头函数的 this2、不能通过 new 关键字调用同样也没有 new.target 值和原型谈谈对this的理解this 总是指向函数的直接调用者而非间接调用者如果有 new 关键字this 指向 new 出来的那个对象全局环境中this 默认绑定到 window。bind,call,apply的区别手撕源码当我们使用一个函数需要改变this指向的时候才会用到call,apply,bind立即执行传递的参数不多则可以使用fn.call(thisObj, arg1, arg2 …)立即执行传递的参数很多则可以将参数放在数组里使用fn.apply(thisObj, [arg1, arg2 …])生成一个新的函数长期绑定某个函数给某个对象使用则可以使用bind(thisObj, arg1, arg2 …)// 全局添加一个_call方法Function.prototype._Call function(obj) {// 参数是否存在如果存在则转为 Object 类型否则直接取 window 对象为默认对象let _obj obj? Object(obj) : window_obj.fn this;// 保存参数的数组var argArr []// 遍历参数因为首项是 obj所以要从次项开始遍历才是参数for (let i 1; i arguments.length; i) {argArr.push(‘arguments[’ i ‘]’);}// 或者用一下两种方法得到 argArr// 1. let argArr […arguments].slice(1)// 2. let argArr Array.from(arguments).slice(1)// 执行 _context 的 fn 方法把 argArr 拆分_obj.fn(…argArr); // eval(“_context.fn(” argArr “)”);// 移除 fn 方法delete _context.fn;}Function.prototype._apply function(obj, argArr) {// 如果obj不存在则默认window对象var _obj obj ? obj : window// 给_obj添加fn方法_obj.fn this// 获取第二个数组参数var arg []// 当这个参数数组不存在或者为空时直接执行函数否则把数组拆分后传递给函数并执行if (!argArr || argArr.length 0) {_obj.fn()} else {for (var i 0; i argArr.length; i) {arg.push(‘argArr[’ i ‘]’)}// 执行obj的fn方法把arg拆分eval(“_obj.fn(” arg “)”)}// 移除这个方法delete _obj.fn}Function.prototype._bind function(obj) {// 判断调用_bind方法的是否为函数if (typeof(this) ! “function”) {throw Error(“调用_bind方法的必须为函数”)}// 截取传给函数的参数var args Array.prototype.slice.call(arguments, 1)// 保存这个函数以便后续使用var _fn this// 创建一个待会儿返回出去的函数这个函数会赋到外部变量中var bindFn function() {// 获取_bind方法返回的函数的参数var newArgs Array.prototype.slice.call(arguments)// 通过apply去改变this指向,实现函数柯里化var _obj this.constructor _fn ? this : obj_fn.apply(_obj, newArgs.concat(args))}// 创建一个中介函数以便实现原型继承var ProtoFn function(){}ProtoFn.prototype _fn.prototypebindFn.prototype new ProtoFn()// 返回bindFn的函数给外部return bindFn}this指向默认绑定全局环境中this 默认绑定到 window。隐式绑定一般地被直接对象所包含的函数调用时也称为方法调用this 隐式绑定到该直接对象。隐式丢失隐式丢失是指被隐式绑定的函数丢失绑定对象从而默认绑定到 window。显式绑定通过 call()、apply()、bind()方法把对象绑定到 this 上 叫做显式绑定。 new 绑定如果函数或者方法调用之前带有关键字 new它就构成构造函数调用。 对于 this 绑定来说称为 new 绑定。【1】构造函数通常不使用 return 关键字它们通常初始化新对象当构造函数 的函数体执行完毕时它会显式返回。在这种情况下构造函数调用表达式的计 算结果就是这个新对象的值。【2】如果构造函数使用 return 语句但没有指定返回值或者返回一个原始值 那么这时将忽略返回值同时使用这个新对象作为调用结果。【3】如果构造函数显式地使用 return 语句返回一个对象那么调用表达式的值 就是这个对象。设计模式应用场景手撕源码设计模式总共有 23 种总体来说可以分为三大类创建型模式 Creational Patterns 、结构型模式 Structural Patterns 和行为型模式 Behavioral Patterns 。什么是观察者模式观察者模式是定义对象间的一种一对多依赖关系使得每当一个对象状态发生改变时其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅Publish/Subscribe模式、模型-视图Model/View模式、源-监听器Source/Listener模式或从属者Dependents模式。优点观察者模式可以实现表示层和数据逻辑层的分离并定义了稳定的消息更新传递机制抽象了更新接口使得可以有各种各样不同的表示层作为具体观察者角色观察者模式在观察目标和观察者之间建立一个抽象的耦合观察者模式支持广播通信观察者模式符合开闭原则对拓展开放对修改关闭的要求。缺点如果一个观察目标对象有很多直接和间接的观察者的话将所有的观察者都通知到会花费很多时间如果在观察者和观察目标之间有循环依赖的话观察目标会触发它们之间进行循环调用可能导致系统崩溃观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的而仅仅只是知道观察目标发生了变化。在观察者模式中有如下角色Subject抽象主题抽象被观察者抽象主题角色把所有观察者对象保存在一个集合里每个主题都可以有任意数量的观察者抽象主题提供一个接口可以增加和删除观察者对象ConcreteSubject具体主题具体被观察者该角色将有关状态存入具体观察者对象在具体主题的内部状态发生改变时给所有注册过的观察者发送通知Observer抽象观察者是观察者者的抽象类它定义了一个更新接口使得在得到主题更改通知时更新自己ConcrereObserver具体观察者实现抽象观察者定义的更新接口以便在得到主题更改通知时更新自身的状态。什么是单例模式答单例模式是一种常用的软件设计模式在应用这个模式时单例对象的类必须保证只有一个实例存在整个系统只能使用一个对象实例。优点不会频繁地创建和销毁对象浪费系统资源。使用场景IO 、数据库连接、Redis 连接等。什么是简单工厂模式答简单工厂模式又叫静态工厂方法模式就是建立一个工厂类对实现了同一接口的一些类进行实例的创建。比如一台咖啡机就可以理解为一个工厂模式你只需要按下想喝的咖啡品类的按钮摩卡或拿铁它就会给你生产一杯相应的咖啡你不需要管它内部的具体实现只要告诉它你的需求即可。优点工厂类含有必要的判断逻辑可以决定在什么时候创建哪一个产品类的实例客户端可以免除直接创建产品对象的责任而仅仅“消费”产品简单工厂模式通过这种做法实现了对责任的分割它提供了专门的工厂类用于创建对象客户端无须知道所创建的具体产品类的类名只需要知道具体产品类所对应的参数即可对于一些复杂的类名通过简单工厂模式可以减少使用者的记忆量通过引入配置文件可以在不修改任何客户端代码的情况下更换和增加新的具体产品类在一定程度上提高了系统的灵活性。缺点不易拓展一旦添加新的产品类型就不得不修改工厂的创建逻辑产品类型较多时工厂的创建逻辑可能过于复杂一旦出错可能造成所有产品的创建失败不利于系统的维护。get和postPut(增)Delete(删)Post(改)Get(查)get 和 post 在缓存方面的区别get 请求类似于查找的过程用户获取数据可以不用每次都与数据库连接所以可以使用缓存。post 不同post 做的一般是修改和删除的工作所以必须与数据库交互所以 不能使用缓存。因此 get 请求适合于请求缓存。为什么javascript是单线程与异步有冲突吗JS的单线程是指一个浏览器进程中只有一个JS的执行线程同一时刻内只会有一段代码在执行例如打开的多个页面使用的都是同一个JS执行线程如果其中一个页面在执行一个运算量较大的function时其他窗口的JS就会停止工作。异步机制是浏览器的两个或以上常驻线程共同完成的。例如异步请求是由两个常驻线程JS执行线程和事件触发线程共同完成的JS的执行线程发起异步请求这时浏览器会开一条新的HTTP请求线程来执行请求这时JS的任务已完成继续执行线程队列中剩下的其他任务然后在未来的某一时刻事件触发线程监视到之前的发起的HTTP请求已完成它就会把完成事件插入到JS执行队列的尾部等待JS处理。例如定时触发settimeout和setinterval是由浏览器的定时器线程执行的定时计数然后在定时时间把定时处理函数的执行请求插入到JS执行队列的尾端所以用这两个函数的时候实际的执行时间是大于或等于指定时间的不保证能准确定时的。所谓的JS的单线程和异步更多的应该是属于浏览器的行为他们之间没有冲突更不是同一种事物没有什么区别不区别的。同步和异步的区别同步一般指的是在代码运行的过程中从上到下逐步运行代码每一部分代码运行完成之后下面的代码才能开始运行。异步指的是当我们需要一些代码在执行的时候不会影响其他代码的执行也就是在执行代码的同时可以进行其他的代码的执行不用等待代码执行完成之后才执行之后的代码就像我们人一样可以一边看电视剧一边吃东西一样互不干扰这种方式就是异步。说一下promise解决了什么问题。他的底层逻辑如何实现没有promise该怎么办promises是异步编程的一种解决方法从语法上讲promise是一个对象他可以获取异步操作的消息本意讲他是承诺承诺他过一段时间会给你一个结果。解决了什么问题解决可读性的问题解决信任问题promise 只有成功和失败 2 个状态让一个函数无论成功还是失败都能被调用。原理Promise.all()方法用于将多个 Promise 实例包装成一个新的 Promise 实例。该方法提供了并行执行异步操作的能力并且在所有异步操作执行完并且执行结果都是成功的时候才执行回调。没有promise用async实际开发中我觉得async更好用。延时和异步同步和异步的区别?同步一般指的是在代码运行的过程中从上到下逐步运行代码每一部分代码运行完成之后下面的代码才能开始运行。eg浏览器访问服务器用户看到页面刷新重新发请求等请求完页面刷新新内容出现用户看到新内容之后进行下一步操作。异步浏览器访问服务器请求用户正常操作浏览器在后端进行请求。等请求完页面不刷新新内容也会出现用户看到新内容。JS 的延迟加载有助与提高页面的加载速度。defer 和 async、动态创建 DOM 方式用得最多、按需异步载入 JSdefer延迟脚本。立即下载但延迟执行延迟到整个页面都解析完毕后再运行按照脚本出现的先后顺序执行。async异步脚本。下载完立即执行但不保证按照脚本出现的先后顺序执行。如何解决异步回调地狱promise、generator、async/await回调函数的定义:函数A作为参数(函数引用)传递到另一个函数B中并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式)就叫做匿名回调函数。回调地狱嵌套的回调函数defer和async的区别defer属性和async属性都只适用于外部脚本文件表示立即下载延迟执行。defer与async的区别是defer要等到整个页面正常渲染结束才会执行async一旦下载完渲染引擎就会中断渲染执行这个脚本以后再继续渲染。一句话defer是“渲染完再执行”async是“下载完就执行”。如果有多个defer脚本会按照它们在页面出现的顺序加载而多个async脚本是不能保证加载顺序的。async/await具体该怎么用async function testResult() {let result await after2seconds(30);console.log(result);}promise和async/await的关系PromisePromise 是异步编程的一种解决方案比传统的解决方案——回调函数和事件——更合理和更强大简单地说Promise好比容器里面存放着一些未来才会执行完毕异步的事件的结果而这些结果一旦生成是无法改变的async awaitasync await也是异步编程的一种解决方案他遵循的是Generator 函数的语法糖他拥有内置执行器不需要额外的调用直接会自动执行并输出结果它返回的是一个Promise对象。两者的区别:Promise的出现解决了传统callback函数导致的“地狱回调”问题但它的语法导致了它向纵向发展行成了一个回调链遇到复杂的业务场景这样的语法显然也是不美观的。而async await代码看起来会简洁些使得异步代码看起来像同步代码await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖只有这一句代码执行完才会执行下一句。async await与Promise一样是非阻塞的异步。async await是基于Promise实现的可以说是改良版的Promise它不能用于普通的回调函数。简单来看这两者除了语法糖不一样外他们解决的问题、达到的效果是大同小异的我们可以在不同的应用场景根据自己的喜好来选择使用。promisepromise.all,promise.race源码手撕让你写一个请求5秒内执行完就返回执行结果否则返回超时// 要7秒才能执行完function ajax1() {return new Promise((resolve, reject) {setTimeout(() {resolve(‘7秒后我才完成’)}, 7000)})}// 5秒后抛出一个错误function timeout() {return new Promise((resolve, reject) {setTimeout(() reject(new Error(‘超过5秒了’)), 5000)})}Promise.race([ajax1(),timeout()]).then(res {console.log(res)})ajax和axiosfetch的区别是什么ajax 是使用js中XMLHttpRequest对象发起异步请求axios 是使用XMLHttpRequest基于Promise 的实现版本Fetch是基于promise设计的。一定记住fetch不是ajax的进一步封装而是原生js没有使用XMLHttpRequest对象。requestJS的核心原理是什么如何动态加载的如何避免多次重复加载如何缓存原理requireJS核心原理是通过动态创建 script 脚本来异步引入模块然后对每个脚本的 load 事件进行监听如果每个脚本都加载完成了再调用回调函数。通过正则匹配模块以及模块的依赖关系保证文件加载的先后顺序。通过指定script的src属性来异步加载模块的。然后对每个脚本的 load 事件进行监听如果每个脚本都加载完成了再调用回调函数。根据文件的路径对加载过的文件做了缓存。垃圾回收必要性JavaScript 引擎每次创建字符串、数组或对象时解释器都会动态地分配了内存为了避免消耗完系统中所有可用的内存造成系统崩溃。所以要释放这些内存以便他们能够被再用。JavaScript 的解释器可以检测到何时程序 不再使用一个对象了当他确定了一个对象是无用的时候他就知道不再需要这 个对象可以把它所占用的内存释放掉了。垃圾回收的方法1标记清除最常见的垃圾回收方式当变量进入环境时就标记这个变量为”进入环境 “,从逻辑上讲永远不能释放进入环境的变量所占的内存永远不能释放进入环境变量所占用的内存只要执行流程进入相应的环境就可能用到他们。当离开环境时就标记为离开环境。 垃圾回收器在运行的时候会给存储在内存中的变量都加上标记所有都加然后去掉环境变量中的变量以及被环境变量中的变量所引用的变量条件性去除 标记删除所有被标记的变量删除的变量无法在环境变量中被访问所以会被删除最后垃圾回收器完成了内存的清除工作并回收他们所占用的内存。2计数引用。不太常见引用计数法的意思就是标记每个值引用的次数当声明了一个变量并用一个引用类型的值赋值给改变量则这个值的引用次数为 1,相反的如果包含了对这个值引用的变量又取得了另外一个值 则原先的引用值引用次数就减 1当这个值的引用次数为 0 的时候说明没有办 法再访问这个值了因此就把所占的内存给回收进来这样垃圾收集器再次运行 的时候就会释放引用次数为 0 的这些值。用引用计数法会存在内存泄露objA 和 objB 通过各自的属性相互引用这样的话两个对象 的引用次数都为 2在采用引用计数的策略中由于函数执行之后这两个对象 都离开了作用域函数执行完成之后因为计数不为 0这样的相互引用由于不会触发垃圾回收的过程如果大量存在就会导致内存泄露。基本数据类型五种基本数据类型: Undefined、Null、Boolean、Number和String。一种复杂数据类型Object三大引用类型存储在堆内存中: Object、Array和Function类型判断首先会想到typeof。单单用 typeof 并无法完全满足这其实并不是 bug本质原因是 JS 的万物皆对象的理论。因此要真正完美判断时我们需要区分对待:基本类型(包括null)直接使用 typeof 即可。引用类型的类型判断1可以使用原型链使用instanceof但是不能识别出基本数据类型。2Object.prototype.toString.call(obj)可以相对较全的判断js的数据类型。原理Object原型上的toString方法作用在传入的obj的上下文中。为什么要用Object的toString方法其实各数据类型使用toString()后的结果表现不一的原因在于所有类在继承Object的时候改写了toString()方法。 Object原型上的方法是可以输出数据类型的。因此我们想判断数据类型时也只能使用原始方法。在项目中使用哪个判断还是要看使用场景具体的选择一般基本的类型可以选择typeof引用类型可以使用instanceof。 和的区别比较类型和值只比较值。1隐式转换var a?;console.log(a 1a 2a 3);//返回true答案一var a {i:1,valueOf:function(){return a.i;}}解释如果原始类型和对象比较对象会转为原始类型的值在进行比较。对象转换为原始类型的值先调用对象的 valueOf 方法如果返回的还是对象再接着调用 toString 方法为什么[]![]的优先级要大于的所以先运算右边![]----结果为false所以实际上比较的是 [] false数组与布尔值进行比较两个运算子都会先转成数值然后再进行比较。Number([])为0Number(false)为0过程[]![] ---- []false ----- 00 —//truejs动画和css动画区别 为什么css动画比JavaScript高效浏览器的渲染流程渲染流程主要有4个步骤解析 HTML 生成DOM 树解析 CSS 样式生成 CSSOM 树CSSOM 树与 DOM 树结合生成 Render tree布局 Render Tree 对每个节点进行布局处理确定在屏幕上的位置重排/回流绘制 Render Tree遍历渲染树将每个节点绘制出来重绘CSS3 动画也被称为补间动画原因是只需要添加关键帧的位置其他的未定义的帧会被自动生成。JS 动画是逐帧动画在时间帧上绘制内容一帧一帧的所以他的可再造性很高几乎可以完成任何你想要的动画形式。但是由于逐帧动画的内容不一样会增加制作的负担占用比较大的资源空间。如果我们采用 JS 来实现动画每一帧画面的改变都会导致回流重排而 CSS 的动画是运行在合成线程中的不会阻塞主线程并且在合成线程中完成的动作不会触发回流和重绘。JS 动画运行在 CPU而 CSS 动画运行在 GPUdom0级事件dom2级事件DOM0级事件绑定curEle.οnclickfunction(){};DOM2级事件绑定只有2级DOM包含3个事件事件捕获阶段、处于目标阶段和事件冒泡阶段标准浏览器curEle.addEventListener(‘click’,function(){},false)IE6-8:curEle.attachEvent(‘onclick’,function(){})模块化ES5:require:对于基本数据类型属于复制(即会被模块缓存),对于复杂数据类型属于浅拷贝.ES6:import只读引用// 导入import “/app”;import React from “react”;import { Component } from “react”;// 导出export function multiply() {…};export var year 2018;export default …防抖节流防抖与节流函数是一种最常用的 高频触发优化方式能对性能有较大的帮助。防抖 (debounce): 将多次高频操作优化为只在最后一次执行通常使用的场景是用户输入只需再输入完成后做一次输入校验即可。节流(throttle): 每隔一段时间后执行一次也就是降低频率将高频操作优化成低频操作通常使用场景: 滚动条事件通常每隔 100~500 ms 执行一次即可。深浅拷贝浅拷贝以赋值的形式拷贝引用对象仍指向同一个地址此时修改新对象时原对象也会改变。深拷贝: 完全拷贝一个新对象修改时原对象不再受到任何影响1JSON.parse(JSON.stringify(obj)): 性能最快 具有循环引用的对象时缺点当被拷贝的对象含有函数、undefined、或 symbol 时无法拷贝 。2递归进行逐一赋值。function deepClone(obj{}){if(typrof obj !“object” || obj null){retuen obj;}let resultif(obj instanceof Array){result [];}else{result {};}for(let key in obj){if(obj.hasOwnProperty(key)){result[key]deepClone(obj[key])}}return result;}什么是事件监听说说前端中的事件流在HTML 中与 javascript 交互是通过事件驱动来实现的例如鼠标点击事件 onclick、页面的滚动事件 onscroll 等等可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的就需要了解一下“事件流”的概念。什么是事件流事件流描述的是从页面中接收事件的顺序,DOM2 级事件流包括下面几个阶段。事件捕获阶段事件对象从Window对象开始沿传播路径向下依次经过各元素传播至目标元素的父元素处于目标阶段事件对象到达目标元素事件冒泡阶段事件对象从目标元素的父元素开始沿传播路径向上依次经过各元素传播至Window对象。事件捕获先由最上一级的节点先接收事件然后向下传播到具体的节点。当用户点击了元素采用事件捕获则click事件将按照document———的顺序进行传播。事件冒泡是由IE开发团队提出来的即事件开始时由最具体的元素文档中嵌套层次最深的那个节点接收然后逐级向上传播addEventListeneraddEventListener 是 DOM事件新增的指定事件处理程 序的操作这个方法接收 3 个参数要处理的事件名、作为事件处理程序的函数 和一个布尔值。最后这个布尔值参数如果是 true表示在捕获阶段调用事件处理程序如果是 false表示在冒泡阶段调用事件处理程序。IE 只支持事件冒泡。如何阻止事件冒泡方法一使用stopPropagation()方法使用event对象调用即可。代码event.stopPropagation();如何阻止默认事件可以使用preventDefault()方法直接使用event对象调用即可。代码event.preventDefault()事件委托事件委托是利用事件的冒泡原理来实现的就是事件从最深的节点开始然后逐步向上传播事件。不在事件的发生地上设置监听函数而是 在其父元素上设置监听函数通过事件冒泡父元素可以监听到子元素上事件的 触发通过判断事件发生元素 DOM 的类型来做出不同的响应。举例todoList就是 ul 和 li 标签的事件监听比如我们在添加事件时候采用 事件委托机制不会在 li 标签上直接添加而是在 ul 父元素上添加。好处比较合适动态元素的绑定新添加的子元素也会有监听函数也可以有事件触发机制.浏览器渲染过程解析器根据词语构建节点node形成DOM树。构建CSS规则树CSS和DOM树生成Render树生成布局Generating the Layout绘制Painting回流位置与重绘颜色generatorgenerator生成器是ES6标准引入的新的数据类型。一个generator看上去像一个函数但可以返回多次。定义generator由function*定义注意多出的*号并且除了return语句还可以用yield返回多次。用AJAX时可以这么写try {r1 yield ajax(‘http://url-1’, data1);r2 yield ajax(‘http://url-2’, data2);r3 yield ajax(‘http://url-3’, data3);success(r3);}catch (err) {handle(err);}如何判断数组1原型链Array.prototype.isPrototypeOf(obj); // 判定Array是不是在obj的原型链中如果是则返回true,否则false。2构造函数:obj instanceof Array3改变this跨原型链调用toString()Object.prototype.toString.call(obj)4ES5新增的方法Array.isArray(arr1)在数组原型链上实现删除数组重复数据的方法。定义Array.prototype.remove function(val) {var index this.indexOf(val);if (index -1) {this.splice(index, 1);}};使用arr.remove(arr2)数组去重有哪些方法法一indexOf 循环去重法二ES6 Set 去重Array.from(new Set(array))数组展平arr.join(‘,’).split(‘,’);1最简单的思路循环中判断如果子元素是数组则递归。function flatten(origin) {var result [];for(var i 0; i origin.length; i) {var item origin[i];if(Array.isArray(item)) {result result.concat(flatten(item))} else {result.push(item);}}return result;}var arr [“a”, “b”, [“c”, “d”], [[“d”],“e”], “f”];flatten(arr); // [“a”, “b”, “c”, “d”, “d”, “e”, “f”]2toString()数组的原型对象上有一个方法toString, 它能把数组的所以元素转化成用逗号隔开的字符串。origin.toString().split(‘,’); // [“1”, “2”, “3”, “4”, “a”, “b”, “c”, “d”, “d”, “e”, “f”]由于 toString 转化为字符串的时候不会区分字符串和数字类型在进行区分数据类型的时候要注意。3split上面的方法我们用 toString() 将数组转化为字符串那么我们也可以用 split 来做arr.join(‘,’).split(‘,’);同样这种字符串和数组互转的过程不适合多种数据类型同时处理。4reduce我们注意到其实数组扁平化其实就是“迭代 拼接累加 递归”的过程数组 reduce 方法既可以迭代又可以累加适合做数组扁平化。function flatten(origin){return origin.reduce(function(init, item){return init.concat(Array.isArray(item) ? flatten(item) : item)}, [])}var arr [1, [2, 3, [4]], “a”, “b”, [“c”, “d”], [[“d”],“e”], “f”];console.log(flatten(arr)) // [1, 2, 3, 4, “a”, “b”, “c”, “d”, “d”, “e”, “f”]5ES6 扩展运算符…可以将两重数组转换为单层数组:[].concat(…[1, [2, 3, [4]], “a”, “b”, [“c”, “d”], [[“d”],“e”], “f”]);typeof 和instance oftypeof:1.返回值是一个字符串 用来说明变量的数据类型。2.typeof 一般只能返回如下几个结果 number, boolean, string, function, object, undefined。instanceof:1.返回值为布尔值;2. instanceof 用于判断一个变量是否属于某个对象的实例。为什么0.10.20.3计算机是二进制来表示浮点数的无法准确表示一个浮点数只能逼近。1用symbol.iterator实现对象遍历清晰的记得是b站的问题难搞哦Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for…of 循环使用。1URL和URI有什么区别URI 是统一资源标识符相当于一个人身份证号码Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是一个来 URI 来定位的 URI一般由三部组成①访问资源的命名机制②存放资源的主机名③资源自身的名称由路径表示着重强调于资源。URL是统一资源定位符相当于一个人的家庭住址URL 是 Internet 上用来描述信息资源的字符串主要用在各种 WWW 客户程序和 服务器程序上特别是著名的 Mosaic。采用 URL 可以用一种统一的格式来描述 各种信息资源包括文件、服务器的地址和目录等。URL 一般由三部组成①协议(或称为服务方式)②存有该资源的主机 IP 地址(有时也包括端口号)③主机资源的具体地址。如目录和文件名等。4webpack篇怎么打包 webpack是用来干什么的 除了webpack用过其他打包工具吗webpack是一个模块打包工具他要做的事是分析你的项目找到js模块以及其他一些浏览器不能直接运行的拓展语言并将其转换和打包为合适的格式给浏览器使用。尤玉溪在知乎上推荐过vite但是我没有用过。webpack热更新原理一、是什么HMR全称 Hot Module Replacement可以理解为模块热替换指在应用程序运行过程中替换、添加、删除模块而无需重新刷新整个应用例如我们在应用运行过程中修改了某个模块通过自动刷新会导致整个应用的整体刷新那页面中的状态信息都会丢失。如果使用的是 HMR就可以实现只将修改的模块实时替换至应用中不必完全刷新整个应用在webpack中配置开启热模块也非常的简单如下代码const webpack require(‘webpack’)module.exports {// …devServer: {// 开启 HMR 特性hot: true// hotOnly: true}}通过上述这种配置如果我们修改并保存css文件确实能够以不刷新的形式更新到页面中但是当我们修改并保存js文件之后页面依旧自动刷新了这里并没有触发热模块所以HMR并不像 Webpack 的其他特性一样可以开箱即用需要有一些额外的操作我们需要去指定哪些模块发生更新时进行HRM如下代码if(module.hot){module.hot.accept(‘./util.js’,(){console.log(“util.js更新了”)})}二、实现原理Webpack Compile将 JS 源代码编译成 bundle.js构建输出的文件HMR Server用来将热更新的文件输出给 HMR Runtimesocket服务器会被注入到浏览器更新文件的变化Bundle Server静态资源文件服务器提供文件访问路径在HMR Runtime 和 HMR Server之间建立 websocket用于实时更新文件变化当某一个文件或者模块发生变化时webpack监听到文件变化对文件重新编译打包编译生成唯一的hash值这个hash值用来作为下一次热更新的标识根据变化的内容生成两个补丁文件manifest包含了 hash 和 chundId用来说明变化的内容和chunk.js 模块由于socket服务器在HMR Runtime 和 HMR Server之间建立 websocket链接当文件发生改动的时候服务端会向浏览器推送一条消息消息包含文件改动后生成的hash值作为下一次热更新的标识在浏览器接受到这条消息之前浏览器已经在上一次socket 消息中已经记住了此时的hash 标识这时候我们会创建一个 ajax 去服务端请求获取到变化内容的 manifest 文件mainfest文件包含重新build生成的hash值以及变化的模块对应上图的c属性浏览器根据 manifest 文件获取模块变化的内容从而触发render流程实现局部模块更新三、总结关于webpack热模块更新的总结如下通过webpack-dev-server创建两个服务器提供静态资源的服务express和Socket服务express server 负责直接提供静态资源的服务打包后的资源直接被浏览器请求和解析socket server 是一个 websocket 的长连接双方可以通信当 socket server 监听到对应的模块发生变化时会生成两个文件.jsonmanifest文件和.js文件update chunk通过长连接socket server 可以直接将这两个文件主动发送给客户端浏览器浏览器拿到两个新的文件后通过HMR runtime机制加载这两个文件并且针对修改的模块进行更新loader和plugin【Loader】用于对模块源码的转换loader描述了webpack如何处理非javascript模块并且在buld中引入这些依赖。loader可以将文件从不同的语言如TypeScript转换为JavaScript或者将内联图像转换为data URL。比如说CSS-LoaderStyle-Loader等。loader的使用很简单在webpack.config.js中指定loader。module.rules可以指定多个loader对项目中的各个loader有个全局概览。loader是运行在NodeJS中可以用options对象进行配置。plugin可以为loader带来更多特性。loader可以进行压缩打包语言翻译等等。loader从模板路径解析npm install node_modules。也可以自定义loader命名XXX-loader。语言类的处理器loaderCoffeeScriptTypeScriptESNextBable,Sass,Less,Stylus。任何开发技术栈都可以使用webpack。【Plugin】目的在于解决loader无法实现的其他事从打包优化和压缩到重新定义环境变量功能强大到可以用来处理各种各样的任务。plugins在webpack运行的生命周期中会广播出许多事件plugin可以监听这些事件在合适的时机通过webpack提供的API改变输出结果。webpack提供了很多开箱即用的插件CommonChunkPlugin主要用于提取第三方库和公共模块避免首屏加载的bundle文件或者按需加载的bundle文件体积过大导致加载时间过长是一把优化的利器。而在多页面应用中更是能够为每个页面间的应用程序共享代码创建bundle。webpack功能强大难点在于它的配置文件webpack4默认不需要配置文件可以通过mode选项为webpack指定了一些默认的配置mode分为development/production默认是production。插件可以携带参数所以在plugins属性传入new实例。5vuejs篇双向绑定原理手撕简单源码vue3新特性proxy和defineProperty的区别mvvm和mvc差异和项目开发一个道理小公司接小项目boss从客户那接了单给程序员做程序员做了给客户看客户看了不满意找领导领导找程序员这么个循环就是mvc公司大了项目大了领导不管了那就是客户需求和产品经理说产品经理和程序员对接程序员做完给产品经理看产品再去把东西给客户这就是mvvm父子通信非父子通信生命周期key的作用v-if和vue-router原理路由如何跳转vuex数据流向mutation和action6react及react native篇Vue和React的区别他们的设计思路的不同react组件是函数式的思想。组件的状态和逻辑通过参数传入尤其在hook中体现的非常明显。vue的思想是响应式的也就是基于是数据可变的通过对每一个属性建立Watcher来监听当属性变化的时候响应式的更新对应的虚拟dom。react单向数据流vue双向绑定。react 路由模式我们平时会使用的主要是两种路由模式HashRouter这种模式基于浏览器location的hash片段来实现实现比较简单不需要服务器的支持缺点是url样式不够优雅而且hash参数容易丢失。BrowserRouter这种模式基于浏览器的history API可以让我们创建一个像 http://example.com/home/files 这样真实的URL而且切换url不会引起页面的刷新用户体验比较好是我们比较推荐的路由方式不过这种模式需要服务器比如Nginx的支持因为路径 /home/files 只是一个前端定义的路由当用户刷新页面的时候浏览器会去向服务器请求这个资源服务器因为没有对应的这个资源就会返回404导致页面无法显示所以需要Nginx将所有404的请求返回入口文件 /index.htmlreact单向数据流的好处 ?数据流动方向可以跟踪流动单一追查问题的时候可以跟快捷。缺点就是写起来不太方便。要使UI发生变更就必须创建各种action来维护对应的state。react和vue的区别1react整体是函数式的思想把组件设计成纯组件状态和逻辑通过参数传入所以在react中是单向数据流推崇结合immutable来实现数据不可变。react在setState之后会重新走渲染的流程。vue的思想是响应式的也就是基于是数据可变的通过对每一个属性建立Watcher来监听当属性变化的时候响应式的更新对应的虚拟dom2react的性能优化需要手动去做而vue的性能优化是自动的但是vue的响应式机制也有问题就是当state特别多的时候Watcher也会很多会导致卡顿所以大型应用状态特别多的一般用react更加可控3react的思路是all in js通过js来生成html所以设计了jsx还有通过js来操作css社区的styled-component、jss等。vue是把htmlcssjs组合到一起用各自的处理方式vue有单文件组件可以把html、css、js写到一个文件中html提供了模板引擎来处理。说一下什么是虚拟DOM?为什么要使用虚拟DOM虚拟DOM是怎么工作的为什么操作 DOM 慢?虚拟DOM可以看作是一个使用javascript模拟了DOM结构的树形结构然后用这个树构建一个真正的DOM 树插到文档当中。当状态变更的时候重新构造一棵新的对象树。然后用 新的树和旧的树进行比较记录两棵树差异 把所记录的差异应用到所构建的真 正的 DOM 树上视图就更新了。Virtual DOM 本质上就是在 JS 和 DOM 之间做 了一个缓存。当状态改变时重新构建新的DOM树。为什么要使用虚拟DOM浏览器里一遍又一遍的渲染DOM是非常非常消耗性能的常常会出现页面卡死的情况所以尽量减少对DOM的操作成为了优化前端性能的必要手段。虚拟DOM是怎么工作的vdom就是将DOM的对比放在了js层通过对比不同之处来选择新渲染DOM节点从而提高渲染效率。为什么操作 DOM 慢?DOM 本身是一个 js 对象, 操作这个对象本身不慢, 但是操作后触发了浏览器的行为, 如 repaint 和 reflow 等浏览器行为, 使其变慢。diff算法diff算法的作用:计算出Virtual DOM中真正变化的部分并只针对该部分进行原生DOM操作而非重新渲染整个页面。传统diff算法:通过循环递归对节点进行依次对比算法复杂度达到 O(n^3) n是树的节点数这个有多可怕呢——如果要展示1000个节点得执行上亿次比较。。即便是CPU快能执行30亿条命令也很难在一秒内计算出差异。React的diff算法1什么是调和将Virtual DOM树转换成actual DOM树的最少操作的过程 称为 调和 。2什么是React diff算法diff算法是调和的具体实现。diff策略React用 三大策略 将O(n^3)复杂度 转化为 O(n)复杂度。策略一tree diffWeb UI中DOM节点跨层级的移动操作特别少可以忽略不计。策略二component diff拥有相同类的两个组件 生成相似的树形结构拥有不同类的两个组件 生成不同的树形结构。策略三element diff对于同一层级的一组子节点通过唯一id区分。setstate同步还是异步具体过程执行过程代码是同步的只是合成事件和钩子函数的调用顺序在更新之前导致在合成事件和钩子函数中没法立马拿到更新后的值形成了所谓的“异步”所以表现出来有时是同步有时是“异步”。一句话来说就是“只在合成事件和钩子函数中是“异步”的在原生事件和 setTimeout/setInterval等原生 API 中都是同步的”那为什么会出现异步的情况呢为了做性能优化将 state 的更新延缓到最后批量合并再去渲染对于应用的性能优化是有极大好处的如果每次的状态改变都去重新渲染真实 dom那么它将带来巨大的性能消耗。那如何在表现出异步的函数里可以准确拿到更新后的 state 呢通过第二个参数 setState(partialState, callback) 中的 callback 拿到更新后的结果。或者可以通过给 setState 传递函数来表现出同步的情况this.setState((state) {return { val: newVal }})那表现出异步的原理是怎么样的呢源码可参考React-setState原理这里还是用最简单的语言理解在 React 的 setState 函数实现中会根据 isBatchingUpdates(默认是 false) 变量判断是否直接更新 this.state 还是放到队列中稍后更新。然后有一个 batchedUpdate 函数可以修改 isBatchingUpdates 为 true当 React 调用事件处理函数之前或者生命周期函数之前就会调用 batchedUpdate 函数这样的话setState 就不会同步更新 this.state而是放到更新队列里面后续更新。这样就可以理解为什么原生事件和 setTimeout/setinterval 里面调用 this.state 会同步更新了吧因为通过这些函数调用的 React 没办法去调用 batchedUpdate 函数将 isBatchingUpdates 设置为 true那么这个时候 setState 的时候默认就是 false那么就会同步更新。redux原理在React中数据在组件中是单向流动的数据从一个方向父组件流向子组件通过props,所以两个非父子组件之间通信就相对麻烦redux的出现就是为了解决state里面的数据问题。Redux是将整个应用状态存储到一个地方上称为store,里面保存着一个状态树store tree,组件可以派发(dispatch)行为(action)给store,而不是直接通知其他组件组件内部通过订阅store中的状态state来刷新自己的视图。我们首先要创建一个状态类来管理我们的全局状态而且当这些状态发生变化的时候可以引起界面的刷新比如我们可以把当前登录的用户信息放到全局状态中其他组件可以直接引用。如果想要实现全局状态的管理我们可以借助于React提供的 Context 或者社区的 Redux MobX 也是一个非常流行的状态管理库它使用非常简单上手容易。ReactHook为什么使用Hooks1.React Hooks 就是让你不必写class组件就可以用state和其他的React特性2.你也可以编写自己的hooks在不同的组件之间复用3.由于业务变动函数组件不得不改为类组件等等。React hooks优势:1.没有破坏性改动完全可选的。 你无需重写任何已有代码就可以在一些组件中尝试 Hook。100% 向后兼容的。 Hook 不包含任何破坏性改动。2.更容易复用代码:它通过自定义hooks来复用状态从而解决了类组件有些时候难以复用逻辑的问题3.函数式编程风格:函数式组件、状态保存在运行环境、每个功能都包裹在函数中整体风格更清爽更优雅4.代码量更少5.更容易拆分组件React hooks缺点:hooks 是 React 16.8 的新增特性、以前版本的就别想了1.部分代码从主动式变成响应式2.状态不同步:函数的运行是独立的每个函数都有一份独立的作用域。当我们处理复杂逻辑的时候经常会碰到“引用不是最新”的问题React生命周期挂载componentDidMount()更新componentDidUpdate()卸载componentWillUnmount()容器组件和展示组件为什么要用在使用React中会出现过一个文件的代码很多既存在应用数据的读取和处理又存在数据的显示。要实现组件的复用我们就需要将展示组件和容器组件分离出来。展示组件Presentational Component关注页面的展示效果外观内部可以包含展示组件和容器组件通常会包含一些自己的DOM标记和样式(style)通常允许通过this.props.children方式来包含其他组件。对应用程序的其他部分没有依赖关系例如Flux操作或store。不用关心数据是怎么加载和变动的。只能通过props的方式接收数据和进行回调(callback)操作。很少拥有自己的状态即使有也是用于展示UI状态的。会被写成函数式组件除非该组件需要自己的状态生命周期或者做一些性能优化。ExamplePageHeader,Sidebar,UserInfo,List容器组件Container Component关注应用的是如何工作的内部可以包含容器组件和展示组件但通常没有任何自己的DOM标记除了一些包装divs并且从不具有任何样式。提供数据和行为给其他的展示组件或容器组件。调用Flux操作并将它们作为回调函数提供给展示组件。往往是有状态的因为它们倾向于作为数据源通常使用高阶组件生成例如React Redux的connectRelay的createContainer或Flux Utils的Container.create而不是手工编写。父子组件通信父子组件props自定义事件redux非父子通信1.状态提升 – 中间人模式(通过父组件来通信一级一级的分发)2.发布订阅者模式 – 不需要借助任何人的力量纯原生js的方式(设计模式中的一种)3.mobx高阶组件高阶组件不是组件高阶组件是一个函数接收一个组件参数然后返回一个新组件。比如说redux的connect连接器。高阶组件并不会改变传入的组件也不会使用继承来拷贝他的行为而是将传入组件放进了这个容器组件中。一个高阶组件是0副作用的纯函数。shouldComponentUpdate 可以避免不必要的rendershouldComponentUpdate确定是否将渲染更新组件。默认情况下它返回true。如果您确定组件在状态或道具更新后不需要渲染则可以返回false值。这是提高性能的好地方因为如果组件收到新的props它可以防止重新渲染。7计算机网络http和https的区别是什么http超文本传输协议https超文本传输安全协议协议为了实现网络通信而达成的一种“约定”这种“规则”不同厂商的生产设备以及不同操作系统组成的计算机之间就可以实现通信。http特点B/S架构。基于TCP/IP通信协议从WEB服务器传输超文本标记语言(HTML)到本地浏览器的传送协议。简单快速1客户向服务器请求服务时只需传送请求方法和路径没有验证对方身份存在冒充危险。2HTTP允许传输任意类型的数据对象数据的完整性未校验容易被篡改。请求信息明文传输容易被窃听截取。。3每次连接只处理一个请求。服务器处理完请求并收到客户的应答后即断开连接但是却不利于客户端与服务器保持会话连接为了弥补这种不足产生了两项记录http状态的技术一个叫做Cookie,一个叫做Session。为什么要用https绝大的网站现在都采用的是https协议这也是未来互联网发展的趋势一般理解为HTTPSSL/TLSSSL 协议位于 TCP/IP 协议与各种应用层协议之间。通过 SSL证书来验证服务器的身份并为浏览器和服务器之间的通信进行加密。https的缺点HTTPS协议多次握手非对称加密的加解密效率是非常低的HTTPS连接缓存不如HTTP高效会增加数据开销和功耗申请SSL证书需要钱功能越强大的证书费用越高。SSL涉及到的安全算法会消耗 CPU 资源对服务器资源消耗较大。HTTPS为什么要使用一个对称加密和非对称加密相结合的一个方式因为http的内容是明文传输的明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点如果信息在传输过程中被劫持传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉这就是中间人攻击。所以我们才需要对信息进行加密。1. 对称加密简单说就是有一个密钥通信双方都持有同一个密钥。Window btoa() // 创建一个 base-64 编码的字符串window.atob(// 解码使用 base-64 编码的字符串。2. 非对称加密简单说就是有两把密钥通常一把叫做公钥、一把叫私钥用公钥加密的内容必须用私钥才能解开同样私钥加密的内容只有公钥能解开。3. https使用了那种加密方式HTTPS 在内容传输的加密上使用的是对称加密非对称加密只作用在证书验证阶段浏览器端通过公钥加密随机数并把加密后的随机数传输到服务端服务端通过私钥对随机数进行解密。http1.0,1.1,2.0,3.0特性HTTP 1.0 浏览器每次请求都需要与服务器建立一个TCP连接服务器处理完成以后立即断开TCP连接无连接服务器不跟踪每个客户单也不记录过去的请求无状态。HTTP 1.11长连接增加Connection字段通过设置Keep-Alive保持HTTP连接不中断如果客户端想关闭HTTP连接可以在请求头中携带Connection:false来告知服务器关闭请求。2管道化服务器必须按照客户端请求的先后顺序依次回送相应的结果。一旦有某个请求超时后续请求只能被阻塞也就是常说的 线头阻塞3缓存处理缓存处理 — 强缓存、协商缓存启发式缓存新增缓存处理强缓存和协商缓存新的字段如cache-control支持断点传输以及增加了Host字段使得一个服务器能够用来创建多个Web站点HTTP 2.01二进制分帧HTTP2.0通过在应用层和传输层之间增加一个二进制分层帧改进传输性能。2多路复用链接共享— 真并行传输。所有HTTP2.0通信都在一个TCP链接上完成这个链接可以撑在任意流量的双向数据流。每个数据流以消息的形式发送而消息由一或多个帧组成。这些帧可以乱序发送然后再根据每个帧头部的流标识符Stream_id重新封装。3头部压缩使用encoder来减少需要传输的header大小通讯双方各自cache一份header_files表既避免重复header的传输又减少了需要传输的大小。高效的压缩算法可以很大的压缩header减少发送包的数量从而降低延迟。4服务器推送服务器除了最初请求的响应外服务器还可以额外向客户端推送资源而无需客户端明确的需求。HTTP 3.0基于UDP协议的QUIC协议。10-RTT 是 QUIC协议相比HTTP2.0的最大优势。缓存当前会话的上下文下次恢复会话的时候只需要将之前的缓存传递给服务器验证通过就可以进行传输了。什么是0-RTT建连传输层0-RTT就能建立连接加密层0-RTT就能建立加密连接2多路复用QUIC基于UDP一个连接上的多个stream之间没有依赖即使丢包只需要重发丢失的包即可不需要重传整个连接。3更好的移动端表现QUIC在移动端的表现比TCP好因为TCP是基于IP识别连接而QUIC是通过ID识别链接。无论网络环境如何变化只要ID不便就能迅速重新连上。4加密认证的根文TCP协议头没有经过任何加密和认证在传输过程中很容易被中间网络设备篡改、注入和窃听。QUIC的packet可以说武装到了牙齿除了个别报文比如PUBLIC_RESET和CHLO所有报文头部都是经过认证的报文Body都是经过加密的。所以只要对 QUIC 做任何更改接收端都能及时发现有效地降低了安全风险。5向前纠错机制QUIC协议有一个非常独特的特性成为向前纠错Foward Error ConnecFEC每个数据包除了它本身的内容之外还包括了其他数据包的数据因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。http状态码尤其301和302区别304。1**: 服务器收到请求, 需请求者进一步操作2**: 请求成功3**: 重定向, 资源被转移到其他 URL 了4**: 客户端错误, 请求语法错误或没有找到相应资源5**: 服务端错误, server error301: 资源(网页等)被永久转移到其他 URL, 返回值中包含新的 URL, 浏览器会自动定向到新 URL302: 临时转移. 客户端应访问原有 URL304: Not Modified. 指定日期后未修改, 不返回资源403: 服务器拒绝执行请求404: 请求的资源(网页等)不存在500: 内部服务器错误http请求几种方法及区别尤其get/post的幂等性8 种请求方法OPTIONS返回服务器针对特定资源所支持的 HTTP 请求方法也可以利用其向 web 服务器发送 * 的请求来测试服务器的功能性。HEAD向服务器索与 GET 请求相一致的响应只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下就可以获取包含在响应小消息头中的元信息。GET向特定的资源发出请求它的本质就是发送一个请求来取得服务器上的某一资源。POST向指定资源提交数据进行处理请求例如提交表单或者上传文件等。数据被包含在请求体中。PUT向指定资源位置上传最新内容。DELETE请求服务器删除 Request-URL 所表示的资源。TRACE回显服务器收到的请求主要用于测试或诊断。CONNECT协议中预留给能够将连接改为管道方式的代理服务器。首先 GET 和 POST 方法都是基于 TCP/IP 协议也就是说两者的数据传输都是建立在 TCP 的连接所以如果从两者的本质来讲并没有多大的区别你非要给 GET 方法加上 request body给 POST 方法加上 URL 参数都是行得通的HTTP 协议对于 GET 和 POST 其实并没有长度限制。因而两者的区别更多地体现在使用规范上从使用规范上来说GET 浏览器回退是无害的因为有本地缓存。而 POST 会再次提交请求post没有本地缓存。GET 只能进行 URL 编码而POST 支持多种编码方式。GET 参数通过 URL 传递并且长度有限制而 POST 放在 request body 并且长度没有限制。并且正因为这个原因 GET 比 POST 更不安全因为参数暴露在 URL 中。最后一个小细节GET 产生一个 TCP 数据包而 POST 产生两个 TCP 数据包。对于 GET 请求浏览器会把 http header 和 data 一起发送出去服务器响应 200。而 POST 请求浏览器会先把 http header 发送出去服务器响应 100然后浏览器再发送 data服务器响应 200。当然了并不是所有浏览器Firefox只发一次幂等性什么是幂等性幂等性指的是一次请求和多次请求某一资源具有同样的副作用。比如你采用 GET 请求银行账户的余额虽然结果不一定相同可是并无副作用因此是幂等的。而如果采用 POST 请求提交扣款多次提交产生不同的副作用因此不满足幂等性。HTTP 的 GET、DELETE、PUT、POST 的幂等性GET 请求用于获取资源无副作用所以是幂等的。DELETE 请求用于删除资源有副作用但是DELETE 同一资源无论调用一次还是调用多次其副作用是相同的因此也满足幂等性。PUT 方法用于创建或更新操作有副作用与 DELETE 相同对同一资源无论调用一次还是多次其副作用是相同的因此也满足幂等性。POST 方法与 PUT 方法的区别主要在于幂等性POST 不具备幂等性因为 POST 请求每次都会创建一个文件而 PUT 方法会在服务器验证是否有 ENTITY若有则更新该 ENTITY 而不是重新创建。TCP 和 UDP有什么特点有哪些区别大概适用于什么样的场合。TCP传输控制协议。是一种面向连接的、可靠的、基于字节流的运输层的全双工通信协议。TCP 对应的协议1 HTTP是从 Web 服务器传输超文本到本地浏览器的传送协议UDP 用户数据报协议。是一种面向无连接不可靠的支持多种交互的运输层通讯协议。UDP 对应的协议1 DNS用于域名解析服务将域名地址转换为 IP 地址。DNS 用的是 53 号端口。TCP的三次握手和四次挥手2MSL是为啥TCP 三次握手第一步让服务器知道客户端能够发送,第二步让客户端知道服务器能够接收并且能够发送,第三步让服务器知道了客户端能够发送。至此双方都能确认了对方能够收和发, 接下来就是愉快的互相收发数据的过程啦。四次挥手第一步: 客户端做为主动发起方想要与服务器断开连接,第二步: 服务器告诉客户端说我收到你的关闭请求了第三步: 服务器向客户端请求关闭第四步: 客户端告诉服务器说我也收到了你的关闭请求了. 此时服务器就关闭了, 而客户端还要等待2MSL的时间之后才能关闭MSL最长报文段寿命。服务器的超时重发机制。在TIME_WAIT 也被叫做MSL等待状态状态下客户端向服务器发出ACK以后需要等待2个MSL的时间。假如ACK在传输中丢失超时后服务端会重新发送FIN, 客户端收到以后会重新发ACK。假如在2MSL时间中客户端都没有收到服务端重发的FIN,那么客户端认为服务端已经收到了客户端发送的ACK 此时客户端才可以放心的断开连接。TCP的拥塞控制防止过多的数据注入到网络中.TCP的四种拥塞控制算法1.慢开始2.拥塞控制3.快重传4.快恢复8其他怎么理解大前端方向LRU原理常用数据结构和算法线程和进程图片资源压缩显示前端性能检测伪随机算法9主管/hr面问题最有成就感的事你最有成就感的事与某次成长困难有关且这件事的解决让你明白一个道理。最失败的经历最近读过什么书写过多少代码怎么和人合作编程遇到矛盾怎么处理平时怎么学习的学习目的考试做历年真题刷错题实际应用官网练习小demo边学边用休闲科幻小说可以跳出自己的惯性思维。为什么选择学习这方面知识职业规划1. 最初始的两年中踏实的做好自己的本职工作会向高手请教研究些新技术提高自己的技术水平。当前面这些完成我已经是可以成为一位独挡一面的技术工程师了。2. 在接下来的几年中熟悉公司使用的这套框架搞懂底层原理。想努力成为一名架构师了“不想当架构师的程序员不是好程序员。”自己在以后也会朝着这个方向去努力。3. 一个产品进行分析的程序员如果能够创造出一款自己设计的产品被大众使用你有什么优点与众不同的东西你有什么缺点别傻傻的光说缺点说说你是怎么克服或者绕开它们的呀兴趣爱好平时作息时间更想从事什么样的行业游戏动漫生活外卖买房等贝壳的问题我选择动漫用爱发电他选择挂我有没有对象灵魂拷问10反问环节的参考提问技术栈前几家面试的时候问问看看自己掌握的和市场需求是不是一样岗位业务问就是核心业务团队规模新团队的话再考虑考虑咯团队偏合作还是偏个人个人觉得这个是个好问题他说偏合作你就说自己挺喜欢和人合作的还能向前辈们学很多东西他说偏个人你就说喜欢这种锻炼个人能力的环境是否出差对方在这个公司干了多久了解一下公司能不能留的下人工作时长加班情况福利待遇往下的推荐在hr面再问薪资构成新人培训机制一些其他的比如工位大小有的公司工位真的贼小健身房下午茶食堂等等数据结构介绍一下堆栈的概念介绍一下链表和数组都有什么区别你最喜欢哪些排序的算法。如果我是一个完全不懂的人请你向我介绍一下它介绍一下时间复杂度的概念学习方式你学习前端的学习路线是怎样的。你学习的方式大概是什么样的先复现一个简单网页学习常用的htmlcss。学习flex布局grid布局媒体查询。学习js基础js常用apiBOM和Dom学习reactJSX ts网络协议LessAntd和mobxreact reactHook讲讲前端工程化解决代码冗余项目可维护性提升版本迭代速度实现前端工程化的基础——前后端分离场景场景题无限下拉刷新相册有哪些注意点场景题给你一个不了解的技术你怎么调研它场景题对库的使用会有哪些考虑的点如果库的使用有争议怎么办如果你的方案胜出了怎么办对图片的优化了解比较新的图片格式吗2025开年AI技术打得火热正在改变前端人的职业命运阿里云核心业务全部接入Agent体系字节跳动30%前端岗位要求大模型开发能力腾讯、京东、百度开放招聘技术岗80%与AI相关……大模型正在重构技术开发范式传统CRUD开发模式正在被AI原生应用取代最残忍的是业务面临转型领导要求用RAG优化知识库检索你不会带AI团队微调大模型要准备多少数据你不懂想转型大模型应用开发工程师等相关岗没项目实操经验……这不是技术焦虑而是职业生存危机曾经React、Vue等热门的开发框架已不再是就业的金钥匙。如果认为会调用API就是懂大模型、能进行二次开发那就大错特错了。制造、医疗、金融等各行业都在加速AI应用落地未来企业更看重能用AI大模型技术重构业务流的技术人。如今技术圈降薪裁员频频爆发传统岗位大批缩水相反AI相关技术岗疯狂扩招薪资逆势上涨150%大厂老板们甚至开出70-100W年薪挖掘AI大模型人才不出1年 “有AI项目开发经验”或将成为前端人投递简历的门槛。风口之下与其像“温水煮青蛙”一样坐等被行业淘汰不如先人一步掌握AI大模型原理应用技术项目实操经验“顺风”翻盘大模型目前在人工智能领域可以说正处于一种“炙手可热”的状态吸引了很多人的关注和兴趣也有很多新人小白想要学习入门大模型那么如何入门大模型呢下面给大家分享一份2025最新版的大模型学习路线帮助新人小白更系统、更快速的学习大模型2025最新版CSDN大礼包《AGI大模型学习资源包》免费分享**一、2025最新大模型学习路线一个明确的学习路线可以帮助新人了解从哪里开始按照什么顺序学习以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛没有明确的学习路线可能会导致新人感到迷茫不知道应该专注于哪些内容。我们把学习路线分成L1到L4四个阶段一步步带你从入门到进阶从理论到实战。L1级别:AI大模型时代的华丽登场L1阶段我们会去了解大模型的基础知识以及大模型在各个行业的应用和分析学习理解大模型的核心原理关键技术以及大模型应用场景通过理论原理结合多个项目实战从提示工程基础到提示工程进阶掌握Prompt提示工程。L2级别AI大模型RAG应用开发工程L2阶段是我们的AI大模型RAG应用开发工程我们会去学习RAG检索增强生成包括Naive RAG、Advanced-RAG以及RAG性能评估还有GraphRAG在内的多个RAG热门项目的分析。L3级别大模型Agent应用架构进阶实践L3阶段大模型Agent应用架构进阶实现我们会去学习LangChain、 LIamaIndex框架也会学习到AutoGPT、 MetaGPT等多Agent系统打造我们自己的Agent智能体同时还可以学习到包括Coze、Dify在内的可视化工具的使用。L4级别大模型微调与私有化部署L4阶段大模型的微调和私有化部署我们会更加深入的探讨Transformer架构学习大模型的微调技术利用DeepSpeed、Lamam Factory等工具快速进行模型微调并通过Ollama、vLLM等推理部署框架实现模型的快速部署。整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握而L3 L4更多的是通过项目实战来掌握大模型的应用开发针对以上大模型的学习路线我们也整理了对应的学习视频教程和配套的学习资料。二、大模型经典PDF书籍书籍和学习文档资料是学习大模型过程中必不可少的我们精选了一系列深入探讨大模型技术的书籍和学习文档它们由领域内的顶尖专家撰写内容全面、深入、详尽为你学习大模型提供坚实的理论基础。书籍含电子版PDF三、大模型视频教程对于很多自学或者没有基础的同学来说书籍这些纯文字类的学习教材会觉得比较晦涩难以理解因此我们提供了丰富的大模型视频教程以动态、形象的方式展示技术概念帮助你更快、更轻松地掌握核心知识。四、大模型项目实战学以致用当你的理论知识积累到一定程度就需要通过项目实战在实际操作中检验和巩固你所学到的知识同时为你找工作和职业发展打下坚实的基础。五、大模型面试题面试不仅是技术的较量更需要充分的准备。在你已经掌握了大模型技术之后就需要开始准备面试我们将提供精心整理的大模型面试题库涵盖当前面试中可能遇到的各种技术问题让你在面试中游刃有余。因篇幅有限仅展示部分资料需要点击下方链接即可前往获取2025最新版CSDN大礼包《AGI大模型学习资源包》免费分享