月份: 2014-03

一位39岁程序员的困惑:知道得越多编程越慢怎么办

Zilk1988 年 14 岁时就开始编程,此后尝试过几种职业,最终还是在 1997 年决定成为职业程序员(又称码农),现在已经 39 岁,对此选择依然无怨无悔。

但是后来他发现一个问题,自己的经验越丰富,完成项目或任务的时间反而越长。因为他见过了太多可能会出问题的情况而对选择踌躇。比方说,假设他刚想到要写一段写入文件的代码时,电光火石之间他就已经开始担心起下面的一系列的问题:权限、锁定、并发、源自操作、迂回 / 框架,不同的文件系统、目录中的文件数、可预测的临时文件名、PRNG(伪随机数生成器)的随机性质量够不够、操作过程中断电怎么办、API 怎么写才好理解、文档应该怎么写等等。

简而言之,他的问题已经从“怎么做”变成了“怎么做最好 / 最安全”。

结果就是他他做出来的版本坚如磐石,但是也导致他完成项目的时间比菜鸟还要长。

Zilk 说,他自己精通算法、热爱数学,享受复杂项目,专注度也没有问题。也许经验是有问题(尽管已经 39 岁了),所有会害怕犯错,因此导致项目费时。所以他在StackExchange上邀请同行帮助他解决这个问题。

下面就是精选出来的解决方案:

Telastyn:
你完成项目并不慢。以前你认为自己的菜鸟项目做完了但实际上并没有完。你应该把质量卖给客户。“公司可以做得更快成本更低,但项目真的完成了吗?或者说你愿意花几年的时间找 bug 吗?”此外,你还应该知道并接受那句老话:“完美是好的敌人。”

sevenseacat:
“好、快、省只能 3 选 2”。以前你懂得少所以牺牲了“好”,现在你懂得多了却牺牲了“快”。

mouviciel:
似乎你的经验的确不足:)。教训:遵守需求即可,不要想其他。这样才不会实现不需要的功能。

Satish:
应考虑敏捷方法论而不是瀑布流。先交付然后迭代交付。此举有助于降低风险和成本。

DXM:
似乎你加入黑暗面:管理的时候到了。
我不是要建议你放弃编程变身经理。但从你的描述来看你的经验仅限于技术层面。写文件这么简单的事情你居然能想到 10 个方面的问题,稚嫩一点的开发者绝对是想不出来的。这不是什么坏事,但是……
黑暗面的一切都与现值有关。它要考虑的是如何用最小的投入实现最大的产出(成本效益分析)。商业上的一切事情都要归结到成本、成功几率、失败几率、潜在回报等问题。做好这方面的数学然后采取相应行动。
哪怕你是开发者也无妨:忽略权限和命名冲突的情况下建个临时文件只需 5 分钟的时间。净收益:团队其他成员可以开始依赖此文件的代码编写工作。这是不是一个完美的解决方案?当然不是。99% 呢?95%?90%?这些可能性是存在的。
还要问你一个问题:你对技术债务(注:快速解决但会增长后续维护成本的做法)感觉如何?有人认为不应该有技术债务。我不同意。跟商业一样,技术债务让你可以借到“金钱”和“时间”以便晚点交付某样东西。2 年做出一个完美解决方案,或者用 4 个月时间快刀斩乱麻作出客户可以使用并且购买的东西,哪一个更好?判断当然要因情况而定,但是大多数情况下如果你要让客户等两年的话,客户可能早就跟竞争对手签约了。
关键是像管理商业债务一样管理好你的技术债务。借的钱不够的话就拿不到最佳的投资回报。但是负债太高的话利息会把你压垮。
我的建议是用番茄工作法。专注于小的时间间隔(番茄),然后为未来的工作 / 研究分配这些时间段,并且在执行的过程中不断根据事情的优先级进行调整。

Saul:
编程的一个关键是管理并控制好复杂性,这是我的最高优先级之一。忽略了复杂性管理,要么缺陷频发,要么软件的 ETA(预计到达时间)急剧增加。
软件复杂性有很多不同的管理层次和办法,好的做法可以是这样的:“任何软件项目的最高优先都是客户满意度,这是客户期望的函数。”
换言之,软件复杂性取决于你控制客户期望的水平如何。
如果你接受这个观点,那么下面两点也很显然:
客户期望必须明示
客户期望永远都可以改变且通过协商完成。
你举了一个很好的例子,“直接写”还是“无数的其他考虑”。考虑一下,如果有人详尽写下了此二者的需求,双方的功能描述还是一样的吗?
同样是造飞机,F16 能飞,航模也能飞,但那能一样吗?

本来我打算把所有建议都摘录出来的,但是考虑到上述的精彩见解足以解决 Zilk 的困惑,并且为了践行这些建议,本文就此打住,感兴趣者可参见完整讨论。

最后我只补充一句:
你还可以看看麦当劳理论。

JS获取当前时间戳的方法-JavaScript 获取当前时间戳

JavaScript 获取当前时间戳
第一种方法:

var timestamp =Date.parse(new Date());

结果:1280977330000
第二种方法:

var timestamp =(newDate()).valueOf();

结果:1280977330748

第三种方法:

var timestamp=newDate().getTime();

结果:1280977330748

第一种:获取的时间戳是把毫秒改成000显示,

第二种和第三种是获取了当前毫秒的时间戳。

JS的trim()方法,js去首尾空格

js去空格,js中本身没有trim函数。无法像其他程序语言使用trim、ltrim 或 rtrim取出空格。因为在js中却没有这3个内置方法,所以需要手工编写。

下面的实现方法是用到了正则表达式,效率不错,并把这三个方法加入String对象的内置方法中去。

  写成类的方法格式如下:(str.trim();)

  <script language="javascript">
   String.prototype.trim=function(){
      return this.replace(/(^\s*)|(\s*$)/g, "");
   }
   String.prototype.ltrim=function(){
      return this.replace(/(^\s*)/g,"");
   }
   String.prototype.rtrim=function(){
      return this.replace(/(\s*$)/g,"");
   }
  </script>

  写成函数可以这样:(trim(str))

  <script type="text/javascript">
   function trim(str){ //删除左右两端的空格
       return str.replace(/(^\s*)|(\s*$)/g, "");
   }
   function ltrim(str){ //删除左边的空格
       return str.replace(/(^\s*)/g,"");
   }
   function rtrim(str){ //删除右边的空格
       return str.replace(/(\s*$)/g,"");
   }
  </script>

jquery select 获取,添加,设置

每一次操作select的时候,总是要出来翻一下资料,不如自己总结一下,以后就翻这里了。

比如<select class=”selector”></select>

1、设置value为pxx的项选中

 $(".selector").val("pxx");

2、设置text为pxx的项选中    

$(".selector").find("option[text='pxx']").attr("selected",true);

这里有一个中括号的用法,中括号里的等号的前面是属性名称,不用加引号。很多时候,中括号的运用可以使得逻辑变得很简单。

3、获取当前选中项的value

$(".selector").val();

4、获取当前选中项的text

$(".selector").find("option:selected").text();

这里用到了冒号,掌握它的用法并举一反三也会让代码变得简洁。

 

很多时候用到select的级联,即第二个select的值随着第一个select选中的值变化。这在jquery中是非常简单的。

如:

$(".selector1").change(function(){
     // 先清空第二个
      $(".selector2").empty();

     // 实际的应用中,这里的option一般都是用循环生成多个了
      var option = $("<option>").val(1).text("pxx");
      $(".selector2").append(option);

});

 jQuery获取Select选择的Text和Value:
      1. var checkText=jQuery(“#select_id”).find(“option:selected”).text();   //获取Select选择的Text

      2. var checkValue=jQuery(“#select_id”).val();   //获取Select选择的option Value

      3. var checkIndex=jQuery(“#select_id “).get(0).selectedIndex;   //获取Select选择的索引值

      4. var maxIndex=jQuery(“#select_id option:last”).attr(“index”);   //获取Select最大的索引值

jQuery添加/删除Select的Option项:

      1. jQuery(“#select_id”).append(“<option value=’Value’>Text</option>”);   //为Select追加一个Option(下拉项)

      2. jQuery(“#select_id”).prepend(“<option value=’0′>请选择</option>”);   //为Select插入一个Option(第一个位置)

      3. jQuery(“#select_id option:last”).remove();   //删除Select中索引值最大Option(最后一个)

      4. jQuery(“#select_id option[index=’0′]”).remove();   //删除Select中索引值为0的Option(第一个)

      5. jQuery(“#select_id option[value=’3′]”).remove();   //删除Select中Value=’3’的Option

      6. jQuery(“#select_id option[text=’4′]”).remove();   //删除Select中Text=’4’的Option

内容清空:

      jQuery(“#select_id”).empty();

第三方js的api接口获取用户ip地址以及所在城市信息

第三方js的api接口获取用户ip地址以及所在城市信息
利用第三方的api js 接口就可以获取用户的ip地址以及所在城市

新浪的IP查询接口:
新浪的:http://counter.sina.com.cn/ip?ip=IP地址
返回Js数据,感觉不是很精确,可以把问号后面的去掉,直接返回本机对应的IP所在地
http://counter.sina.com.cn/

太平洋电脑网IP查询接口:
http://whois.pconline.com.cn/?ip=0.0.0.0
把0.0.0.0换成IP地址,页面上还有其他无关内容,这些内容是告诉我们哪些接口可以调用、接口调用参数和使用方法等

通过上边的js接口调用就可以判断用于属于哪个城市,直接显示该城市的相关信息了,对于需要城市切换的网站,首次判断用户来源非常有帮助。

ps:个人感觉太平洋的这个准确。

JavaScript模板引擎Arttemplate

现在程序开发一般都使用MVC这样的设计开发模式,将数据的输入、处理、输出三步明确的分开,有利于项目开发中的分工与提高开发效率。将M与V分开后,可以将数据输出到各种前端展现方式,在V的层面一系列数据你可以用柱状图表现,也可以用HTML表格表现,V的分离使得死的数据可以被活灵活现的展示给用户,提高用户体验度。至于MVC的模式的优缺点,不是此文的目的,就不多叙了。

前端展示的多样化,加大了前端开发人员的工作量,也对前端开发人员的能力有了更多的要求,但使用“模板引擎”一定程度上帮助前端开发人员使用自己熟悉的标签语言就能达到开发要求。

一般的web开发要使用和后台开发程序配合的模板引擎,但随着用户体验的更高追求,页面无刷新或部分刷新的ajax被广泛应用后,js发送ajax请求回来的数据格越来越多,这些数据返回后一般都使用简洁的json格式,节约流量和提高效率,但json并不能直接在页面展示,而要通过js再转换拼装成html代码,将json这类的数据转换成html代码输出的这个过程就是本文要说的正题了。

Arttemplate 超快的前端模板引擎

artTemplate 新一代 javascript 模板引擎

artTemplate 是新一代 javascript 模板引擎,它在 v8 中的渲染效率可接近 javascript 性能极限,在 chrome 下渲染效率测试中分别是知名引擎 Mustache 与 micro tmpl 的 25 、 32 倍(性能测试)。

引擎支持调试。若渲染中遇到错误,调试器可精确定位到产生异常的模板语句,解决前端模板难以调试的问题(详情)。

另外,artTemplate 的模板还支持使用自动化工具预编译,支持将模板转换为 js 文件。

官方网站:

http://aui.github.io/artTemplate/

相关网站:

http://cdc.tencent.com/?p=5723

https://github.com/aui/artTemplate

微擎(we7)0.5版本反应特别慢解决方法

最近一段时间使用微擎0.5版本的时候发现。不知为什么现在反应特别慢,微信关键词回复需要 多次才有反应。

同服务器其他程序速度很快!自己手写的微信回复程序反映也很快 就we7关键词或点击自定义菜单慢。

果然断定不是微信的问题。是微擎的问题。

后来找了很多方法。无意间在一片文章中找到了 微擎0.5版本反应特别慢解决方法。试了一下果然成功。

其实就是一个小函数的问题。

解决方法

用dw在微擎目录下查找

sort($signkey);

全部替换为

sort($signkey,SORT_STRING);

sort函数是为数组排序的。两个就是差了一个参数 “SORT_STRING” 速度上就有很大的差别。

后来查阅了一下 

定义和用法

sort() 函数按升序对给定数组的值排序。

注释:本函数为数组中的单元赋予新的键名。原有的键名将被删除。

如果成功则返回 TRUE,否则返回 FALSE。

语法

sort(array,sorttype);
参数 描述
array 必需。输入的数组。
sorttype

可选。规定如何排列数组的值。可能的值:

  • SORT_REGULAR – 默认。以它们原来的类型进行处理(不改变类型)。
  • SORT_NUMERIC – 把值作为数字来处理
  • SORT_STRING – 把值作为字符串来处理
  • SORT_LOCALE_STRING – 把值作为字符串来处理,基于本地设置*。

Js动态添加与删除Option对象

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>JS动态添加删除option</title>
<script>
//动态删除select中的所有options:
function delAllOptions(){
      document.getElementById("user_dm").options.length=0; 
}

//动态删除select中的某一项option: 
function delOneOption(indx){
      document.getElementById("user_dm").options.remove(indx); 
}

// 动态添加select中的项option: 
function addOneOption(){
      //document.getElementById("user_dm").options.add(new Option(2,"mytest")); 
   
   var selectObj=document.getElementById("user_dm");
   alert(selectObj.length);
   selectObj.options[selectObj.length] = new Option("mytest", "2");
}
</script> 
</head>
<body> 
<select id="user_dm" name="user_dm">
<option value="0" selecte>==请选择人员==</option>
<option value="1">test</option>
</select><br>
<input type="button" onClick="addOneOption()" value="添加">
<input type="button" onClick="delOneOption(1)" value="删除第一个">
<input type="button" onClick="delAllOptions()" value="清空">
</body>
</html> 

———————–

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Js动态添加与删除Option对象</TITLE>
<script language="JavaScript">
// 添加选项
function addOption(pos){
var objSelect=document.getElementById("mySelect");
    // 取得字段值
   //var strName = document.myForm.myOptionName.value;
    // var strValue = document.myForm.myOptionValue.value;
    // 建立Option对象
    var objOption = new Option("aaaaaaaa","bbbbbbbbb");
    if (pos == -1 & pos > objSelect.options.length) 
       objSelect.options[objSelect.options.length] = objOption;
    else
       objSelect.add(objOption, pos);
}


// 删除
function deleteOption(type){
var objSelect=document.getElementById("mySelect");
    if (type == true)
       objSelect.options[objSelect.selectedIndex] = null;
    else
       objSelect.remove(objSelect.selectedIndex);
}
// 显示选项信息
function showOption(){
var objSelect=document.getElementById("mySelect");
    var name = objSelect.options[objSelect.selectedIndex].text;
    var value = objSelect.options[objSelect.selectedIndex].value;
    alert(name + " = " + value);
}

//动态删除select中的所有options:
function clearAllOptions(){
   var objSelect=document.getElementById("mySelect");
   objSelect.options.length=0; 
}
</script>
</HEAD>
<BODY>
<h2>Js动态添加与删除Option对象</h2>
<hr>

<select id="mySelect" name="mySelect">
<option value="中国" Selected>中国</option>
<option value="日本">日本</option>
<option value="美国">美国</option>
</select>
<input type="button" onclick="showOption(this.form)" value="显示">
<input type="button" onclick="deleteOption(true)" value="删除">
<input type="button" onclick="deleteOption(false)" value="Remove方法"><br><br>
选项名称 : <input type="text" name="myOptionName" value="英国"><br>
选项的值 : <input type="text" name="myOptionValue" value="value4">
<input type="button" onclick="addOption(-1)" value="添加">
<input type="button" onclick="addOption(0)" value="插入到最前面">
<input type="button" onclick="clearAllOptions()" value="清空">
</BODY>
</HTML>