review前端代码的一些心得

  1. js的函数声明和实现写在一起,不方便review。写代码时应该在格式上注意。seajs模块对外暴露的接口是一个不错的放声明的地方
  2. 模块内部函数,应该直接用function来定义,不要绑定到特定对象上,方便review。这些function纯粹是功能性的、面向过程的,仅仅用来内部查看,不需要绑定到对象上,也不需要暴露出去。

// 后面接着更新。。。

knockoutjs初探——MVVM框架

Backbone, ember, knockout算是比较火的三个前端MV*框架,受到Knockout.js vs Backbone.js文章的蛊惑,我决定尝试一下knockout。文中称Backbone的优势在于,对Rest接口的后台进行了一个很好的model,也就是说是一个不错的ORM(这个比喻让写过后台的人秒懂啊有木有!),而对于DOM操作,这种属于controler范围的东西,Backbone没有一个集中编写的位置,也没有提供任何方便,你需要自己用jquery去操纵。因此,Backbone非常_“灵活”_。

继续Knockout。Knockout有个牛逼的在线教程,灰常有用。

Textarea和p

在前端实现MVC框架都有一个问题,View可能会接受大量用户输入,并进行改变。

Knockout对input类型和p类型都可以进行model的绑定,

<p data-bind="text: question"></p>
<select data-bind="options: [1,2,3,4,5], value: points"></select>

这里就是对p元素绑定text类型的变量question。question是在js中的ViewModel中定义的,具体绑定细节就请移步教程~ question是一个observable

question = ko.observable("Are you hungry?")

当需要改变question的值时,使用

question("Are you happy?") //change value
question()    //read value

让人想起来setters和getters啊。question的值一旦改变,所有data-bind相关的view都会改变。

text这个类型,很明显是一个文档值类型,我们可以相见,还会有html类型用来直接传入html。Knockout的模板当然不止提供这些,还提供例如:foreach(循环block内部的内容),visible(满足条件才可视),click等等。例如:

<h3 data-bind="visible: value() > 3 ">value居然大于3了</h3>

只有当value()的值大于3的时候才会显示h3的内容

<button href="#” data-bind="enable: value()>3, click: onclick"></button>

相当于绑定了一个回调函数。

显然,你也可以自定义,这个成为bindingHandlers。

bindingHandlers的init和update

bingingHandler的定义如下:

ko.bindingHandlers.yourhandler = {
    init: function(element, accessValue){},
    update: function(element, accessValue){}
}

update很好理解,当元素内容发生改变的时候,通过选中$(element),利用accessValue()里的值进行操作。这个accessValue就是html中跟在visible或者text或者yourhandler后面的值,需要通过accessValue()调用返回。

init是什么的?一般需要自定义handler是希望实现一些动画,但是,如果只有update,当页面第一次加载的时候,只能执行update中的例如,fadeOut()动画,于是,页面就相当于闪了一下,多不和谐。于是,你可以自定义init来改变handler第一次加载时的行为。

真贴心啊!

于是,你就可以这样写了。

<p data-bind="yourhandler: value"></p>

init在页面加载的时候只执行一次,这意味着!可以在里面再另外写一些辅助性的绑定哦~~~

//...    
$(element).hover(function(){}, function(){})
$("span", element).each(function(){ $(this).addClass('span'); })
//...

Viewport & media query in design for mobile

Responsive design is undoubtly the trend to design a website for both big screen and mobile screen. The magic lies on the media query in CSS.

What media query do?

It query how the screen or device that presenting the web page looks like. For example, how long is the device width, a 1024px screen or a 640px one.

Like this (in html file):

<link rel="stylesheet" media="screen and (color)" href="example.css" />

or like this (in css file):

@media all and (min-width:500px) { /* your css here */ }

So, you can change your css responsively and respectively as the screen changes.

What viewport do?

Another relative technique is the viewport. It is created by Safari and can hardly be a standard. But it is there to be used. When a mobile device render a traditional web page in a little screen, to avoid using a narrow width to make the page looks weird (for those has never been developed to fit mobile screens), the browser use a larger screen, say, 980px, to render the page. Then the browser zooms out to fit the content to the 320px screen. If you don’t want your site be zoomed out, you can use this:

<meta name="viewport" content="width=device-width">

Then, the web page is rendered as a device-width browser, it will look like a narrowed desktop browser by dragging.

No picture means nothing (No pic you say a jb)

fixed, device-width viewport

fixed, default viewport

flexible, device-width viewport

flexible, default viewport

So what?

With device-width viewport, at least your font-size would be as normal and clear to read. If you use flexible or fixed design in your website only, you should not modify the viewport, for that users would zoom in & out to read your content, while your layout wouldn’t go weird.

Anything to do with media query?

Of course! If you use media query to use defferent css in defferent screen-size, you would absolutely get the best and optimized effect of your sites. But that would be quite a lot of work.

For more reference, check out here:

Media Queries, W3C Recommendation 19 June 2012

Using the viewport meta tag to control layout on mobile browsers

坑爹的viewport

seajs配置alias找模块

seajs的模块可以通过seajs.config来设置别名

seajs.config({
    alias: {
      'app': 'http://path/to/app',
      'json': 'json/1.0.1/json',
      'jquery': 'jquery/1.7.2/jquery'
    }
})

但是,我在配置本地应用别名的时候,总是出错,后来直接跑了一趟支付宝= =b
总算找到问题,我的配置如下:

alias{
    'a':'./assets/a/src/a'
}

在alias中,必须配置绝对路径,或者配置类似于例子中,相对于sea-modules的路径,不能使用其他方式的相对路径:)
感觉这个也算是看文档不仔细把,

'app': 'http://path/to/app',

这一句隐含的含义是,用绝对路径~哈哈

Decode escaped HTML in JavaScript

My co-worker escapes all the data sent to the backend using a Java tool. The characters are converted into something like &#12345; which means its original unicode in decimal. Meanwhile, html character entities are used when escaping so that the character like “<” will be &lt; .

Frontend should not only decode the string transmitted back but also convert the string into JSON objects. lazily I choose the tricky way to unescape the string, like this:

function getJson(data){
    return $.parseJSON($('

').html(data).text());
}

But I find this code sometimes doesn’t work and it seems the the data has been cut off in some place which misleading me thinking some sort of memory leaking.

I tried and tried, and with the help of JSON Lint, I found that the problem laid on the character .

In the approach above, the data is converted into characters which means the &quot has been converted into , but the json string returned use in its format! So, it is the that cut off the string!

Then, I wrote something like this:
(Thanks to Convert HTML Character Entities back to regular text using javascript)

function u2text(text){
    var $p = $('

');
    return text.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);?/gi, function($0, $1) {
        if ($1[0] === "#") {
            return String.fromCharCode($1[1].toLowerCase() === "x" ? parseInt($1.substr(2), 16) : parseInt($1.substr(1), 10));
        } else {
            return $p.html($0).text().replace(/"/g, "\\u0022");
        }
    });
}

In this code the Chinese character in unicode will be converted using the String.fromCharCode, while the html character entities will be decoded using the <p> block scheme, and obviously, quotes are treated differently. Be cautious that the quote character should be converted into “\u0022”. If you use “\u0022”, you change nothing.

After all, the decoding is dangerous for the escaping text has been decoded. In my situation the escaping stuff will be handed over to front-end template system, say Dust.js, which will take very good care of the security problems.

邮件入门手册

电子邮件算是互联网最古老的应用了,已经形成了礼仪甚至文化。不过在谈到礼仪之前,还是要先谈用法。国内由于qq强大的地位,以至于邮件的使用场合很多都被qq取代了,所以一部分童鞋很少使用邮件,也就不怎么会使用邮件。然而IM终究还是不能取代邮件,就像社交网络不能取代IM一样。最近国外有些新产品让邮件更易用,更像一款社交产品,算是历史的进步吧~:) 不过在更易用的邮件到来之前,先看看老古董要如何使用吧。

邮件的好处

先看邮件比IM优势的地方。

1. 自己不需要马上回复

多好的一件事啊!作为程序员,总算不需要总是被qq的提醒打断自己的思路了。我可以选择一个合适的时间,想清楚,然后再回复邮件。而不需要直接应付对方qq上发来一个问题,然后讨论来讨论区,窗口关掉了,之前在干什么也忘记了。打断是效率的大敌,为什么程序员喜欢晚上干活?因为不会有人打扰。不过我还是希望有规律的作息时间的,所以,最好白天不要打扰我,除非事情非常紧急,一般情况下给我发邮件吧~

2. 不要求对方马上回复

同理,我要找某人某件事,如果用qq或者电话,会直接打断他手头的工作,也许一个绝妙的idea就此消失了,多不好意思!于是我选择给他发一封邮件,他有时间就会来看一下,并回复我,于是我的心理就踏实多了。这样也十分礼貌。在qq上抖人是多么一件令人发指的事啊!

3. 历史记录可查,附件不会丢失

qq不提供服务器端的历史记录。也就是说我用手机就看不到历史记录了,而且qq的历史记录不方便搜索,注意是不方便,不方便是一件很可怕的事,比不能还可怕。邮件的记录是可以很容易的搜索的,这样我想起来什么东西,直接在邮件界面的搜索框搜索就好了,不需要找到那个人的头像,点开聊天记录,点击搜索,或者向前不断的翻页。
另外,很多人喜欢在qq上抖一下,然后对我说,给你传一个文件。我承认qq的发送文件、离线文件做的用户体验很好,但我接受到文件之后,常常过一阵子找不到那个文件了。我可以在操作系统中搜索,哦天哪,慢的要命,还需要找一些其他的工具才足够方便。如果用邮件的附件呢?我可以直接搜索附件,然后重新下载一次。那个文件永远在那里不会丢失,而我也可以看完附件之后就删掉,免的电脑里的文件乱七八糟。
除此之外,我可以轻易的把这个文件转发出去,这样其他人也变的很容易获得这个文件了。

4. 写邮件鼓励深度思考,想好了再说

qq上常常出现冗长的对话,说一句话,解释好多句,于是因为说的人没想清楚,听的人也被迫花同样的时间来等待对方把事情说清楚。当然用来交流感情挺不错,但是涉及到协作和效率,这时候发邮件就效率的多。说的人可以把事情从前到后想清楚在发出来,听的人一眼就看明白了,然后经过一番思考再回复过去。因为这一切都不是实时的,给了人更多的自由和空间。

邮件的基本使用

说了这么多好处,我想你一定打算改变你凡事都qq的习惯了。下面有一些基本技巧,或许你还不了解。

1. 抄送

什么是抄送!?我从前也一直不理解这个问题。直到我去实习,才深深体会到抄送的意义所在。我打算给A发送一个邮件,希望A回复我,可是A偏偏觉得我是一个实习生,爱理不理的,于是我就把发送给A的邮件抄送一份给他的主管B。主管B会收到这封邮件,同时也会看到收件人是A,抄送意味着B只需要看一眼这封邮件就好了,应该由A来处理。这时候B发现A居然偷懒没有处理这封邮件,于是他就回复邮件:请A尽快处理!然后我的事就给办了。
多微妙的一个功能啊!当然上面只是举了一个比较极端的例子。一般来说,收件人是希望对方回复这封邮件,或采取行动,而抄送的人则是让你看一眼,我们在谈论这件事,你也可以参与进来,或者直接删掉这封邮件。这样区分一下,邮件就会更有针对性。
Web邮件端在渐渐淡化这个功能,因为对于普通用户一般用不着,但如果打算用gmail来协同办公,这个概念还是比较重要的,在邮件的详细信息栏可以看到。

2. 过滤器

我常常看到童鞋的收件箱里塞了100多封未读邮件,然后觉得他居然可以活到现在,我还在给他发邮件,太牛逼了。事实上,各大邮箱都考虑到这个问题,并提供过滤器。你可以在设置里找到过滤器,并设置来自某个地址的邮件放置到某个文件夹,或者打上某个标签。对于一些不太重要的订阅邮件、广告邮件,可以选择跳过收件箱,这样有闲情逸致就去看看那个文件夹下是不是有新邮件了,忙的时候就可以放心的不理会,收件箱也不会被打扰。
过滤器设置的时候可以勾选上“应用到历史邮件”,就会把符合过滤规则的邮件都从收件箱过滤到对应的文件夹。
对于一些每次变换邮件地址的垃圾邮件,过滤器可以设置的更强一些,例如将包含”@some.com”关键词的邮件都过滤掉。很多为了防止spam识别,会不断变换邮件地址,例如从service+1212@some.com下次变成了service+1000@some.com,这样你把前一个邮件地址顾虑了,下一次又不能过滤掉了。所以干脆过滤所有的。

3. 邮件群组和邮件列表

经常需要给很多人发邮件。比较普遍的一种方式是,建立一个google group,然后向群组的邮件地址发送邮件,这样所有人就都可以收到了。邮件列表也可以,就是你在联系人里自己建立一个文件夹之类的东西,然后给这个文件夹下所有人发邮件,这样地址栏会出现很多人的名字。嗯……你说qq群邮件?那玩意不遵循邮件协议,用客户端居然收不到,如果你打算躺在腾讯的温室里过一辈子,就去用吧。不过qq邮箱本身做的还是很不错的,这点不可否认。
邮件列表就会遇到reply和reply to all 的问题。回复邮件如果选择reply,就会回复给发件人,这样其他人都收不到,如果是打算像跟帖一样回复的话,结果恐怕就变成私信了。私信的结果是,两个人发的很high,结果其他人啥都不知道,于是一些信息就莫名其妙miss掉了,这在讨论一些事情问题会很严重。那怎么跟帖呢?就是reply to all。
一般来讲在小团队里reply to all 问题不大,发来发去也就那么一些邮件。团队一大,reply to all就会涉及到一些邮件礼仪的问题了,因为那些你抄送的不想干的人也会被一起卷入到一个大讨论中,收件箱就一直被这个大讨论占据着。所以,回复邮件的时候细心一点,be considerate.

邮件与qq的关系

讨论了半天,我们有qq了,但是我们还是需要邮件,同时,我们也需要qq。因为一些急事emergency,qq还是要来的快一些。所以我整天挂在q上,纵然ubuntu下的web qq用起来有时候让我有砸电脑的冲动。邮件适合需要思考的讨论,IM适合快速的信息交换。要说区别看起来不大,也仅仅是“看起来”不大。为什么不用gtalk?嗯,我的gtalk也是整天在线的,而且gtalk的聊天记录和邮件放在一起,非常方便查找。可惜要说服别人放弃qq是一件很难的事,因为他也要说服他的好友一起放弃,impossible啊。

Jquery Animation’s Synchronization and Nested Animation Using a Counter

Animation In Jquery is quite simple and easy to use. But things come complicated when you want to create a series of animations. Recently I am building an app which heavily relies on the animation, and get really exhausted sereral times. I learn a lot from this.

Animation Sync

Here is what I write at the very beginning.

$('#left').animate({left: '300px'}, 300, function(){
    $('#left #left-node').attr('id', 'center-node');
    $(this).attr('id', 'center');
    //...
});
$('#center').animate({left: '600px'}, 300, function(){
    $('#center #center-node').attr('id', 'right-node');
    $(this).attr('id', 'right');
    //...
});
$('#right').animate({left: '900px'}, 300, function(){$(this).remove();})

Three blocks will move right at the same time. Then left and center block will change their id to fit the new position. Then here comes the problem: although the three animations in different elements seem to finish at the same time, they finish one after another indeed. And I even don’t know which one! So the operations of changing the id will result in a mess. Needless to say other animation I want to do after.

I need a function that can be called after all these animations finish. I resort to the Queue in the Jquery but find the queue is binding to a particular element. Then a school mate tells me to use a counter and a shared callback to synchronize the animation. That’s quite a good idea. Then the code will be like this.

var sync = 3;
function callback(){
    if(--sync > 0) return;
    //...
}
$('#left').animate({left: '300px'}, 300, callback);
$('#center').animate({left: '600px'}, 300,callback);
$('#right').animate({left: '900px'}, 300, callback);

Nested Animation

As I dynamically generate the html, so I want to make the animation more beautiful. So I write this.

//...generate the html
$("#left-node .node, #center-node .node").hide().fadeIn(300, function(){
    $("#left-node").animate({left: '300px'}, 300);
    $("#center-node").animate({left: '600px'}, 300);
});

I want all the nodes to fade in and after that move the right position. Then the disaster occurred. Since the $() selector has selected more than one element, so the callback will be triggered more than once! Say 15 nodes have been selected, the left-node and the center-node will animate for 15 times! And the default animation queue in both element will function, that is to say, they will animate for 15*300 = 4500 ms. The worst part is, if any event trigger other animation on the two element, the upcoming animation will be held up till the repeated animation finish. The users will see a blocked response in their eyes.
This can also be fixed by the counter mentioned above.

var $nodes = $("#left-node .node, #center-node .node");
var sync = $nodes.size();
$nodes.hide().fadeIn(300, function(){
    if(--sync > 0) return;
    //... further animation
});

OK! All animations go as expected now. But this is really a hard work for a novice of JavaScript like me.

Well, maybe the best way to avoid these complicated cases is not to design so many animations in your web page.

UMD 互联网开发模型(基于REST)

前言

最近一直在做Web前端开发,学习js,写着写着,发现越来越像之前做过的android开发了。这倒不是说我把js当成java来写了,而是从一些基本思路上来看,互联网产品都或多或少有着相似之处。当然,都是基于REST风格的前后台交互,统一,简单。在这里总结成模型。外国人也常常提出各种模型,主要是方便理清思路,所用到的概念和技术不一定是新提出来的,而UMD模型提到的技术则更是毫无新意可言,如果你是Web开发老手,就不太需要了,我想你心中一定有自己的一套模型。这个模型可能更多是帮助新手认识互联网开发的所需考虑的各个方面。

假设:

用户使用 Web app是希望通过一系列交互来提供或找到某些信息

这个假设很多情况下都成立,因为其实啥都没说。不过游戏能不能算Web app呢,看如何理解了。个人没开发过游戏,没发言权,所以暂时不算好了。

UMD: UI, Memory, Database

把假设引申一下就可以得出,整个Web其实就是信息流的交互,因此,我们可以从数据的角度来观察任何一个Web app的架构,数据存在于哪些位置,做怎样的流动,产生怎样的后果。数据一般来说存在于以下位置:

  1. UI 用户界面,数据按照一定格式直接呈现给用户,提供信息
  2. Memory 内存,客户端或者浏览器里暂存的数据,在app生命周期中存在,与UI对应
  3. Database 数据库,存在于网站后台,用于数据的持久化存储,静态的html应该可以包括其中,如果通过资源(resource)这个词来描述可能更适合。
  4. Cache 缓存,缓存可能存在于客户端的本地数据库或者后台的数据库中,可选项,其与Memory作用类似,可以用相同的思路讨论,或者成为UMCD模型进一步讨论,这里不多说了。

UMD Consistency and Update

既然我们可以把数据分成三块,这三块数据最基本要保证:一致性。即三部分数据所表达的信息一致,换句话套用一下就是:所见即所得。

因此,三处数据则至少有一下三类方法来更新数据:

  • updateUI()
  • updateMemory()
  • updateDatabase()

这里的update不是指狭义上的CRUD中的update,我们可以看成是一种对数据的操控,包含了CRUD,让这个数据变的更有效,并得到相应的返回。

另一方面,用户界面需要提供用户交互,让用户找到自己想要的东西。因此,在UI上还会至少有一类方法,处理界面上出现的用户交互:

  • handleEvent()

handleEvent()应该不仅包括从网页上进行的交互,用户输入的url,以及在别的网页点击链接进入这个网页,都应该包括其中,不过这部分浏览器替我们做了。从计算机一出生到现在,其做的最基本的一件事应该就是接受input,提供output,这两点在Web app中可以对应成handleEvent()和updateUI(),因此这个模型我想至少不是错误的。有了这四个方法,我们就可以绘制一般的Web app的程序运行模型。

一致性原则告诉我们:

三处数据任何一处的数据更新,另外两处数据都要同时也得到更新。

在图中看起来UI和Database是不能直接通信并互相更新的,Memory起到了一个枢纽的作用。但其实现实的Web开发中,很多时候是没有Memory这一层的,甚至在几年前,认真对待内存中的数据可能都是一件非常滑稽的事,因为那是浏览器要考虑的。但随着Web app的发展,趋势是其越来越像一个客户端,需要有自己的固定的内存分配来存放数据。因此我们讨论的时候就把Memory带上,来强调在实现前台的时候需要考虑Memory。我最近写的代码中就确实需要维护内存中的数据,通过Memory作为桥梁来更新UI数据事实上可以认为或者实现成updateMemory()和updateUI()需要同时被调用。

UMD Realization

模型是用来指导实践的,即在具体的Web app实现场合,我们如何利用这个模型帮助我们理清思路,并完成各个部分的开发。

User Interface

在web app的场合,UI主要由HTML和CSS来呈现,通过JavaScript来动态控制。

  • handleEvent()

Jquery是很经典的事件驱动的Js库,能够很好的绑定事件到回调函数来处理事件。原生的JavaScript当然更是可以绑定事件了,只是写起来很罗嗦,并且有各种兼容性问题。

  • updateUI()

Jquery库也可以进行DOM、CSS操作来更新用户界面,以及各种实用的动画。同时,用JavaScript来控制DOM总是一件从编码到浏览器调用都很不开心的一件事,很容易写的效率很低,相应的,就有一些前端模板出现,例如mustache,写一定的模板之后,mustache能够为你生成相应的html代码。HTML5标准中提供了更多的帮助你改善UI的工具。

根据一致性原则,updateUI()的原因可能是另外两处数据发生了变化,而在模型中,鼓励内存的变化来调用updateUI(),而不是后台的数据返回后直接更新。注意,是鼓励,但不是所有场合。

Memory

Web应用发展到现在,很多应用仍然不需要特别注重存在于内存中的数据,只是单纯的把后台的页面呈现出来就可以了。但随着Web app的复杂和功能性越来越强,在内存中存储数据能够有效降低网络请求数量和页面响应速度。HTML5中规定了一些在浏览器端的数据存储功能,解决问题的思路和放在内存中类似,在处理大量数据的场合更适合。

内存中的数据内容一般是UI中呈现数据在内存中的映射,首要问题是数据结构,数据如何进行存储,Js中提供的object普通对象和function函数对象能够用一种很简单、基本的结构来存储数据:键值对和数组的集合。这个也可以在JSON的数据格式和object literal的声明方式来得到体现。即

{

    key: value,

    key_array: [v1, v2, …],

    key_obj: { obj_key: obj_value},

}

考虑将数据和业务逻辑分开是一种符合趋势的思路。显式、明确的考虑updateMemory()函数能够让人对数据把握的更清楚,特别是在Js这种灵活性太高的语言中,也使得代码更容易维护。虽然Js的函数式语言特性让内存中的数据可以封装在各种函数的闭包中,但没有组织的零散数据的可维护性不太好,虽然写起来很快。

updateMemory()方法的调用者可能来自UI或者后台数据库,既然Memory是一个信息的桥梁,那么Memory既然是数据的集中地。例如用户输入的handleEvent()需要修改内存中的数据,而后台数据更新后的返回,也需要修改内存中的数据,或者至少看看内存中数据是不是已经过时了。

Database

后台的数据一般都存在数据库中,辅以文件系统。使用REST风格的结果是,统一认定后台的数据位资源,后台所要做的就是接受前台的请求并CRUD特定的资源。对于前台来说,后台就是一个黑盒子,只有提供API接口和数据协议来交互。REST风格的API接口其实就是一段特定的URL,数据协议基本上通过JSON格式规定,从而保证简单、易用。

updateDatabase()的调用者一般来说是Memory,即当Memory需要发生改变的时候,去改变后台的数据。不过Web程序中很多时候不用涉及到Memory,所以也可能是直接的用户事件调用的,例如提交一个表单。

在ajax大量广泛的如今,很多时候连表单和上传文件都希望能够异步实现,提升用户体验。异步通信的好处就在于,可以很快的响应用户界面而不必等待后台的操作完成。但是与此同时,这将可能产生UI、Memory两者和Database的数据不一致。在后台操作完成之后,及时的updateMemory()并通过其updateUI()是很有必要的,特别是当后台操作失败的时候,需要及时修正Memory中的数据,并提示用户。

结语

暂且写成这样吧,主要解释了三种数据:UI、Memory和Database,以及相应的四种方法:updateUI(), updateMemory();updateDatabase和handleEvent()。具体实现的时候,脑袋里带着这几样东西去写东西,应该比啥都不想一个事件一个事件的去写来的高效,鲁棒性强。不过我个人写前端也没多久,后台也只用django写过一个学期,认识或许还不是很到位。接着code一阵子,看需不需要把这个模型弄成前端框架啥的。模型中所有的概念现有的框架和语言都已经够用了,只是不是那么明确而已。

互联网创业是什么

记忆中先是青年导师李开复先生鼓动年轻人创业,找到自己的梦想,创新工厂就这样呼啦啦的起来了。然后36kr、车库咖啡等一系列创业辅助服务,以及淹没了互联网的创业大讨论,让人觉得仿佛一夜之间,创业变成了一件多么简单的事,只要认真去追逐,就能够实现自己的梦想。于是,我还真的能在周围看见冲动型的创业者,当然也有很多让我备受感动和尊敬的严肃的创业者。这时候李先生又开始担心自己一不小心误导了一代大学生,开始劝大家,要创业,还是先参与创业比较靠谱。话说的真心没错,但一想到他先忽悠人创业,又让人先参与创业,然后自己再弄一个孵化器给里面创业团队招人,未免有点,额,我小人了。不扯了,写点自己的看法。

创业不是点子

点子不值钱,貌似关注互联网创业都已经被灌输过了,大量的人教导我们点子不重要,重要的在于你能否把这个点子实现了。所以出现了很多创业者找技术co-founder,这一般会很困难,因为技术男也觉得自己有一身技术,凭啥要听你的,我自己也有想法,还可以c2c。很多人对点子守口如瓶,生怕别人知道,担心被知道而抄袭。只是在70亿人口的地球上,这种想法未免太自大,因为很多人也都想过这个idea。我有冒出过很多idea,一些有人在做,一些曾经做失败了,一些时机还没到。问题在于,这个idea之所以还没出现成功的产品,是因为什么呢?我能做到前人做不到的嘛?这样来看,还不如把idea多问问周围的同学,集中一下众人的智慧。

创业不是写代码

程序员最容易的一个冲动就是觉得自己能够实现一切,我能把点子写成网站,我可以开始创业了!貌似看《社交网络》很容易给程序员形成一种错觉,只要像扎克伯格一样闷着头写三个月代码,然后就牛逼了。Napster的创始人肖恩帕克起到了至关重要的作用,帕克是一个有丰富创业经验的人,有人脉,并和扎克一起开始在全美的大学运营facebook。如果帕克当初没有找到扎克伯格,还真不知道facebook多久才能发展到现在的规模。沃兹和乔布斯也一样,如果没有乔布斯的包装,沃兹开发出来的牛逼东西,恐怕也只有极客们才用用玩一下。运营让代码成为产品,并让产品真正为用户带来价值。

创业不是运营

网站如果没有运营,就好像生了孩子不去养一样。正如前面提到的,运营对于一个产品来说很关键。但单纯的牛逼运营而没有网站功能的支撑,恐怕也只能昙花一现。乔布斯靠其扭曲现实力场,能够让麦金塔在上市时大卖,但由于麦金塔的诸多质量问题,最终导致半年后几乎没法销售,这也导致苹果内部矛盾丛生,以及最红老乔被苹果赶出公司。啊,那时候还是PC时代。京东其实也是靠烧钱的运营搞起来的,结果服务器屡次崩溃。当然,或许这是传说中的服务器营销。

创业不是数据

如果运营的不错,收到很多良好的用户数据,那这个真的是一笔宝贵的财富,创业者到了这一步,已经很接近成功了。例如facebook挟持了大量用户之间的关系数据,让用户很难转移到其他社交平台,所以google+推出来虽然是要和fb竞争,结果fb不怎担心,倒是让twitter菊花一紧。如果说国外的互联网看重的是服务质量,国内互联网则真看重数量。数据基本上被腾讯、百度、阿里给占完了,这让创业公司运营出来的数据简直九牛一毛。所以腾讯可以毫不费力在产品还在蹒跚学步时弄一个大男孩跟他干上一架,然后就没有然后了。

你还愿意创业嘛

看到这,我想我要表达的意思也很明确了,创业真的不是仅仅写完代码那么简单。有了一个点子,并开始开发,这才是创业开始的第一步,后面还有产品的运营、升级,和对手的竞争,是上面所有一切的集合,还要更多。这些如果都还没有想清楚,或者至少有所考虑,那怎么能就贸然的开始创业呢?

创业需要耗费大量的时间和精力,你是否愿意投入7年时间花在同一项目上?这有时恐怕就更需要创业的核心产品能够有长久的吸引力,能够值得你去奋斗大半生。即使是这样,看着周围的同学拿到了一个10k的offer,自己还在省吃俭用的担心融资被花光,估计也会心里不好受。但还真有很多人这些没搞清楚,就拉着人一起宣称创业,没有钱,技术也没有特殊的专利,idea同时在被很多创业团队做,然后拉着大伙一块交钱开公司——这完全就是把钱往水里砸。

别说我在创业

很多人看我弄了一家公司,就误以为我已经开始创业了。可上面我提到的很多点,我都完全想不清楚,缺乏运营经验,初期资金缺乏,关键在于,我居然还要离开武汉去浙大读研——任何投资人都会被这点吓跑。开设公司的初衷仅仅是为了开发出来的东西能够上线并让其他人用一用,这是被国内监管制度逼的,而且我还和Varkrs’ Lab的成员签了协议,产品属于开发者,不属于公司,投资人如果看到这一点,估计直接转身就走了。还在淘宝的时候,一个我很喜欢的主管劝我说,如果要做,干脆就彻彻底底,撞个头破血流。后来想想,终究还是没有这样的勇气,一方面对自己也不是特别的有信心;另一方面,我实在不愿意把其他人拖下水。他笑话我说这是玩票。嗯,确实是玩票,为了什么?就是看看我上面说的这些到底是怎么一回事,李开复说先要参与创业,其实就是说把创业这件事从头到尾看明白,想清楚。那么我更愿意称我现在的行动为一次尝试,同时,我也愿意将这段经历和Varkrs’ Lab的成员们分享,免得总是在学院里做些永远不会上线的眼子项目,做完了还觉得自己不是程序员。

小谈移动互联网

记得暑假去车库咖啡,一个身材丰腴的大叔问我,小伙子,你有没有想自己创业的想法呀?我说有。哪方面的?互联网。你不打算试试移动互联网嘛?我说现在都在扎堆弄移动互联网,没意思,不过移动端是互联网的标配。颇具喜感的是,我当时确实在写一个移动互联网的应用,给路人网的android客户端。
在我的概念中,互联网和移动互联网两个东西从没有真正的割裂开过,有了互联网,就必然有移动互联网。要搞移动互联网,那也必须得有互联网。或许这是我们这一代人对网络的体验造就的这样的思维定势吧。

那互联网和移动互联网到底有啥区别呢?仔细想了想,或许最大的区别就在于屏幕大小。计算能力、定位功能、网络能力、电池方面的区别,基本上这两年都能解决。至于ipad这个中间产物,我还是先把它当游戏机好了。

大屏幕·互联网

互联网的屏幕一般在12寸以上,终端是电脑。

大屏幕首先意味着你得背个包或者干脆不能拎走。所以既然移动已经很麻烦了,就不介意再给你配个键盘,稍微麻烦一点,但提供更快速方便的输入能力。

第二个显而易见的是,强大的输出能力。大量的信息在上下的翻页中全部展示出来,可以给用户完整、丰富的、可能不想要的内容。信息量大所以对信息的筛选不需要精细,只要一股脑都给用户就行了。

有了强大的输入和输出,大屏幕留给用户进行交互的空间就很大,能够进行复杂用户交互行为,提供一大堆按钮和链接让用户选择,搭配键盘提供快速的输入。

互联网的使用情境大都是在一个地方坐下来,把电脑放在桌子上。当然你也可以躺在沙发上,但你一定不是站着并把电脑悬空放在手上敲键盘。使用情境意味着你会停下来耐心的把一个页面的所有信息看完,进行大量的交互行为,最终从大量的信息中摄取到你想要的。

小屏幕·移动互联网

移动互联网的尺寸在4.3寸以下,一个手可以握住。好像有4.4寸的,我想我得先买一个有大兜的裤子。

小屏幕带来了极大的便携性,从而让移动互联网在硬件的输入输出上捉襟见肘。

更少的信息,更compact的界面,为了不至于让用户看不清楚,还要把字弄的一定大小。所以,呈现给用户的信息一定是细心挑选的,本来就Don’t make me think了,这下用户更不愿意看到冗余的信息。广告什么的,会直接引起用户的反感(当然这是一种让用户付费的方式)。

从输入来看,用户输入文字的速度大大下降,但拍照、声音输入更为便捷,成为主要输入方式。由于触摸并没有想象中的方便(想象手指按住了两个字母,或者一大片范围),用户的交互行为十分受限。

移动端的使用情境大约是碎片时间,公车上、厕所里、排队中,基本是外出的时候。用户每屏幕摄取的信息量很少。移动互联网给了用户随时随地接入互联网的能力,但同时也限制了他们接入到的内容量,也就意味着,最好给用户看他关注的信息。打发无聊时间的应用例如SNS是一种选择,除此之外,用户更希望移动终端是一个瑞士军刀,告诉他们到哪里能做什么,并指导他们如何去做,即辅助用户做其他的事情,而不是让用户停留在互联网上。

写着写着,发现基本没啥新鲜的,我总是擅长把一件很普通的事情讲成大道理,然后自娱自乐。真可怕。以后再更新吧。