forecho 的独立博客

把生命浪费在美好的事物上

2013年给自己的一个胶带

2014年02月06日

2013年发生了很多事。

完成的事情有:

  1. 年后果断的辞职了。
  2. 辞职之前利用周六周末去庐山玩了一躺。
  3. 来深圳了。
  4. 找了一家小公司,被坑了。
  5. 有找了一家公司,公司环境挺好的,但是氛围很差,进去没多久就碰上裁员,继续被坑。
  6. 去了一躺云南,完成了去大理、丽江还有住青旅的心愿。
  7. 回来十一之后找了一家还不错的公司。
  8. 碰到一个志趣相投的同伴。
  9. 把「你丫闭嘴」项目上线了,虽然几乎没人访问。【泪】
  10. 学习 CakePHP 。
  11. 升级了固态硬盘,花了1500左右。
  12. 生日给自己买了一块机械手表。
  13. 生日弟弟送了一块飞利浦的剃须刀。
  14. 买了一个 iPad Air。
  15. 看完了5本书。
  16. 自认为喜欢上了思考。
  17. 开始追《全职猎人》动漫。
  18. 发现一个能让我看得进去书的好方法。
  19. 喜欢上了写作来记录自己的想法。
  20. 喜欢上了Podcast。
  21. 一如既往的对技术的热爱。

成为一流的人才

2014年01月26日

我们经常会听到一句话「不怕神一样的对手,就怕猪一样的队友」,但是你有没有想过这个「猪一样的队友」说的是否是自己呢?

2013年我来深圳找工作的时候,刚开始是抱着「自己工作经验不到2年,希望找个能让自己快速成长的公司」,工作找了很久,每次技术面试都很差,大多数公司都希望找到「一流」的人才,这个是事实。那段时间找工作再到换工作对自己打击很大。

再到后来看到了《乔布斯:遗失的访谈》,这个关于乔布斯访谈的节目,乔布斯的下面几句话对自己感触很大:

能进入这个行业,我感到很幸运
But what I was lucky enough to spend my life in, is like this,
我的成功得益于我发现了许多才华横溢、不甘平庸的人才
and so I built lots of my success of finding these truly gifted people, and not settling for B and C players, really going for A players.
而且我发现只要召集到五个这样的人
And I found something, I found when you get enough A players together, when you go through the incredible work to find you know 5 of these A players,
他们就会喜欢上彼此合作的感觉,前所未有的感觉
they really like working with each other, because they never had a chance to do that before,
他们会不愿再与平庸者合作,只招聘一样优秀的人
and they don’t want to work with B and C players, so they become self-policing, they only want to hire more A players.

和优秀的人工作,你进步很快,最重要的是那种工作的感觉真的是很棒,让你感觉到你不是一个人在战斗,你说的东西他们都能懂,他们说的你也感兴趣,就是这种感觉。之前看的《打造 Facebook》其中有讲到 Facebook 也是只招一流的人才。我这才恍悟过来,把自己变成一流的人才是一件多么紧急的事情啊,有更好的人才,公司为什么要选你?有现成的人才,为什么要花时间来培养你呢?

之前老是抱着「我技术不好,但是我对工资要求也不高;能让我去大公司,提高技术,甚至不高工资,管饭就行」这样糟糕的想法。公司招来一个菜鸟,让你弄一个东西,一两个月还搞不出来,那是在浪费他们的时间,对他们来说少给你的工资又算的了什么呢?你花两个月做出来的东西,他们不能用,然后又得再去找人重新做,这个损失才是真的很大。

之前废话了那么多,如果你认同我的观点,那么你可以继续往下看了。 前个星期一起开早会的同事提议大家,开会的时候可以说说主持早会人的一些缺点。轮到我的时候,得到了一些同事的肯定,认为我很热爱技术,说我的目标很明确的人,对我的鼓励很大。前一段时间堂弟对我推荐《全职猎人》动漫,看了几集,确实很适合我的胃口,越看越觉得很有意思,甚至是周末的时候花了一整天都在看,直到看到最新一集,很是精彩,因为很认同主角,主角现在虽然实力很弱,但是他想成为一名实力很强的猎人,在每次遇到实力比自己强的对手,不是去害怕,而是兴奋!他非常的享受战斗的过程,甚至有点让人感到「变态」,但是我是非常非常的喜欢这种精神。

记得12年过完年找工作的时候,一家公司老板面试我,给我的评价是「热爱技术,但是技术基础太差,但是愿意给我试用几天的机会」,加上这次同事评价 - 「我是个热爱技术,并且有着明确目标的人」,再加上朋友的评价是「很享受编程的样子」。这说明我的路没有走弯,我很感谢他们的评价。

但是这还不够,远远不够,我需要更多。我的技术其实还是很差,接触的东西越多,越觉得自己会的东西太少,我要看的书还有很多。我希望把自己打造成一流的人才。

表单多radio jQuery 不为空验证

2014年01月24日

一、如果表单是 POST 或者 GET 提交的话,可以直接这样写 jQuery:

$("form").submit(function() {
    var submitme = true;
    $(':radio').each(function() { // loop through each radio button
        nam = $(this).attr('name'); // get the name of its set
        if (submitme && !$(':radio[name="'+nam+'"]:checked').length) {
        // see if any button in the set is checked
            alert(nam+' group not checked');
            submitme = false;
        }
    });
    return submitme; // cancel the form submit
});

二、如果表单用的 Ajax 提交的话,我们还需要修改一下:

  1. 把提交按钮 type 由 submit 改成 button 类型,然后加一个 id=”submit ”。

  2. jQuery 代码如下:

    $(“#button”).click(function(){ var submitme = true; $(‘:radio’).each(function() { nam = $(this).attr(‘name’); if (submitme && !$(‘:radio[name=”‘+nam+’”]:checked’).length) { alert(nam+’ group not checked’); submitme = false; } });

     if (submitme) {
         // 防止重复提交
         $(this).attr({
             disabled: 'disabled',
             value: '正在提交...'
         });
         $.post("/admin/saveUserData",$("#user-form").serialize(),function(data){
             #do something
             ....
         });
     };  })
    

参考文章:http://stackoverflow.com/questions/10706925/jquery-ensuring-all-radio-groups-are-checked

Yii 非主键关联

2014年01月24日

1
2
3
4
5
6
7
8
9
10
11
function relations()
    {
        return array(
            'last_experience' => array(
                self::HAS_ONE,
                'Experience',
                '',
                'on' => 'user_id=last_experience.user_id'
            ),
        );
    }

jQuery Ajax 点击修改

2014年01月23日

先来一张效果图: view HTML页面代码如下:

<td align="center" onclick="changeLike(<?php echo $id ?>,'<?php echo $like_count; ?>',this)">
    <?php echo $value['like']; ?>
</td>

JavaScript代码如下:

function changeLike (id, like, obj) {
    $(obj).html('<input type="num" name="" size="5" value="'+like+'">');
    $(obj).find('input').focus();
    // 键盘Enter键提交
    $(obj).find('input').keydown(function(event) {
        if(event.which==13){
            $(obj).find('input').blur();
        }
    });
    // 更新数据
    $(obj).find('input').blur(function(event) {
        $(obj).html(this.value);
        $.get('/admin/ajaxLike/'+id+'/'+this.value, function(data) {
            like = data;
        });
    });
}

至于控制器代码就很简单了,用获取到的参数,更新记录,返回新纪录。下面是我用CakePHP写的action,请结合自身情况写代码:

public function ajaxLike($id, $like)
{
    $this->layout = 'ajax';
    $this->Article->id = $id;
    $this->Article->saveField('like', $like);
    exit($like);
}

CakePHP Ajax分页

2014年01月23日

Controller文件头部调用CakePHP自带分页并且配置分页条数代码:

public $components = array('RequestHandler', 'Paginator');
public $paginate = array('limit' => 2 );  //2是为了方便测试

调用的action方法如下:

public function list()
{
    $this->Paginator->settings = $this->paginate;
    $data = $this->Paginator->paginate('Notice');
    $this->set('data', $data);
}

list.ctp文件,代码如下:

<?php echo $this->Js->writeBuffer(array('inline'=>false));?>
<div id="search_result">
    <?php foreach ($data as $key => $value): ?>
        <?php echo $value['Notice']['title'] ?>
    <?php endforeach ?>
    <?php $this->Paginator->options(array(
                'update' => '#search_result',
                'evalScripts' => true,
    ));?>
    <?php echo $this->Paginator->prev('上一页' . __('', true), array(), null, array('class'=>'disabled'));?>
    <?php echo $this->Paginator->numbers(array('class' => 'numbers', 'first' => false, 'last' => false));?>
    <?php echo $this->Paginator->next(__('下一页', true) . ' >>', array(), null, array('class' => 'disabled'));?>
    <?php echo $this->Js->writeBuffer(array('inline'=>true));?>
</div>

参考文章: http://endoyuta.com/2013/05/06/cakephp-2-3-ajax%E3%81%AApagination/ http://caky.de/en/core-libraries/helpers/js.html#ajax-pagination

Yii扩展自带的时间选择器插件CJuiDatePicker

2014年01月13日

事情大概是这样的:我数据库时间字段用的是 int 类型,存储的是时间戳。并且我写文章的时候,时间是需要可以修改的。

来一张最终效果图:

首先我用了 Yii 自带的 Zii CJuiDatePicker 扩展,非常的强大的把 jQuery UI 的 Datepicker 继承进去了,使用非常的简单,手册上有。但是这个有个缺陷,没有小时分钟,只能配置日期。这个有点坑爹了。然后没办法,去找了一个 yii 的扩展。我选了 ejuidatetimepicker,使用也很简单,基本就按照给的 Demo复制过去就可以了。

现在来说说这个功能的难点,首先我数据库是 int 时间戳格式的,但是我用的这个插件是日期格式的,那么现在我又不想改数据库时间的字段类型,我要如何解决? Google 了一下,找到了一篇文章,我按照这个来结果成功了。

首先根据插件的 Demo 我们在视图form的时间是这样写的:

<?php echo $form->labelEx($model,'create_time'); ?>
    <?php $this->widget('application.extensions.timepicker.EJuiDateTimePicker',array(
        'model'=>$model,
        'attribute'=>'create_time',
        'language'=>'zh-CN',
        'options'=>array(
            'hourGrid' => 4,
            'hourMin' => 9,
            'hourMax' => 17,
            'timeFormat' => 'hh:mm',
            'changeMonth' => true,
            'changeYear' => false,
            ),
        'htmlOptions'=>array(
            'readonly'=>true,
            'style'=>'width:180px;'
        ),
    )); ?>
<?php echo $form->error($model,'create_time'); ?>

控制器部分我们基本上不用修改。接下来我们去修改 Model 文件,添加两个 yii 的 function:

protected function beforeSave()
{
    $this->admin_id = Yii::app()->user->id;
    // $this->create_time = date('Y-m-d', CDateTimeParser::parse($this->create_time, 'yyyy-MM-dd hh:mm'));
    $this->create_time = strtotime($this->create_time);
    return parent::beforeSave();
}

protected function afterFind()
{
    $this->create_time = Yii::app()->dateFormatter->format('yyyy-MM-dd hh:mm', $this->create_time);
    return parent::afterFind();
}

beforeSave 就是数据保存之前我们要处理的事件。afterFind 就是数据显示之前我们要处理的事件。 非常巧妙的用法。

最后别忘记了把 Model 的 rules 的时间验证规则改一下,代码如下:

array('create_time', 'date', 'format'=>'yyyy-MM-dd hh:mm', 'message'=>'{attribute} have wrong format'),

**值得注意的是 rules 验证会在 beforeSave 之前执行。beforeSave 和 afterFind 都是 protected 属性。

** 参考文章:** - http://www.yiiframework.com/extension/ejuidatetimepicker/ - http://www.yiiframework.com/doc/api/1.1/CJuiDatePicker - http://www.volkomenjuist.nl/blog/2013/02/24/yii-cjuidatepicker-dateformat/   

最后感叹下自带 zii 的方便强大,再分享一个资源: http://www.bsourcecode.com/yii-framework/yii-extensions/

Comments

Jack Van: 怎么只能从9点到16点

ForEcho: 代码上面有参数。自己可以设置,hourMin 和 hourMax

CakePHP的小技巧用法

2014年01月03日

1、问:如果控制器有一个方法,不要视图怎么办?

答:使用:$this->autoRender = false

2、对于一直在开发的网站,在频繁更新的情况下,如何保证css文件、js文件和image文件不调用浏览器缓存文件问题?

答:一个是在调用的文件名最后加变量后缀,如时间。示例代码如下:

<link rel="stylesheet" type="text/css" href="http://forecho.com/css/index.css?2014-01-03-1" media="all" />

二如果是CakePHP的话还可以修改core.php配置文件,代码如下:

/**
 * Apply timestamps with the last modified time to static assets (js, css, images).
 * Will append a querystring parameter containing the time the file was modified. This is
 * useful for invalidating browser caches.
 *
 * Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
 * timestamping regardless of debug value.
 */
    Configure::write('Asset.timestamp', true);

这样的好处是你接下来可以直接用CakePHP自带的写法调用图片和文件了,如:

<?php
	echo $this->Html->css('main');
	echo $this->Html->image();
?>

3、点赞的时候需要+1,如何更新数据库?

代码如下:

$this->Widget->updateAll(
    array('Widget.numberfield' => 'Widget.numberfield + 1'),
    array('Widget.id' => 1)
);

4、如何通过主键最简单的方式获取到一条数据?

代码如下:

// 只获取name字段信息
$this->User->read("name", $id);
// 获取所有信息
$this->User->read(null, $id);

5、CakePHP控制器如何返回上一页?

$this->redirect($this->referer());

6、CakePHP A控制器调用B控制器

$this->requestAction(
    array('controller'=>'Wx','action'=>'aa'),
    array('data'=>
        array('xing'=>'A1','ming'=>'A2')
    )
);

这样可以在A控制器调用B控制器方法,而且在后面传参过去,用$this->request->data获取参数值。

7、输出单个页面执行的SQL语句

$log = $this->Model->getDataSource()->getLog(false, false);
debug($log);

Model要改一下名字才能用。

庆「元旦」读完《淘宝技术这十年》

2014年01月01日

元旦放假一天,天气不错无处可玩,想着去广场晒着太阳应该是件很不错的事情。于是吃完午饭抱着同事借来的《淘宝技术这十年》去广场找了个位置看书,在家对着电脑不管多安静,我是看不进去书的。 其实以前在博客园的这里已经看得差不多一半了,其实书的内容不怎么多的,除了讲技术的部分不明觉厉之外,其他的章节还是很有意思的。下面就摘抄一些有意义的笔记。内容主要为后面一章节,本书的前一半内容看的比较早了,当时忘记记录笔记了。

子柳:你对刚入行的技术人员有什么建议?
正明:找到自己感兴趣的,花时间投进去,通过实践后的知 识积累比只看书本有用得多。我看过一本操作系统方面的英文书,其中引用了一段中国人的格言:“I hear and I forget. I see and I remember. I do and I understand”,这句话给我留下非常深刻的 印象。是荀子说的“不闻不若闻之,闻之不若见之,见之不若知 之,知之不若行之。”

子柳:从你的经历来看,你对现在的技术人员的成长有什么建议?
正祥:很多人会说年轻人比较浮躁,其实我的身边有很多非常优秀的年轻人,他们聪明、刻苦、有闯劲、愿意接受新事物。 年轻的同事想赚钱,想提升自己的职称,这些都是十分正常的。 在这点上,我特别喜欢马总的理念——做公司要赚钱,但阿里从 不把赚钱作为第一目标,我们服务好了客户,客户赚了钱,我 们一定会得到自己应得的一份。在个人成长问题上也是类似的 道理,这就是,一个人如果把做事、做成事作为主要目标,该他 得到的东西,一定会顺理成章的、水到渠成地得到,但是,如果 把上升作为主要目标,做同样的事,结果就会完全不一样。一句 话,你的心态会最终决定你的成就。

子柳:你来淘宝技术大学授课的时候,给学员说过“但行好 事,不问前程”,现在很多同学都因为晋升的问题很纠结,可否 解释一下自己是怎么看待晋升的?
毕玄:大家都说了,晋升是一个“水到渠成”的事情。大家 都会在意晋升,这个是正常的,除非你不在意级别,生活上也没 有压力,不过这样的人是很少的,呵呵。如果真的没有升上去, 这个也没有什么办法能够挽救了。我觉得重要的是在这个过程中 你回顾了你一年做了什么事情,对公司有什么贡献,技术上有哪些成长。 对于技术人员最常见的一种情况是晋升名单公布的时候,你 去看谁升上去了,然后对比一下自己,觉得他水平不如自己,为 什么是他得到了晋升,而不是你。我觉得最重要的是看那个人对 公司做了多少贡献,你可以说你的技术确实很强,但事实是你对 公司没有做出任何贡献。

子柳:你是技术晋升的评委,在评审的过程中,你比较看重什么样的特质?
毕玄:如果你是向技术方向发展的人员,我们要看技术方面的专业性;然后看你的技术对公司的业务发展有多少贡献。还有 一点,我比较看重的是,也许你不在其位,但能够跳出自己的范 围,想到公司未来到底会面临什么问题,用什么方法来解决。当 然,仅想是不够的,如果你能够落实就最好了,我们不管你落实 的技术含量有多高,关键是你解决了什么样的问题。如果你能够 做到这些,你这个人对公司就非常重要。

子柳:你经常出去招聘学生,你欣赏什么样的学生?
毕玄:其实在校招聘的时候,我比较欣赏的学生往往是那些很“不务正业”类型的。我经常会问他们,你有没有利用业余时间出于自己的技术兴趣做的一些小东西。这样的学生我们通常 会比较感兴趣,我认为这样的学生是真正喜欢技术。聪明程度一般就可以的,他能够进入这些不错的学校,智商是不会有什么问 题的。

子柳:你对新人的要求是什么样的?
放翁:第一个是做事要自己思考后再去问别人,而不是一遇到问题就找人求助。第二个是不断地打破自己的一些想法,你不要担心自己今天已经做了50%的工作,要是推倒重来,前面的事情都白干了。我现在带的两个新人成长很快,但是都有类似的经历,就是一个东西被我反复推翻重做,在这个过程中就是不断地成长,要思考我为什么让你推倒重做,若想不清楚,下次重做的概率会更大,这样慢慢地就会学会了思考。

子柳:你对工程师有什么忠告?
放翁:任何一个公司,不管用什么手段,都做不到绝对公 平,最终只会有小部分人得到机会。这个时候去抱怨、愤怒都没 有用的,只有自己不断地努力争取机会才行。

子柳:给技术刚起步的人员一些技术成长的建议吧。
云铮:兴趣是最好的老师,坚持是达到梦想的唯一途径,当然,在个人发展的不同阶段寻找到合适的导师很重要,看准方向 会事半功倍。在刚刚参加工作还没有形成自己的判断时,方向有 两个来源,一个是个人的兴趣,一个是找一个你非常佩服且能掌 握未来方向的人,当然,如果这两者正好重合,那么剩下的就是 脚踏实地坚持。

子柳:说说你个人的成长经验,给起步阶段的同事一些建议吧。
小马:现在回过头来看,其实成长最快的一段时间是刚进淘 宝的那几年,那个时候很单纯,就想着把工作做好,做完一个做 下一个,不管这个业务是不是重要,需求方是不是好打交道。有个“一万个小时理论”,我觉得很正确,说的就是一个人必须经 过不断地练习,不断地遇到问题才能成长起来。当然,做的时候 要不断总结,写博客是一个很好的途径。

子柳:现在有很多人出去创业,作为一个曾经创过业的技术 人员,你有什么看法?
小马:很多人创业是因为公司变得越来越大,有很多流程和 规章制度的限制,这样自己发挥的空间越来越小。但是真的到 社会中创业时会发现限制同样很多,你同样要面临税务局、工商 局、商标、公司注册、股东关系、员工管理、同行竞争等问题, 这跟你在公司中工作并没有本质的不同。所以说创业其实是一种 心态,你用旺盛的精力、饱满的斗志和坚定的信念去克服一个又 一个的困难,这就是创业。到外面去创业和在一个大公司里创 业,我个人觉得并没有本质的区别。 当然,如果你不认可公司整体的方向,或者你不认可这个行 业,你有一个理想去打造一个新的天地,公司也应该有这种胸怀 鼓励你去创业。

总结一下去年真正看完的书只有可怜的《Getting Real – 37signals》、《不许联想》、《打造 Facebook》、《把时间当作朋友》4本。太少了,争取今年能至少读完10本书。