更加全面的可以到引擎找
box-sizing有两个值:content-box(W3C标准盒模型),border-box(怪异模型),
这个css 主要是改变盒子模型大小的计算形式
可能有人会问padding-box,这个之前只有 Firefox 标准实现了,目前50+的版本已经废除;
用一个栗子来距离,一个div的宽高分别100px,border为5px,padding为5px
<style> .test { box-sizing: content-box; border: 5px solid #f00; padding:5px; width: 100px; height: 100px; } </style> <div class="test"></div> <!-- content-box的计算公式会把宽高的定义指向 content,border和 padding 另外计算, 也就是说 content + padding + border = 120px(盒子实际大小) 而border-box的计算公式是总的大小涵盖这三者, content 会缩小,来让给另外两者 content(80px) + padding(5*2px) + border(5*2px) = 100px -->常用的一般为三种.clearfix, clear:both,overflow:hidden;
比较好是 .clearfix,伪元素万金油版本...后两者有局限性..等会再扯
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } <!-- 为毛没有 zoom ,_height 这些...IE6,7这类需要 csshack 不再我们考虑之内了 .clearfix 还有另外一种写法... --> .clearfix:before, .clearfix:after { content:""; display:table; } .clearfix:after{ clear:both; overflow:hidden; } .clearfix{ zoom:1; } <!-- 用display:table 是为了避免外边距margin重叠导致的margin塌陷, 内部元素默认会成为 table-cell 单元格的形式 -->clear:both:若是用在同一个容器内相邻元素上,那是贼好的...有时候在容器外就有些问题了,比如相邻容器的包裹层元素塌陷
overflow:hidden:这种若是用在同个容器内,可以形成 BFC避免浮动造成的元素塌陷
这种问题见仁见智,我的回答大体是这样的..待我捋捋.
transition一般用来做过渡的, 没时间轴的概念, 通过事件触发(一次),没中间状态(只有开始和结束)
而animate则是做动效,有时间轴的概念(帧可控),可以重复触发和有中间状态;
过渡的开销比动效小,前者一般用于交互居多,后者用于活动页居多;
至于如何让animate停留在最后一帧也好办,就它自身参数的一个值就可以了
animation-fill-mode: forwards; <!--backwards则停留在首帧,both是轮流-->让我们来举个栗子....自己新建一个 html 跑一下....
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Box-sizing</title> <style> .test { box-sizing: border-box; border: 5px solid #f00; padding: 5px; width: 100px; height: 100px; position:absolute; /* 简写的姿势排序 @keyframes name : 动画名 duration 持续时间 timing-function 动画频率 delay 延迟多久开始 iteration-count 循环次数 direction 动画方式,往返还是正向 fill-mode 一般用来处理停留在某一帧 play-state running 开始,paused 暂停 .... 更多的参数去查文档吧..我就不一一列举了 */ animation: moveChangeColor ease-in 2.5s 1 forwards running; } @keyframes moveChangeColor { from { top:0%; left:5%; background-color:#f00 } to{ top:0%; left:50%; background-color:#ced; } } </style> </head> <body> <div class="test"></div> </body> </html>我们要考虑两种情况,定宽高和不定宽高的;
方案 N 多种,我记得我很早写过这类的笔记
传送门:网页元素居中攻略记
!important > 行内样式 > id > class > tag
样式权重可以叠加, 比如 id>class
简言之:就是不滥用标签(比如 DIV)/随意嵌套(比如 span>div) ,
类的命名要合理, 利于浏览器解析乃至引擎收录,也利于团队协作和维护
七种数据类型
BooleanNullUndefinedNumberStringSymbol (ECMAScript 6 新定义)Object(ES6之前)其中5种为基本类型:string,number,boolean,null,undefined,
ES6出来的Symbol也是原始数据类型 ,表示独一无二的值
Object 为引用类型(范围挺大),也包括数组、函数,
大体说一下,想要知其所以然请引擎搜索
相同点:
在 if判断语句中,值都默认为 false大体上两者都是代表无,具体看差异差异:
null转为数字类型值为0,而undefined转为数字类型为 NaN(Not a Number)undefined是代表调用一个值而该值却没有赋值,这时候默认则为undefinednull是一个很特殊的对象,最为常见的一个用法就是作为参数传入(说明该参数不是对象)设置为null的变量或者对象会被内存收集器回收ajax全称是异步 javascript 和 XML,用来和服务端进行数据交互的,让无刷新替换页面数据成了可能;
至于有哪些要要点,来一个简短的ajax请求
var xhr = new XMLHttpRequest(); // 声明一个请求对象 xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ // readyState 4 代表已向服务器发送请求 if(xhr.status === OK){ // // status 200 代表服务器返回成功 console.log(xhr.responseText); // 这是返回的文本 } else{ console.log("Error: "+ xhr.status); // 连接失败的时候抛出错误 } } } xhr.open('GET', 'xxxx'); // 如何设置请求头? xhr.setRequestHeader(header, value); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(null); // get方法 send null(亦或者不传,则直接是传递 header) ,post 的 send 则是传递值更为详细的可以阅读此处;
<<ajax 概念 by 阮一峰>><<XMLHttpRequest2 用法指南>>这里主要考察了闭包,函数表达式以及 IIFE(立即执行表达式)
var add = (function() { // 声明一变量,由于下面 return所以变量只会声明一次 var count = 0; return function() { return console.log(count++); }; })(); add(); // 0 add(); // 1 add(); // 2我这里用的是结合 ES6的,代码量很短
//很好理解, Set 具有值唯一性(但不是所有值,等会我抛出我的另外一篇文章) // 结合...解构,可以把可迭代(比如 arguments/nodelist 等)的转为数组 // sort 里面传入 两个值比较,返回-1和1是因为1代表这个数大排后(相对),-1代表小(相对),0为相等 let arr = [...new Set(['2018-03-05', '2013-06-12','2019-03-12','2018-03-05','2014-02-22'])].sort(function(a,b){ return a<b ? -1:1; // 这里返回的是升序的,降序改下返回值就好了.所以是相对 }) // ["2013-06-12", "2014-02-22", "2018-03-05", "2019-03-12"]对于数组去重的,有兴趣的可以看下我这篇水文:
JS数组去重!!!一篇不怎么靠谱的"深度"水文上面和这道题逗涉及到数组顺序的问题,想了解下为什么 a-b,a>b这类可以更改排序
可以看看知乎对于这块的探讨: 传送门:javascript排序return a-b?
后者的思路就是用排序把异序扭正..
普通版
// 回文判断 , 比如用 abcba var isPalindromes = function(params){ params = params.toString().toLowerCase() return params === params.split('').reverse().join(''); } // 同字母异序判定,比如`abcefd`和`dceabf` var isAnagram = function(str1, str2) { str1 = str1.toString().toLowerCase(); str2 = str2.toString().toLowerCase(); return str1.split('').sort().join('') === str2.split('').sort().join('') }进阶版:多一些特殊字符
若是我们要去除所有非字母数字的字符,则需要用到正则
// 进阶版: isPalindromes('abc_ &b #@a') var isPalindromes = function(params){ // 传入参数先转为字符串且全部转为小写,最后去除多余字符比较 params = params.toString().toLowerCase().replace(/[\W_\s]/g,''); console.log(params) return params === params.split('').reverse().join(''); } // 进阶版同字母异序: isAnagram('ab *&cef#d','!d@ce^abf') var isAnagram = function(str1, str2) { str1 = str1.toString().toLowerCase().replace(/[\W_\s]/g,''); str2 = str2.toString().toLowerCase().replace(/[\W_\s]/g,''); return str1.split('').sort().join('') === str2.split('').sort().join('') }浅拷贝就是把属于源对象的值都复制一遍到新的对象,不会开辟两者独立的内存区域;
深度拷贝则是完完全全两个独立的内存区域,互不干扰
浅拷贝 // 这个 ES5的 function shallowClone(sourceObj) { // 先判断传入的是否为对象类型 if (!sourceObj || typeof sourceObj !== 'object') { console.log('您传入的不是对象!!') } // 判断传入的 Obj是类型,然后给予对应的赋值 var targetObj = sourceObj.constructor === Array ? [] : {}; // 遍历所有 key for (var keys in sourceObj) { // 判断所有属于自身原型链上的 key,而非继承(上游 )那些 if (sourceObj.hasOwnProperty(keys)) { // 一一复制过来 targetObj[keys] = sourceObj[keys]; } } return targetObj; } // ES6 可以用 Object.assign(targeObj, source1,source2,source3) 来实现对象浅拷贝 深度拷贝 // 就是把需要赋值的类型转为基本类型(字符串这些)而非引用类型来实现 // JOSN对象中的stringify可以把一个js对象序列化为一个JSON字符串,parse可以把JSON字符串反序列化为一个js对象 var deepClone = function(sourceObj) { if (!sourceObj || typeof sourceObj !== 'object') { console.log('您传入的不是对象!!'); return; } // 转->解析->返回一步到位 return window.JSON ? JSON.parse(JSON.stringify(sourceObj)) : console.log('您的浏览器不支持 JSON API'); }; 深拷贝的考虑点实际上要复杂的多,详情看看知乎怎么说简言之:谁调用指向谁,运行时的上下文确定,而非定义的时候就确定;
强行绑定 this的话,可以用 call,apply,bind,箭头函数....来修改this的指向
这类的文章太多,自行搜索吧....
Q: 看到你说到 bind,能用 JS简单的模拟个么?
Function.prototype.emulateBind = function (context) { var self = this; return function () { return self.apply(context); } }这个实现很粗糙...更为详细全面,考虑周全的(比如参数的处理什么的)...自行谷歌.
作用域就是有它自身的上下文区域(比如函数内),内部会有变量声明提升,函数声明提升这些;
函数声明提升优于变量声明提升..
作用域有全局作用域和块级作用域(局部,比如用 let 或者单纯花括号的);
作用域会影响this的指向
坐等补充,我回答的时候,面试大佬只是 嗯..恩...恩...也不知道具体如何
我一般用这三种,cors,nginx反向代理,jsonp
jsonp : 单纯的 get 一些数据,局限性很大...就是利用script标签的src属性来实现跨域。nginx 反向代理: 主要就是用了nginx.conf内的proxy_pass http://xxx.xxx.xxx,会把所有请求代理到那个域名,有利也有弊吧..cors的话,可控性较强,需要前后端都设置,兼容性 IE10+ ,比如 Access-Control-Allow-Origin: http://foo.example // 子域乃至整个域名或所有域名是否允许访问Access-Control-Allow-Methods: POST, GET, OPTIONS // 允许那些行为方法Access-Control-Allow-Headers: X-PINGOTHER, Content-Type // 允许的头部字段Access-Control-Max-Age: 86400 // 有效期Q: 对于想携带一些鉴权信息跨域如何走起?比如cookie!
需要配置下 header Access-Control-Allow-Credentials:true ,具体用法看下面的nginxdemo
当然cros的配置不仅仅这些,还有其他一些,具体引擎吧....
若是我们要用 nginx或者 express 配置cors应该怎么搞起? 来个简易版本的
nginx location / { # 检查域名后缀 add_header Access-Control-Allow-Origin xx.xx.com; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; add_header Access-Control-Allow-Credentials true; add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type; add_header Access-Control-Max-Age 86400; } express, 当然这货也有一些别人封装好的 cors中间件,操作性更强... let express = require('express'); let app = express(); //设置所有请求的头部 app.all('*', (req, res, next) => { res.header("Access-Control-Allow-Origin", "xx.xx.com"); res.header("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"); res.header("Access-Control-Allow-Credentials","true") res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); next(); });有些还会跟你死磕,,除了这些还有其他姿势么...我说了一个HTML5的postMessage....
..因为真心没用过,只是以前查阅的时候了解了下..只能大体点下
这货用于iframe 传递消息居多, 大体有这么两步步
window打开一个实例,传递一个消息到一个x域名x 域名下监听message事件,获取传递的消息这货的兼容性没那么好,而且没考虑周全下容易遭受 CSRF 攻击
这里就不说概念性的东西了
XSS的防范
我能想到的就是转义<>这些造成代码直接运行的的标签..轮询或者正则替换 而面试官说这种的效率最低下,我回来仔细找了找相关资料好像没有更优方案...有的留言...若是有用到 cookie,设置为http-only,避免客户端的篡改CSRF的防范一般这几种
验证码,用户体验虽然不好,,但是很多场合下可以防范大多数攻击验证 HTTP Referer 字段,判断请求来源token加密解密,这种是目前很常用的手段了...任何防范都有代价的,比如验证码造成的体验不好,token滥用造成的性能问题,轮询替换造成的响应时间等
原型链算是 JS 内一种独有的机制,
所有对象都有一个内置[[proto]]指向创建它的原型对象(prototype)
原型链的基本用来实现继承用的
我在写的时候,用了两种,一个是 ES5和 ES6的方案
ES5:寄生组合式继承:通过借用构造函数来继承属性和原型链来实现子继承父。 function ParentClass(name) { this.name = name; } ParentClass.prototype.sayHello = function () { console.log("I'm parent!" + this.name); } function SubClass(name, age) { //若是要多个参数可以用apply 结合 ...解构 ParentClass.call(this, name); this.age = age; } SubClass.prototype = Object.create(ParentClass.prototype); SubClass.prototype.constructor = SubClass; SubClass.prototype.sayChildHello = function (name) { console.log("I'm child " + this.name) } let testA = new SubClass('CRPER') // Object.create()的polyfill /* function pureObject(o){ //定义了一个临时构造函数 function F() {} //将这个临时构造函数的原型指向了传入进来的对象。 F.prototype = obj; //返回这个构造函数的一个实例。该实例拥有obj的所有属性和方法。 //因为该实例的原型是obj对象。 return new F(); } */ ES6: 其实就是ES5的语法糖,不过可读性很强.. class ParentClass { constructor(name) { this.name = name; } sayHello() { console.log("I'm parent!" + this.name); } } class SubClass extends ParentClass { constructor(name) { super(name); } sayChildHello() { console.log("I'm child " + this.name) } // 重新声明父类同名方法会覆写,ES5的话就是直接操作自己的原型链上 sayHello(){ console.log("override parent method !,I'm sayHello Method") } } let testA = new SubClass('CRPER')到这里就结束了么...不,这只是笔试,
Q: 问的时候你用过静态方法,静态属性,私有变量么?
静态方法是ES6之后才有这么个玩意,有这么些特点
方法不能给 this引用,可以给类直接引用静态不可以给实例调用,比如 let a = new ParentClass => a.sayHello() 会抛出异常父类静态方法,子类非static方法没法覆盖父类静态方法可以给子类继承静态属性可以继承也可以被修改看下面的代码..
class ParentClass { constructor(name) { this.name = name; } static sayHello() { console.log("I'm parent!" + this.name); } static testFunc(){ console.log('emm...Parent test static Func') } } class SubClass extends ParentClass { constructor(name) { super(name); } sayChildHello() { console.log("I'm child " + this.name) } static sayHello() { console.log("override parent method !,I'm sayHello Method") } static testFunc2() { console.log(super.testFunc() + 'fsdafasdf'); } } ParentClass.sayHello(); // success print let a = new ParentClass('test'); a.sayHello() // throw error SubClass.sayHello(); // 同名 static 可以继承且覆盖 SubClass.testFunc2(); // 可以继承 let testA = new SubClass('CRPER');私有变量这个我没答出来,只是说了下没有private这个关键字和基本用下划线的人为区分
所以回来只是找了下相关的资料,发现有一个比较好的模拟方案,就是WeakMap;
WeakMap可以避免内存泄露,当没有被值引用的时候会自动给内存寄存器回收了.
const _ = new WeakMap(); // 实例化,value 必须为对象,有 delete,get,has,set四个方法,看名字都知道了 class TestWeakMap { constructor(id, barcode) { _.set(this, { id,barcode }); } testFunc() { let { id,barcode } = _.get(this); // 获取对应的值 return { id,barcode }; } }Promise和ajax没有半毛钱直接关系.promise只是为了解决"回调地狱"而诞生的;
平时结合 ajax是为了更好的梳理和控制流程...这里我们简单梳理下..
Promise有三种状态,Pending/resolve()/reject();
一些需要注意的小点,如下
在 Pending 转为另外两种之一的状态时候,状态不可在改变..Promise的 then为异步.而(new Promise())构造函数内为同步Promise的catch不能捕获任意情况的错误(比如 then 里面的setTimout内手动抛出一个Error)Promise的 resolve若是传入值而非函数,会发生值穿透的现象Promise的catch还是then,return的都是一个新的 Promise(在 Promise 没有被中断的情况下)Promise 还有一些自带的方法,比如race,all,前者有任一一个解析完毕就返回,后者所有解析完毕返回...
实现一个延时的 promise 函数, 可以用async和await
const delay = (time)=> new Promise((resolve,reject)=>{ setTimeout(resolve,time) }) // test let testRun = async function(){ console.log(1); await delay(2000); console.log('我两秒后才触发',3) } // 1 => Promise = > 3 <<Promise 必知必会(十道题)>>: 有助于你更加深刻的了解 promise 的运行情况关于 Promise 的 9 个提示更多的Promise 详情可以参考<<JavaScript Promise迷你书(中文版)>>;Q: TCP 是在哪个OSI 的哪个层!通讯过程是全双工还是半双工(单工)?
A: 传输层,全双工
Q: TCP的通讯的过程是怎么样的!
A: 整个过程是三次握手,四次挥手..
Q: 你说的没错,说说整个过程如何?
A: 举个栗子,我把 TCP 比做两个人用对讲机沟通(大白话)..三次握手就是.A1(吼叫方,客户端)想要呼叫 A2(控制室的某某,服务端)..
A1对着对讲机说"over over ,听到请回答"(第一次,请求应答) ...
A2收到回应"收到收到,你说"(第二次,确认应答)
A1开始巴拉巴拉个不停而 A2没拒绝(第三次,通讯建立)
而四次挥手则是两者确认互相倾述完毕的过程..
A1说:"控制室,报告完毕了"(第一次挥手)
A2说:"知道了...那么你废话说完就好好听我指挥....巴拉巴拉.."(第二次挥手)
A1此时等待控制室说完毕,而控制室等回应(第三次挥手)
等到 A1回馈控制室确认都知道完毕了..(第四次挥手)...
以上都是瞎掰,可能有些地方描述不当,笑笑就好了
TCP没有百分百建立成功的,会造成链接失败的情况有很多..
比如长时间没应答(A1吼了半天没有反应或者 A2应答了而 A1不再鸟它)..亦或者丢包(对讲机也没了);
TCP 协议相关的文章网上很多,若是要更加全面的了解该协议请自行引擎..
我建议阅读<<TCP-IP详解卷1~卷3>>,这个是网络圣经...很厚...我只看了一丢丢..
对于这类的问题我也只能大体点了下,毕竟不是专攻网络这块的...
OSI 七层涵盖:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层;
五层模型就是"会话,表示,应用层"同为一层;
Q: DNS 的大体的执行流程了解么,属于哪个层级?工作在哪个层级?
DNS 属于应用层协议, 至于TCP/UDP哪一层上面跑,看情况 , 大体的执行流程是这样的;
优先读取浏览器缓存其次系统的缓存都没有的情况下,找本地hosts文件(比如你写了映射关系优先寻找)再没有的情况找最近的域名解析服务器再没有则扩大访问,最终找到根服务器,还是没有就失败了..DNS 的解析的几个记录类型需要了解:
A: 域名直接到 IPCNAME: 可以多个域名映射到一个主机,类似在 Github Page就用 CNAME 指向MX: 邮件交换记录,用的不多,一般搭建邮件服务器才会用到NS: 解析服务记录,可以设置权重,指定谁解析TTL: 就是生存时间(也叫缓存时间),一般的域名解析商都有默认值,也可以人为设置TXT: 一般指某个主机名或域名的说明回来我找下相关的资料,有兴趣的可以深入了解下,传送门如下:
梳理Linux下OSI七层网络与TCP/IP五层网络架构TCP/IP(六)应用层(DNS和HTTP协议)DNS域名解析解剖我只是粗浅的回答了下...
HTTP相对于 HTTPS来说,速度较快且开销较小(没有 SSL/TSL) 对接,默认是80端口;
HTTP容易遭受域名劫持,而HTTPS相对来说就较为安全但开销较大(数据以加密的形式传递),默认端口为443..
HTTP是明文跑在 TCP 上.而HTTPS跑在SSL/TLS应用层之下,TCP上的
Q: 那么 HTTPS中的TLS/SSL是如何保护数据的...
一般有两种形式,非对称加密,生成公钥和私钥,私钥丢服务器,公钥每次请求去比对验证;
更严谨的采用 CA(Certificate Authority),给密钥签名....
Q: 你说到对称加密和非对称加密,能说说整个流程如何运转的么(HTTPS)
对称加密: 双方都有同样的密钥,每次通讯都要生成一个唯一密钥,速度很快安全性较低且密钥增长的数量极快非对称加密(一般用 RSA) 安全性很高,对资源消耗很大(CPU),目前主流的加密算法(基本用于交换密钥或签名,而非所有通讯内容)CA(数字签名): 这个是为了防止中间人给偷换了造成数据被窃取而诞生的用一些权威机构颁布的算法来签名,权威机构做中间人,通讯过程都会跟机构核对一遍懂得真心不多,回来找了下相关资料,有兴趣可以点击看看;
深入揭秘HTTPS安全问题&连接建立全过程深入理解 https 通信加密过程:口语化 " : 看了上面那篇文章来看下面,会清晰很多Q: SPDY 听说过么.什么来的?
谷歌推行一种协议(HTTP 之下SSL之上[TCP]),可以算是HTTP2的前身,有这么些优点
压缩数据(HEADER)多路复用优先级(可以给请求设置优先级)而这些优点基本 HTTP2也继承下来了..
Q: 你对 HTTP 的状态吗了解多少...
这里列举一丢丢常见的..
1XX: 一般用来判断协议更换或者确认服务端收到请求这些 100: 服务端收到部分请求,若是没有拒绝的情况下可以继续传递后续内容101: 客户端请求变换协议,服务端收到确认2xx: 请求成功,是否创建链接,请求是否接受,是否有内容这些 200: (成功)服务器已成功处理了请求。201: (已创建)请求成功并且服务器创建了新的资源。202: (已接受)服务器已接受请求,但尚未处理。204: (无内容)服务器成功处理了请求,但没有返回任何内容。3XX: 一般用来判断重定向和缓存 301: 所有请求已经转移到新的 url(永久重定向),会被缓存302: 临时重定向,不会被缓存304: 本地资源暂未改动,优先使用本地的(根据If-Modified-Since or If-Match去比对服务器的资源,缓存)4XX: 一般用来确认授权信息,请求是否出错,页面是否丢失 400: 请求出错401: 未授权,不能读取某些资源403: 阻止访问,一般也是权限问题404: 页面丢失,资源没找到408: 请求超时415: 媒介类型不被支持,服务器不会接受请求。5XX: 基本都是服务端的错误 500: 服务端错误502: 网关错误504: 网关超时Q: HTTP的请求报文是怎么样的,能大体的说下么?
HTTP 的请求报文 = 请求行 + 请求头 + 请求体;
请求行: 这个好理解就是访问的方法+ 协议+ 访问的 URL 构成请求头: 这个也好理解,比如 accept,content-type,user-agent这类值键对,服务端可以直接读取的请求体: 比如 POST 提交的一个表单,我们编码后放在上面需要传递的想深入了解的具体引擎搜索
Q: 请求报文知道,那你说说cookie是如何跟随请求的?
Cookie 就是保存在 HTTP 协议的请求或者应答头部(Cookie 是由服务端生成),这样一路漂泊...
这类东东弄成数组还是挺好弄的
var str = "I have a dream";就是 macrotask和microtask 相关的, 具体记不起来了..那时候给了答案虽然对了.
要说出所以然,给秀了一脸..回来找了下相关的资料;
JavaScript 运行机制详解:再谈Event Loop深入理解事件循环和异步流程控制所有你需要知道的关于完全理解 Node.js 事件循环及其度量来,这纸给你,写个快排试试...
// 快排的大体思路是这样的, // 找个中位值,从原数组切割出来, // 剩下的作为两个数组,每次都去比较; // 直到递归的结果出来, 平均复杂度O(nlog n) function quickSort(arr) { //如果数组长度<=1,则直接返回 if (arr.length <= 1) { return arr; } // 中间位(基准)取长度的一半向下取整 var pivotIndex = Math.floor(arr.length / 2); //把中间位从原数组切割出来, splice 会改变原数组!!!! var pivot = arr.splice(pivotIndex, 1)[0]; //定义两个空数组来存放比对后的值 var left = []; var right = []; //比基准小的放在left,比基准大的放在right for (var i = 0 , j = arr.length; i < j; i++) { if (arr[i] <= pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } //递归下去 arr = [ left , pivot , right] // 怎么个递归法,就是比对后的数组还是会重复之前的取基准再切开比较..直到最后没有可以切了 return quickSort(left).concat([pivot], quickSort(right)); }Q: 写一个二分法查找
// 二分法跟快排的思路差不多,对半比较 function binSearch(target,arr,start,end) { var start = start || 0; // 允许从什么位置开始,下标 var end = end || arr.length-1; // 什么位置结束,下标 var mid = parseInt(start+(end-start)/2); // 中位下标 if(target==arr[mid]){ return mid; // 找到直接返回下标 }else if(target>arr[mid]){ //目标值若是大于中位值,则下标往前走一位 return binSearch(target,arr,mid+1,end); }else{ 若是目标值小于中位值,则下标往后退一位 return binSearch(target,arr,start,mid-1); } return -1; // 没有找到 } // binSearch(5,[1,2,3,4,5,6,7,8]) => 4这类的文章很多,有兴趣的可以阅读下面的一些文章
传送门:
<<十大经典排序算法总结(JavaScript描述>>JavaScript数据结构和算法javascript 常见排序算法问题的要点: 玻璃球碎(有限个数) ,确定楼层数 , 最少次数 => 就是求最优的公式
在这道题上给秀的一脸,我的第一次的思路
先折半,就变成[1-50][51-100], 那就是 1+50 = 51次 ...
面试大佬说,你用了快排的思路就肯定不是最优的..
憋了许久,想到开平方 , 这样的话,最多只要20次
然后又说给我三个球,在1000米的高楼,判断多少次...但是根据我上面的话,
开立方, , 那最多不超过30次;
至于第一次丢球的位置如何确定, 就是开平之后的值作为一个区间.
若 N 个球和 M 米的大厦...第一次丢球的高度区间就是这个了
面试大佬说这个还可以...那就暂且告一段落
...回来用万能的搜索引擎找了下..最优方案+最少次数需要考虑的东西很多,没那么简单
传送门: 知乎有人讨论了这个问题;
但是高数还老师了..这种帖子看的一脸懵逼....抽空再好好研究下
大体常见的手段了解.
比如从客户端着手的:
压缩代码(JS/CSS),压缩图片合并一些小图片(css sprite)若是打包的代码尽可能切割成多个 chunk,减少单一 chunk过大静态文件采用 cdn 引入HTTP的缓存头使用的合理减小第三方库的依赖对于代码应该考虑性能来编写,比如使用requestAnimationFrame绘制动画,尽可能减少页面重绘(DOM 改变)渐进升级,引入preload这些预加载资源看情况用service worker来缓存资源(比如移动端打算搞 PWA)比如从服务端着手:
带宽,域名解析, 多域名解析等页面做服务端渲染,减小对浏览器的依赖(不用客户端解析)渐进升级,比如引入 HTTP2(多路复用,头部压缩这些可以明显加快加载速度)当然,这是这些都是很片面的点到...实际工作中去开展要复杂的多;
比如我们要多个维度去考虑的话,要去优化 DOM 的绘制时间,资源的加载时间,域名解析这些;
要全面的优化一个项目是一个大工程...
MySQL索引类型:
普通索引: 就普通的类型唯一索引: 代表索引的值唯一不重复(允许有空值),相对于上面多了个UNIQUE主键索引:(创建表的跟随创建,唯一索引,不允许有空值)组合索引(就是将多个字段都建立到一个索引)索引有利有弊,用的好加快查询速度,滥用索引会造成大量磁盘空间占用,维护性也会增多;索引不会包含null的列;
索引的数据结构储存方式,我只简单了解过B-Tree
至于MySQL 和 MongoDB的差异;
前者是关系型数据库, 后者非关系型数据库(数据是以文档的方式储存,值为 key-value);
MySQL应用层面很广,有事务系统这些,链表查询这些都很方便.经常作为很多系统的主力数据库
而MongoDB作为NoSQL,虽然有些层面不如 MySQL,但是应用层面也挺广,比如结合前端做一些用户的概要信息的维护,一些缓存信息的维护.
em....后端了解不多,也能点到即止....大学的时候学过一些..都差不多还给老师....
还有一些题目记不起来了,就没辙了...还有一些题目是看你个人发挥的,没法写,比如
Q: 让你来为公司的一个项目做技术选型,你会怎么做,为什么?Q: MVVM 和 MVC 的差异? 听说过 MVP?Q: React,Angular,Vue的比较?Q: 说说你对 VNode的理解,diff的过程;Q: Vue-Router的两种模式主要依赖什么实现的Q: 小程序以及React Native的差异..等等有些问题回答的一团糟(自我感觉), 我一直在思考,什么叫系统化学习;
我这种的感觉更多的给人叫做"野路子",折腾这折腾那,但是又没有很深入一些知识点;
但面试的过程中磕磕碰碰才能发现自身的很多不足和需要去努力的方向.
此篇文章暂未停更,随时会更新,因为作为技术渣的我还木有找到工作;
在找到工作之前会一直更新面试碰到问到的问题;
有不对之处请留言,会及时跟进修正,谢谢各位大佬
作者:CRPER 链接:https://juejin.im/post/5a998991f265da237f1dbdf9 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。