算法
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
var maxSubArray = function(nums) {
var total = nums[0];
var arrNum = nums[0];
for(let i=1; i<nums.length; i++){
arrNum = Math.max(arrNum + nums[i], nums[i]);
total = Math.max(total, arrNum);
}
return total;
};
查漏补缺
CSS 盒模型
- 标准盒模型:width = content width
- IE 盒模型:width = content width + padding + border
css 布局
圣杯布局
左右两边固定,中间自适应;
#container .column {
height: 200px;
position: relative;
float: left;
}
#center {
background-color: #e9e9e9;
width: 100%;
}
#left {
background-color: red;
width: 200px; /* LC width */
right: 200px; /* LC width */
margin-left: -100%;
}
#right {
background-color: blue;
width: 150px; /* RC width */
margin-right: -150px; /* RC width */
}
// 或者 container overflow:hidden 清除浮动
#footer {
clear: both;
}
BFC
BFC就是“块级格式化上下文”的意思,创建了 BFC的元素就是一个独立的盒子,不过只有Block-level box可以参与创建BFC, 它规定了内部的Block-level Box如何布局,并且与这个独立盒子里的布局不受外部影响,当然它也不会影响到外面的元素
BFC有一下特性:
- 内部的Box会在垂直方向,从顶部开始一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box叠加。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
- 计算BFC的高度时,浮动元素也参与计算。
圣杯布局就是用到了 BFC,默认情况下,如果只是给左边的元素加 float:left,中间和左边的元素会重叠,但是给整个父级加一个 position:relative 就会触发 BFC
flex 布局
容器上写是 display:flex,容器上就具备以下属性。
flex-direction:主轴方向
flex-wrap:如果一条轴线排不下,如何换行
flex-flow:flex-direction 和 flex-wrap 的简写
justify-content:主轴上的对齐方式
align-items:交叉轴上如何对齐
align-content:多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
子属性:
order:定义项目的排列顺序。数值越小,排列越靠前,默认为0
flex-grow:属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
flex-shrink:属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)
flex:flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
align-self:属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性
中间件的实现
express
use 的时候将中间件的都 push 到一个队列中,然后使用的时候遍历队列,拿出来执行回调,传入 req、res、next。next 是一个回调,next 再去执行下一个回调。
koa
也是和上面的差不多,不过队列中的任务都是 generator。
iOS input 下无法 focus
input[type='text'],textarea{
-webkit-user-select:auto;
-moz-user-select:auto;
user-select:auto;
}
graphql
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
Vue 和 react 的区别
总结一下,我们发现的,Vue的优势是:
- 模板和渲染函数的弹性选择
- 简单的语法和项目配置
- 更快的渲染速度和更小的体积
React的优势是:
- 更适合大型应用和更好的可测试性
- Web端和移动端原生APP通吃
- 更大的生态系统,更多的支持和好用的工具
然而,React和Vue都是很优秀的框架,它们之间的相似之处多过不同之处,并且大部分的优秀功能是相通的:
- 用虚拟DOM实现快速渲染
- 轻量级
- 响应式组件
- 服务端渲染
- 集成路由工具,打包工具,状态管理工具的难度低
- 优秀的支持和社区
throttle
var throttle = function(delay, action){
var last = 0
return function(){
var curr = +new Date()
if (curr - last > delay){
action.apply(this, arguments)
last = curr
}
}
}
debounce
var debounce = function(idle, action){
var last
return function(){
var args = arguments
clearTimeout(last)
last = setTimeout(() =>{
action.apply(this, args)
}, idle)
}
}
delegate 的实现
function delegate(parent, type, selector, fn){
parent.addEventListener(type, fuction(e){
var target = e.target;
var current = e.currentTarget;
var bubble = true;
while(bubble && target != current){
if(filiter(agent, selector, target)){
bubble = fn.call(target, e);
}
target = target.parentNode;
return bubble;
}
}, false);
function filiter(parent, selector, target){
var nodes = parent.querySelectorAll(selector);
for(var i=0; i<nodes.length; i++){
if(nodes[i] === target) rertun true
}
}
}
测试案例
String.prototype.trim = function(){
return this.replace(/^\s|\s$/g, '');
}
// TDD是“测试驱动的开发”
suite('trim', function() {
test('test trim string', function() {
var aaa = ' a a ';
assert.equal(aaa.trim(), 'a a');
});
});
// BDD是“行为驱动的开发”
describe('trim', function() {
it('test trim string', function() {
var aaa = ' a a ';
assert.equal(aaa.trim(), 'a a');
});
});
PWA 实现
基于 service worker,ServiceWorker 能访问 cache,可以将一些 js 文件缓存到本地,可以监听所有的请求和初始化,也可以推送消息。最后通过一个 mainfest 文件进行展示。
getBoundingClientRect() 来获取页面元素的位置
document.querySelector('.demo').getBoundingClientRect(),获取之后会引发重排
严格模式
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
weex 分析
- weex 初始化 SDK,加载 js framework
- 注册 Component、module、handle
weex 初始化 SDK,WXSDKEngine
[self _registerDefaultComponents];
[self _registerDefaultModules];
[self _registerDefaultHandlers];
当注册好以后不一定是会直接注册到 js framework 中。如果 framework 没有加载好,就会放在一个堆栈中,等 js framework 加载好后再对栈进行遍历将 Component、module 通过 bridge 进行注册。
js framework 执行在一个线程中,线程会有个 run loop 来保证线程一直是活的。
- 挂载全局属性方法及 VM 原型链方法
- 创建于客户端通信桥
- 弥补环境差异
js bundle 的执行。
- 初始化生命周期
- 数据双绑
- 模板解析
- 绘制 Native UI
事件传递,在初始化 js bundle 的时候,会传递事件类型,和一个 ref 过去,客户端会将这个事件绑定到这个 UI 上,
taskCenter.send(
'dom',
{ action: 'addEvent' },
[this.ref, type]
)
当事件触发之后,客户端会抛一个事件出来,会带有这些数据,ref、type、event、domChanges,一开始还会有 weex 实例 ID,往上传递的时候再进行剥离。传递给 jsfm,jsfm 找到对应的前端 js 事件进行触发,如果事件会对 DOM 进行改动,这个时候又会触发更行。
方法论
最小发布 -> 高内聚
最短依赖 -> 低耦合
webpack 性能优化
常规手段:tree shacking、抽取公共代码、代码压缩混淆、loader 编译去除 node_module、根据不同环境选择不同的 devtool。
happypack:让 loader 可以多进程去处理文件
cacheDirectory:重新构建时用缓存来构建没有修改过的文件不会重新编译。
减少构建搜索或编译的路径,DLL 针对第三方 NPM 包,这些包我们并不会修改它,但仍然每次都要在 build 的过程消耗构建性能,我们可以通过 DllPlugin 来前置这些包的构建
实现 bind 方法
Function.prototype.bind2 = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}
实现高度是宽度的一半
padding 百分比是 content width
部署 http2
一般部署 http2 都需要基于 ssl,所以一般我们在配置的时候都需要验证 CA 证书。
server {
server_name YOUR_DOMAINNAME_HERE;
listen 443 ssl http2;# http2 is available only since OpenSSL version 1.0.2
listen 80;
if ($scheme = http) {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
ssl_certificate server.crt;
ssl_certificate_key server.key;
keepalive_timeout 70;
}