二分之一

Just Jason's Blog

一道据说是企鹅的web前端面试题及解法

题目出自蓝色经典论坛:http://bbs.blueidea.com/thread-3044619-1-1.html

有一组数字,从1到n,从中减少了3个数,顺序也被打乱,放在一个n-3的数组里题:请找出丢失的数字,最好能有程序,最好算法比较快(假设n=10000)

当然解题方法很多,各位看客先尝试用自己的方法解一解,也许会有不一样的收获!

====================

以下是我的解决方法,仅供参考,不过我没有使用for,只使用sort;估计出题者还是考察jser的基础知识;

换了新方法,支持首尾及连续抽取!

附代码:

/*
*仅生成DEMO数组 arr
*按命题要求,arr是已知的,所以生成arr不计作计算时间
*/
var n = 10000; //长度为10000的测试数组
var arr = (function(){
    var arr = [];
    for(var i=1;i<=n;i++){
        if(i!=526&&i!=5422&&i!=2563){ //抽出的数字
            arr.push(i);
        }
    }
    arr = shuffle(arr);

    //打乱数组顺序
    function shuffle(arr){
        for(var rnd, tmp, i = arr.length; i; rnd = parseInt(Math.random() * i), tmp = arr[--i], arr[i] = arr[rnd], arr[rnd] = tmp);
        return arr;
    }

    return arr;
})();
//---------------仅生成DEMO数组 arr-----------------//

//---------------找出三个被抽出的数字----------------//

//结果数组
var res = [];

var time = +(new Date); //开始计时点
//按数值大小排序
arr.sort(function(a,b){
    return a-b;
});

//给首尾各加一个数,以保证以下的算法能找到首尾两个被抽出的数
arr.unshift(0);
arr.push(n+1);

//找到抽出的数
arr.sort(function(a,b){
    if(b-a!=1){
        while(a<b-1){
            a++
            res.push(a);
        }
    }
});

time = (+(new Date))-time; //结束计时点

alert("找到的数:"+res+",所花费的时间:"+time+"毫秒");

Read more »

HTML5游戏入门DEMO【种花女孩推花盆】

小试牛刀,周末用了一天时间,写了一个简单的”HTML5游戏入门DEMO”。

【种花女孩推花盆】创意源于推箱子,是一个flash的小游戏,大家可以先去体验一下flash版的。

游戏比较简单,不使用html5也可以实现,canvas在这个游戏里面有一个大材小用,但姑且也尝一下鲜,就当学以致用。

最大的感受是,尽管HTML5的大部份知识点掌握了,但实现开发中,才发现各种问题,还是要多实际开发。

在线演示地址:http://www.2fz1.com/demo/

源码我就不打包下载了,没有压缩,很简单,直接查看页面源代码吧。

Read more »

在windows下安装seajs打包工具spm及使用方法

具体步聚:

1、访问官方网站下载nodejs windows版并安装,http://nodejs.org/#download

2、windows下,nodejs默认安装目录为:C:\Program Files\nodejs\

3、建议将nodejs目录复制到其它盘的根目录,因为目录中包含的“Program Files”,有空格且较长,在CMD中运行麻烦,需加引号。

比如: 我将nodejs目录移至F盘根目录,并重命名为node,目录更新为:F:\node\

4、进入nodejs安装目录

运行 – cmd – F:(切换到F盘) – cd node(切换到node目录);

5、安装spm

(本步骤,如使用代理上网的方式,请先按下面的方法设置后再运行命令) 执行:npm install spm -g

代理上网的安装方法:

设置代理服务器,比如:npm config set proxy=http://127.0.0.1 我将http://127.0.0.1设置为代理服务器,但http://127.0.0.1没有实际的代理功能,最后只好把所有安装包所需资源下载到127.0.0.1根目录下,最后安装成功。

在windows下,没有后缀名的文件和文件夹名称相同时,命名冲突,需要修改JSON文件中的资源指向其它的目录,所以需要使用以下修改后的安装包进行安装。

spm所需资源及整合下载:http://115.com/file/c2l4d4fo#spm.zip

使用方法:

1、在CDM命令行,切换至需要打包的js文件目录

2、如若需要使用文件合并功能,必须在此文件目录,放置build-config.js

使用合并功能,必须配置app_url

module.exports = {
  "combine_all": true, //合并所有依赖文件
  "base_path": "libs", //基础路径
  "app_url": "http://2fz1.com/js" //使用合并功能,必须配置
};

3、运行 spm build a.js

4、其它命令

压缩并合并一个依赖文件 spm build a.js –combine

压缩并合并所有依赖文件 spm build a.js –combine_all

删除所有已生成的文件: spm build –clear

查找所有参数帮助 spm help build

Read more »

html5 canvas线宽(lineWidth)引起的坐标不准问题

线宽API:

context.lineWidth[=value] //返回或设置线段的线宽,非大于0的值被忽略;默认值为1.0;

线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。

想要获得精确的线条,必须对线条是如何描绘出来的有所理解。见下图,用网格来代表 canvas 的坐标格,每一格对应屏幕上一个像素点。在第一个图中,填充了 (2,1) 至 (5,5) 的矩形,整个区域的边界刚好落在像素边缘上,这样就可以得到的矩形有着清晰的边缘。

如果你想要绘制一条从 (3,1) 到 (3,5),宽度是 1.0 的线条,你会得到像第二幅图一样的结果。实际填充区域(深蓝色部分)仅仅延伸至路径两旁各一半像素。而这半个像素又会以近似的方式进行渲染,这意味着那些像素只是部分着色,结果就是以实际笔触颜色一半色调的颜色来填充整个区域(浅蓝和深蓝的部分)。

要解决这个问题,你必须对路径施以更加精确的控制。已知粗 1.0 的线条会在路径两边各延伸半像素,那么像第三幅图那样绘制从 (3.5,1) 到 (3.5,5) 的线条,其边缘正好落在像素边界,填充出来就是准确的宽为 1.0 的线条。

对于那些宽度为偶数的线条,每一边的像素数都是整数,那么你想要其路径是落在像素点之间 (如那从 (3,1) 到 (3,5)) 而不是在像素点的中间。如果不是的话,端点上同样会出现半渲染的像素点。

Read more »

Function中的扩展方法bind()

js bind 函数 使用闭包保存执行上下文

bind()主要具有两个重要作用:

(1)一般地,方法中的this关键字总是指向调用此方法的对象,这就造成this显得很不稳定,而使用bind()方法能够保证无论什么时候调用此方法,this关键字总是指向你所要的对象.

(2)提供两次添加参数的机会.第一次是在使用bind()方法的时候,第二次是调用bind()方法返回的句

prototypejs框架中的实现方式:

Function.prototype.bind = function() {
    var __method = this;
    var args = Array.prototype.slice.call(arguments);//将arguments转换为数组
    var object=args.shift(); //截取第一个
    return function() {
        return __method.apply(object,
             args.concat(Array.prototype.slice.call(arguments))
    );
    }
}

用法实例:

var name = "window";
var obj = {
    name: 'JSON',
    getName: function() {
        alert(this.name);
    }
};
function runFun(fun) {
    fun();
}
var getName2 = obj.getName.bind(obj);
runFun(obj.getName); //window
runFun(getName2); //JSON

Read more »

通过匿名函数实现JS的代码封装(类封装)

JS没有严格的类似JAVA的类概念,但可以通过原型链实现类。

通常意义上,推荐使用在构造函数中接受属性值,在原型链上注册方法属性。详情可参考《JavaScript高级程序设计(第2版)》

类似以下代码:

var myClass = function(a, b, c){
    this.a = a;
    this.b = b;
    this.c = c;
    // 构造函数
}

myClass.prototype = {
    f1: function(){alert(this.a);},
    f2: function(){alert(this.b);},
    f2: function(){alert(this.c);}
    //该类的方法
}
var classA = new myClass(1,2,3);
classA.f1();

匿名函数

顾名思义,匿名函数就是没有实际名字的函数。

大家知道小括号的作用吗?小括号能把我们的表达式组合分块,并且每一块,也就是每一对小括号,都有一个返回值。这个返回值实际上也就是小括号中表达式的返回值。所以,当我们用一对小括号把匿名函数括起来的时候,实际上小括号对返回的,就是一个匿名函数的Function对象。因此,小括号对加上匿名函数就如同有名字的函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会实现普通函数的调用形式。

(function(){alert(“匿名函数”);});

但小括号返回的仅是函数表达式,函数并没有运行起来。要运行函数表达式在后再再加上();

变成 (function(){alert(“匿名函数”);})();

这样就产生了一个困扰,这样写会产生闭包吗?大家都知道闭包对于GC的垃圾回收机制有影响,建议少用闭包。

下面我们就来探讨一下。

以我的理解来说吧。是否应用了闭包特性,必须确定该段代码有没有最重要的要素:未销毁的局部变量。

只能说这种写法有闭包的特性,只否形成闭包,还要看有没有未销毁的局部变量。

匿名函数封装类

(function(){

    var myClass = function(a, b, c){
        this.a = a;
        this.b = b;
        this.c = c;
        // 构造函数
    }

    myClass.prototype = {
        f1: function(){alert(this.a);},
        f2: function(){alert(this.b);},
        f2: function(){alert(this.c);}
        //该类的方法
    }

    window.myClass = myClass;
})();
var classA = new myClass(1,2,3);
var classB = new myClass(10,20,30);
classA.f1();
classB.f1();

其中window.myClass = myClass;这一段,也可以使用return 抛可供调用的API接口。

Read more »

javascript中的几个小技巧及原理

以下的几个小技巧,其实考察的是对JS基础知识的掌握和理解。基础的东西一定要打牢固,才能向使你的编码能力有台阶性的上升。

1、简短取当前时间戳。

普通青年的做法:

var time = new Date().getTime();

文艺青年的做法:

var time = (+(new Date));
//或
var time = +(new Date);

效果是一样的,但是文艺青年的做法,明显优雅一些,不过可读性视各位的基础而定。

原理:

大家知道小括号的作用吗?小括号能把我们的表达式组合分块,并且每一块,也就是每一对小括号,都有一个返回值。(new Date)其实就是返回当前的Date对象。

一元加操作符(+),放在数字前面,对数值不会产生任何影响。但放在非数值类型的前面,相当于Number()转型函数。+(new Date)就返回了时间戳数字。但为什么外面还需要一对括号呢,如果用于赋值操作,可有可无,但用于字符串连接操作时,一定要加上。

2、布尔操作符的妙用

判断一个字符串为空 var str = “”;

普通青年的做法:

if(str==''){
    alert("字会串是空的哦!");
}

文艺青年的做法:

if(!str){
    alert("字会串是空的哦!");
}

原理:

逻辑非(!)操作符,放在值前面,无论这个值是什么数据类型,这个操作符都会返回一个布尔型,然后再对其求反。 两个”!!”,实际上就相当于应用Boolean()函数转型。

3、逻辑与操作符(&&)的妙用

a(),和 b(); b的执行需a()返回值为true才能执行,否则不执行。

普通青年的做法:

if(a()){
    b();
}

文艺青年的做法:

a() && b();

原理:

逻辑与属于短路操作,如果第一个操作数能够决定结果,那么不会对第二个操作数进行求值。 当a();返回false时,就注定整个表达式为false,无需运行b();

Read more »

js获取GET参数(简易正则实现方式)

js获取GET参数,比较常用到,一般的实现方式通过截取字符串,我用正则简单的实现了一下,在我目前的项目中基本通用,没有遇到问题。

下接上代码,如果获取的参数不存在时,返回空。

//window.location.href = test.html?uin=1000&skey=523
//window.location.href = test.html#uin=1000&skey=523

function getUrlArgs(_name){
    var url = window.location.href;
    if(new RegExp(".+"+_name+"=([^&]+).*","gi").test(url)){
        return RegExp.$1;
    }else{
        return "";
    }
}
alert(getUrlArgs("uin"));
alert(getUrlArgs("skey"));

Read more »

html5 canvas javascript游戏开发物理引擎box2d-js学习资料

box2作为一个优秀的物理引擎,目前被应用在很多游戏中游戏。什么box2d会被大众接受并得到广泛使用呢,首先给大家介绍一下box2d的优点:

市场的游戏大部分都用C++编写,而box2d的原始版本就是用C++实现的,大家只需下载CPP文件,并把它们加入自己的工程下刚可编译,在引入你创建物理模型头文件的情况下,你就可以实例化可以模拟模型运行的对象和场景了。当然box2d其他语言的用法也大同小意。现在有多种语言实现的box2d,包括C++,Java,javascript,flash,也有iphone版和Android版;在开发游戏过程中,利用此物理引擎开发会比较简单,学会了创建物理世界后,加上相应的物体就可以实现物理模仿。而box2d不仅支持的版本比较多,并且入手比较快,参考其用户手册可以很快的实现基本的物理世界。Box2d一个开源项目有很多专业牛人在维护,还有论坛帮助解答,你同时也可以加入他们的加发中。Box2D 是一个用于游戏的 2D 刚体仿真库。程序员可以在他们的游戏里使用它,它可以使物体的运动更加可信,让世界看起来更具交互性。从游戏的视角来看,物理引擎就是一个程序性动画(proceduralanimation)的系统,而不是由动画师去移动你的物体。你可以让牛顿来做导演。

1、源码及DEMO:

http://code.google.com/p/box2dweb/

2、微软官方的一个DEMO

http://ie.microsoft.com/testdrive/Graphics/CanvasPinball/Default.html

3、初级入门资料:

http://www.linuxgraphics.cn/physics/box2d_js_overview.html

http://box2d-js.sourceforge.net/(英文)

http://directguo.com/blog/index.php/2010/05/box2d_js_tutorials/

4、Box2d官方网站:http://www.box2d.org/

5、Google Demo:

http://mrdoob.com/projects/chromeexperiments/google_gravity/

http://mrdoob.com/projects/chromeexperiments/ball_pool/

Read more »

Node.js中文在线学习资料

还记得10年,为实现一个五子棋的在线对战,查资料查到了node.js,那时只有linux版的,没有任何中文资料。后来工作太忙就放弃学习了。没想到发展的那么快,中文文档比较齐全了,是时候系统学习一下node.js了。

nodejs手册中文版.pdf,下载地址:http://ishare.iask.sina.com.cn/f/21982872.html

nodejs手册在线中文版(Node.js Manual & Documentation):http://cnodejs.org/cman/index.html

Express JS 中文入门指引手册:http://www.csser.com/tools/express-js/express-guide-reference-zh-CN.html

在线学习社区:http://club.cnodejs.org/

Read more »