Hibernate关联映射

以简单的两个类为例:
User(int id, String name)
Group(int id, String name)

没有关联关系时的关系模型:
t_user(id int pk, name varchar)
t_group(id int pk, name varchar)

一、多对一和一对多关联映射(多个用户有相同的组)

这几种关联映射后的关系模型是相同的:
t_user(id int pk, name varchar, gid int fk->t_group(id))
t_group(id int pk, name varchar)

1、多对一单向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
        <many-to-one name="group" column="gid"/>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
2、一对多单向关联(几乎不用)

实体模型:
bean.User(int id, String name)
bean.Group(int id, String name, Set users)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<set>映射集合 -->
        <set name="users">
            <!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
            <key column="gid"/>
            <!-- 使用<one-to-many>映射一对多关系 -->
            <one-to-many class="bean.User"/>
        </set>
    </class>
</hibernate-mapping>

为Group加入集合也可以使用List(<list>),注意不能指定类型是具体的HashSet或ArrayList,只能是接口Set或List。
集合标签可以使用order-by属性指定排序:

<set name="users" order-by="id desc">
3、双向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, Set users)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
        <many-to-one name="group" column="gid"/>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<set>映射集合 -->
        <set name="users">
            <!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
            <key column="gid"/>
            <!-- 使用<one-to-many>映射一对多关系 -->
            <one-to-many class="bean.User"/>
        </set>
    </class>
</hibernate-mapping>

双向关联中,为<set>加入”inverse=true”可以反转维护关系:Hibernate将放弃从一的一端维护。意思就是user和group的关系必须使用user维护,操作group时Hibernate将不维护这个关系。

<set name="users" inverse="true">

操作group的示例:

            session.beginTransaction();
            User user = new User();
            user.setName("张三");
            Group group = new Group();
            group.setName("admin");
            group.setUsers(new HashSet());
            group.getUsers().add(user);
            session.save(user);
            session.save(group);
            session.getTransaction().commit();

没有配置inverse=”true”时,Hibernate输出了添加user和group,并更新user的语句:

Hibernate: insert into t_user (name, gid) values (?, ?)
Hibernate: insert into t_group (name) values (?)
Hibernate: update t_user set gid=? where id=?
而配置了inverse=”true”后,Hibernate仅仅输出了添加user和group的语句,并没有更新user,放弃了关系的维护:
Hibernate: insert into t_user (name, gid) values (?, ?)
Hibernate: insert into t_group (name) values (?)
此时应该从user端维护关系:
            session.beginTransaction();
            Group group = new Group();
            group.setName("admin");
            User user = new User();
            user.setName("张三");
            user.setGroup(group);
            session.save(group);
            session.save(user);
            session.getTransaction().commit();

因为外键列在t_user表中,从group端维护需要操作多表,所以从user端维护关系更加合理,效率也更高。上面的代码输出两条SQL语句,插入数据的同时也维护了关系:

Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (name, gid) values (?, ?)

 

二、一对一关联映射(每个用户独有一个组)

依照映射方法不同,可分为主键关联映射唯一外键关联映射。主键关联是维护两张表的主键一致,如有必要还可以在主键上再加上外键约束;唯一外键关联则类似于多对一关联,为表加入一个外键列,不过一对一关联会同时将这个外键加上唯一约束。

1、主键关联映射

主键关联生成的关系模型:
t_user(id int pk fk->t_group(id), name varchar)
t_group(id int pk, name varchar)

1.1、主键单向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <!-- 指定主键生成策略为外键 -->
            <generator class="foreign">
                <!-- 指定要参照的属性 -->
                <param name="property">group</param>
            </generator>
        </id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系。 -->
        <one-to-one name="group">
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>

主键关联由Hibernate维护,不依赖数据库。如果需要在数据库端也生成外键约束,可以使用constrained:

<one-to-one name="group" constrained="true"/>

1.2、主键双向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, User user)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <!-- 指定主键生成策略为外键 -->
            <generator class="foreign">
                <!-- 指定要参照的属性 -->
                <param name="property">group</param>
            </generator>
        </id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系。 -->
        <one-to-one name="group">
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系 -->
        <one-to-one name="user"/>
    </class>
</hibernate-mapping>

 

2、唯一外键关联映射

唯一外键关联生成的关系模型:
t_user(id int pk, name varchar, gid int fk->t_group(id))
t_group(id int pk, name varchar)

2.1、唯一外键单向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 为<many-to-one>加上unique就变成了一对一 -->
        <many-to-one name="group" unique="true" column="gid"/>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>

2.2、唯一外键双向关联

实体模型:
bean.User(int id, String name, Group group)
bean.Group(int id, String name, User user)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 为<many-to-one>加上unique就变成了一对一 -->
        <many-to-one name="group" unique="true" column="gid"/>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一 -->
        <one-to-one name="user"/>
    </class>
</hibernate-mapping>

三、多对多关联映射(每个用户拥有多个组,每个组也有多个用户)

多对多关联映射关系使用中间表表示。导出关系模型时Hibernate将自动生成复合主键以及外键约束。

关系模型:
t_user(id int pk, name varchar)
t_group(id int pk, name varchar)
t_user_group(userid int fk->t_user(id), groupid int fk->t_group(id), pk(userid, groupid))

1、多对多单向关联

实体模型:
bean.User(int id, String name, Set groups)
bean.Group(int id, String name)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="groups" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="userid"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.Group" column="groupid"/>
        </set>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
1、多对多单向关联

实体模型:
bean.User(int id, String name, Set groups)
bean.Group(int id, String name, Set users)

<!-- bean/User.hbm.xml -->
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="groups" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="userid"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.Group" column="groupid"/>
        </set>
    </class>
</hibernate-mapping>
<!-- bean/Group.hbm.xml -->
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="users" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="groupid"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.User" column="userid"/>
        </set>
    </class>
</hibernate-mapping>

多对多的双向关联同样可以在不想要维护关系的一端的<set>里设置inverse=”true”;但是必须有一端可以维护,也就是说只可以设置一个。

7件网络开发者和网站设计者必备的web工具app

原文地址:http://www.smashingapps.com/2011/10/19/7-must-have-web-apps-for-designers-and-developers-toolbox.html

There are many online tools and web applications out there, but getting by free and good ones is not that easy. Today, we are sharing 7 Must-Have Web Apps For Designers And Developers Toolbox. Read each entry in the list and see which one suits your needs best.

Golden Ratio

There are two scenarios the calculator is designed for. The first is that you have a column with a certain width (perhaps to achieve a nice word:line ratio). You wish to find a matching column. Type in the width and use the left side, which gives you both a smaller and larger column. The second scenario is that you have a container and wish to divide it in two. Type in the container width and use the right side measurements.

SpiderScribe

SpiderScribe is an online mind mapping and brainstorming tool. It lets you organize your ideas by connecting notes, files, calendar events, etc. in free-form maps. You can collaborate and share those maps online.

Profitably

Profitably helps you plan for the customers you want, measure how you’re performing, and then execute. It’s web-based software connects securely to business applications like Intuit’s QuickBooks to provide insight to the ~6M small businesses in North America. CFOs, bookkeepers, and business owners alike use Profitably to understand customer profitability, manage cash flow, and plan for future growth, all in real time.

Manifested

Manifested is a new utility for getting a jump start on converting your existing web site to work offline using HTML5?s cache manifest. Manifested scrapes a website for images, stylesheets, and JavaScripts that you may want to cache. Manifested then gives you a custom cache manifest file as a starting point for upgrading your website to support offline functionality.

repl.it

The repl.it project is an attempt to create an online environment for interactively exploring programming languages. It provides a fully-featured terminal emulator and code editor, powered by interpreter engines for more than 15 languages. All our interpreters are written in (or compiled to) JavaScript, and run completely on the user’s device, regardless or whether it’s a desktop, laptop or phone.

Subtle Patterns

Subtle Patterns is a collection of 93 high quality design patterns for you to use freely.

Timeslot

Timeslot makes planning your day a breeze. It simply add items to your day’s agenda, and specify how long each will take. Timeslot will automatically generate start and end times for each item, so when you have to make a change, your entire agenda will update to flow around it.

[zz]基础知识普及:B树、B-树、B+树、B*树,java

B

       即二叉搜索树:

       1.所有非叶子结点至多拥有两个儿子(LeftRight);

       2.所有结点存储一个关键字;

       3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;

       如:

       

       B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;

       如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;

       如:

      

   但B树在经过多次插入与删除后,有可能导致不同的结构:


   右边也是一个B树,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题;      

       实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略;

 

B-

       是一种多路搜索树(并不是二叉的):

       1.定义任意非叶子结点最多只有M个儿子;且M>2

       2.根结点的儿子数为[2, M]

       3.除根结点以外的非叶子结点的儿子数为[M/2, M]

       4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

       5.非叶子结点的关键字个数=指向儿子的指针个数-1

       6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]

       7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

       8.所有叶子结点位于同一层;

       如:(M=3

       B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

B-树的特性:

       1.关键字集合分布在整颗树中;

       2.任何一个关键字出现且只出现在一个结点中;

       3.搜索有可能在非叶子结点结束;

       4.其搜索性能等价于在关键字全集内做一次二分查找;

       5.自动层次控制;

       由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少利用率,其最底搜索性能为:

    

       其中,M为设定的非叶子结点最多子树个数,N为关键字总数;

       所以B-树的性能总是等价于二分查找(与M值无关),也就没有B树平衡的问题;

       由于M/2的限制,在插入结点时,如果结点已满,需要将结点分裂为两个各占M/2的结点;删除结点时,需将两个不足M/2的兄弟结点合并;

 

B+

       B+树是B-树的变体,也是一种多路搜索树:

       1.其定义基本与B-树同,除了:

       2.非叶子结点的子树指针与关键字个数相同;

       3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);

       5.为所有叶子结点增加一个链指针;

       6.所有关键字都在叶子结点出现;

       如:(M=3

   B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

       B+的特性:

       1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

       2.不可能在非叶子结点命中;

       3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

       4.更适合文件索引系统;

  

B*

       B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;

   B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2);

       B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

       B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;

       所以,B*树分配新结点的概率比B+树要低,空间使用率更高;

  

小结

       B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;

       B-树:多路搜索树,每个结点存储M/2M个关键字,非叶子结点存储指向关键字范围的子结点;

       所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

       B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

       B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3

[zz]24款非常实用的CSS3工具终极收藏

对于Web设计和开发人员来说,CSS是非常重要的一部分,随着越来越多的浏览器对CSS3的支持及不断完善,设计师和开发者们有了更多的选择。如今,用纯CSS就可以实现各种各样很酷的效果,甚至是动画。今天这篇文章向大家推荐24款非常优秀的CSS3工具,为了获得更佳的效果,请在Chrome 4+, Safari 4+, Firefox 3.6+, IE9+, Opera 10.5+版本浏览器中浏览如下在线工具。

1.CSS3 Pie

使用CSS3 Pie可以让IE6至IE8版本实现大多数的CSS3修饰特性,如圆角、阴影、渐变等等。

2. CSS3 Click Chart

非常好的CSS3效果演示,提供了示例代码。

 

3.CSS3 Please!

非常帅的一款CSS3工具,可修改代码,即时预览。

 

4.CSS3 Button Maker

一个非常不错的CSS3按钮制作工具。

5.CSS3 Generator

非常不错的CSS3代码生成器,带预览效果。

6.CSS3 Menu

非常不错的CSS3菜单制作工具。

7.CSS3 Gradients

一款非常棒的CSS3渐变效果演示工具。

8.CSS3 Cheat Sheet

一份不错的CSS3属性速查手册(PDF格式)。

9.CSS3 Selector Test

非常不错的CSS3选择器测试工具

10.CSS3 Transforms

一款强大的CSS3旋转动画效果演示工具,即时生成代码。

11.CSS3 Preview

CSS3特性介绍及效果预览。

12.CSS3 Generator

一款非常不错的CSS3代码生成工具。

13.CSS3 Color Names

CSS3颜色命名对照表。

14.Toggle CSS3 Bookmarklet

CSS3书签工具。

 

15.CSS3 Border Radius

一款在线CSS3圆角工具,四个角输入值就能生成对应的效果和代码。

16.CSS3 Desk

很炫的CSS3桌面。

17.Web Browser CSS Support

非常详尽的浏览器对CSS支持情况,包括CSS2.1和CSS3。

18.Key CSS

让元素以键盘风格显示的样式表。

19.CSS3 Playground

一款在线CSS3圆角和阴影效果演示及代码生成工具。

20.CSS3 Wrapping Drop Shadows

CSS3包装阴影效果。

21.CSS3 Carve Me

模仿内阴影效果,可输入内容查看效果,中文也可以噢。

22.Mother Effing Text Shadows

这工具名字太奇怪了,一款文本阴影效果工具,可即时生成代码。

23.CSS3 Learning Tool

在线CSS3学习工具,可即时预览效果。

24.CSS3 Maker

最后压轴的这款工具非常强大,可在线演示渐变、阴影、旋转、动画等非常多的效果,并生成对应效果的代码,赶紧体验一下吧!

(编译来源:梦想天空  原文来自:Ultimate Collection of CSS3 Tools For Your Next Web Development

 

[zz]如何做好一份前端工程师的简历?

原文连接:http://dancewithnet.com/2009/02/17/how-to-make-a-resume-of-f2e/

春节前在蓝色理想上发了个“雅虎口碑招聘前端工程师 ”的启事,节后收到很多简历,加之HR通过专业招聘网站得到的简历和朋友同事推荐的简历,数量上是相当的多,把这些简历一一看完真是一个漫长而幸苦的体力活,何况我还要仔细认真的去提取和核查有用信息评估其能力,尽量不错过任何一个埋藏在大量简历中合适的人,这绝大部分时间并不是一个相当愉悦的过程。所以,我感觉有必要来谈谈:如何做好一份前端工程师的简历。

一、你是前端工程师

虽然简历都会有一些常规信息,但职业决定了这份简历核心内容和求职成败。所以,这份简历应该尽可能体现你自己是一个合格的前端工程师。专业的前端工程师是什么可以看看去年Nate Koechley的演讲《Professional Frontend Engineering》,前端工程师应该关注的内容可以从克军总结的“前端工程师应该关注什么”的思维导图中窥出一二,学习内容聚合可以看看陈成总结的《前端开发大众手册(包括工具、网址、经验等)》

毫无疑问,前端工程师应该知道如何用简历体现其专业技能和职业精神,这是每个应聘者应该考虑的问题。

二、内容为王

  1. 个人信息
    1. 姓名 (必需)
    2. 性别 (必需)
    3. 年龄 (必需)
    4. 联系电话 (必需)
    5. 学历及学位 (必需)
    6. 薪资期望
    7. 个人照片
    8. 邮箱
    9. Blog
    10. 外语能力
  2. 职业技能
    1. HTML、CSS、JavaScript/ActionScript等
    2. Web标准、可用性、可访问性
    3. 一门非前端脚本的语言(Java、PHP、Python、C#等)
    4. 任何有利于前端开发的技能和兴趣
  3. 职业和教育经历
    1. 起始时间、单位名、职位(学位)和收获
    2. 简而精
    3. 按照时间倒序排列
  4. 代表作品
    1. 能体现自己现在前端技能或者重要经历的作品
    2. 简而精,且可以简要附上自己在这个作品中的收获
    3. 和别人合作的作品要注明自己具体完成的内容
    4. 在线链接要测试以保证可用,如果有其他人的变更应注明,较大变更就无需提交了
    5. 提供附件要注明与之对应的文件名
    6. 按完成时间倒序排列

依据实际情况,代表作品也完全可以直接融入到职业技能和经历中体现。当然内容不仅仅是这些,可以任意增加能体现前端工程师职业素质的信息。

三、Web是平台

毫无疑问,Web才是真正的平台,当这个平台的后端逐步被云所统治时(Amazon的很多服务和Google App Engine都初见端倪),那么云端的用户代理(比如浏览器)就是前端工程师的战场。前端工程师是可以长期从事且有前途的职业。

简历作为前端工程师迈向新征途而提交的第一份作品,应该毫不迟疑的用它来体现其专业技能和职业精神,所以Web页面是前端工程师简历的最好载体。它能体现前端工程师诸多专业素质:

  1. 知道为什么选择的DTD是下面中的一个而不是其他,这是对HTML标准的理解和思考 。
    1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    4. <!DOCTYPE HTML>
  2. 针对内容选择合适的HTML标签,合理的id和class命名,尝试使用微格式,这是对语义化的理解和思考。
  3. 至少兼容YUI中列出的A-grade浏览器,这是对跨浏览器和CSS Hacks的理解和思考 。
  4. 虽然Web性能在大访问量下才比较容易凸显,但把尝试把YAHOO性能团队的34条最佳实践应用上,一定会小中见大且受益终生的 。
  5. JavaScript的应用
    1. 简历的信息结构一般很简单,但是这并不意味着无法使用JavaScript来增强它的交互。找出其JavaScript技能和简历相互结合的地方。
    2. 可以尝试使用某种框架(YUIjQueryPrototypeMootools等),很明显框架能提高我们的开发速度,掌握至少一种优秀的框架能增强我们的价值。
    3. 可以利用JavaScript做出几个彩蛋在简历里面么?
    4. 实现结构、样式和行为的分离。
    5. 理解和体现DOM Scripting预留退路(Graceful Degradation)渐进增强(Progressive Enhancement )无侵入的JavaScript(Unobtrusive Javascript)等思想。 空帷翻译的《理解“渐进增强(Progressive Enhancement)”》是篇这方面的好文章。
  6. 可访问性,在这上面每一步的深入研究和应用都值得赞赏。
  7. HTML5CSS3SVGCanvas甚至离线技术、安全技术都可以和我们的简历结合起来。列表When can I use…提供了一些新技术在主流浏览器的支持情况。
  8. 打印样式,很明显前端简历不仅仅是其主管看,还有HR和大老板看,所以准备打印样式是很重要的,这不仅仅是技能问题,更是一种前端开发的素质。你需要知道,打印样式应该是黑字白底,且尽量少的装饰图片,因为现在的绝大部分办公打印机还是黑白的,且黑色更费墨,所以当你的简历是黑色背景时更应该注意这点。
  9. 简单设计,千万不要把你的简历搞一团糟,设计虽然不是前端工程师最重要的技能,但是良好的视觉设计更能体现前端工程师的价值,所以审美其实也是前端工程师的基础素质。如果对视觉设计感到困惑,你可以从看《推荐给大家看的设计书》开始。

四、细节决定体验

  1. 标识性的文件名,比如“秦歌的简历”、“秦歌的作品”,而不是“个人简历”、“我的作品”。
  2. 发完信后记得检查一下发件箱,确保没有忘记发附件。
  3. 简历和众多作品整体打一个包。不要一个大包里面无数个小包。且整个包应该整理过,去掉垃圾,不应该太大。
  4. 不要重复发邮件,特别是拒绝以后,还发一个同样的邮件,除非一段时间后你有较大进步。
  5. 检查链接有效性,无效链接很伤感情的,可以使用Firefox的插件LinkCheckerPinger

实际上,前端工程师的工作成果是直接面向千万用户的,他直接决定了最终的用户体验,所以每个细节都至关重要,就像JavaScript编程一样,只要我们掌握良好的风格要素,我们就能避免很多错误,实际上这个思想贯穿整个前端开发的始终,包括制作简历。

我很喜欢有个人blog的应聘者,因为通过其blog不仅仅可以看出他的前端技能、工作积累、职业素质和分享精神,同时他通过维护blog可以贯穿一个简单开发的始终,从内容、交互、视觉、前端一直到后端维护,而这些角色都是前端在开发过程中的上下游,需要经常协作,这种经历能使前端更高效的沟通和更务实的换位思考。同样,当我推荐前端的简历应该是以Web页面为载体时,也是基于这个想法,并适当的给出一些相关知识以备有兴趣的朋友朝这个方向走下去。虽然我的建议偏向于“HTML+CSS+JavaScript”方向的前端工程师,但实战中肯定有更多能够在简历中体现前端的技能和创意,这本身就是抛砖引玉,这仅仅是一个开始。

简历很重要,但人品、职业精神和专业的前端技能更重要,最重要的是这两者是相辅相成的。虽然很羡慕兄弟团队淘宝UED支付宝UED阿里巴巴B2B国际站UED能有创意、时间和精力搞出那么精致的招聘站点,但我更希望我未来的同事用技能、创意、时间和精力整出一个巨牛的前端工程师简历来震住我(kaven.yan@yahoo.com)吧。