经典Java EE企业应用实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

0.2 走出象牙塔

看到上面的分析,可能有些应届毕业生心底暗暗高兴了:不就是Java吗?不就是C吗?这些我们大学都学过了啊,可是找工作还是困难啊。

笔者经常见到类似如下的应届毕业生的简历。

精通Java(J2EE和J2ME)、C、VC++、C++ Builder、VB编程。

精通ASP、PHP、JavaScript编程,精通网络构架设计、搜索引擎优化。

精通网络安全管理,对解密、加密也有相当的研究。

精通Access、SQL Server、Oracle数据库。

熟悉AutoCAD、Photoshop、Flash等几乎所有的常用软件。

精通Windows、Linux、UNIX等操作系统。

这种“全能人才”式的简历在应届毕业生简历中比比皆是。后来据笔者的有些学员反应:当初他们做简历时全班会一起交流简历内容,每个人都会把其他人简历中的技能复制到自己的简历中,最后全班每个人的简历都变成了“全能人才“。

在他们心中,这种“全能人才”式的简历有一个显著的好处是:这份简历几乎可以“适应”所有IT相关职位。真的如此吗?

下面是笔者从crazyit.org站点看到的阿里软件发布的一则招聘,具体请参考http://www.crazyit.org/thread-2501-1-1.html页面。

职位要求:

1.精通Web编程,3年以上使用Java语言进行Web开发的经验,熟悉HTML、JavaScript。

2.精通JSP、Servlet、Java Bean、JMS、JDBC开发,熟悉J2EE规范,熟悉各种常用设计模式。

3.熟悉基于Oracle的设计和开发、Linux操作系统、SVN操作。

4.有良好的软件工程知识和质量意识。

5.对技术有强烈的兴趣,喜欢钻研,具有良好的学习能力。

6.有良好的沟通技能,团队合作能力。

月薪:9~15k,一年发15个月工资,另有股票期权。

上面这份招聘的薪资不低,年薪可达到13.5万到22.5万,当然这和阿里软件提供的薪资不错有关(笔者有些学生大学刚毕业进阿里软件就是年薪9万),但仔细看看上面的职位要求,他们并没有要求一个“全能人才”。

这里产生了一个问题:应届毕业生写简历时唯恐自己会的技能不够多,所以会把自己所有听过的名词都罗列出来;而IT公司甄选人才时只是挑选“合用”的。而且IT公司的人力资源部门并不傻,IT行业很少有真正的“全能人才”,而大学刚毕业就达到“精通Java(J2EE和J2ME)、C、VC++”的人几乎没有。

应届毕业者之所以敢于往简历上写“精通Java(J2EE和J2ME)、C、VC++”,主要有两方面的理由。

他们找工作本来就抱着“碰运气”的想法,碰上谁就是谁,因此简历总是尽可能地全面。

他们并不知道何谓精通Java、精通C。他们以为学完大学里关于Java的课程、关于C的课程就是精通Java、精通C了,但实际上远远不够。

下面这段代码也是笔者从crazyit.org站点上找到的,发帖者应该是正在学习大学Java教材的大学生。看看这段代码中的问题。

      public class EditorJFrame extends JFrame
          implements ActionListener, ItemListener, MouseListener
      {
          private JTextField text_size;
          private JCheckBox checkbox_bold, checkbox_italic;
          private JButton button_cut, button_copy, button_paste;
          private JTextArea textarea;
    private JPopupMenu popupmenu;
    private JDialog dialog;
    private JLabel label_dialog;
    //初始化界面的方法
    public EditorJFrame()
    {
        ...
    }
    //添加主菜单、快捷菜单、对话框的方法
    private void addmyMenu()
    {
        ...
    }
    public void actionPerformed(ActionEvent e)
    {
        if(e.getActionCommand()=="退出")
            System.exit(0);
        if(e.getActionCommand()=="剪切")
            textarea.cut();
        if(e.getActionCommand()=="复制")
            textarea.copy();
        if(e.getActionCommand()=="粘贴")
            textarea.paste();
        if(e.getSource()==text_size)
        {
            int size=0;
            try
            {
                size = Integer.parseInt(text_size.getText());
                if (size<=0 || size>72)
                    throw new Exception("SizeException");
                java.awt.Font font = textarea.getFont();
                textarea.setFont(new Font(font.getName(),font.getStyle(),size));
            }
            catch(NumberFormatException nfe)
            {
                label_dialog.setText("\""+text_size.getText()+"\" 不能转换成整数,
                请重新输入!");
                dialog.setLocation(this.getX()+100,this.getY()+100);
                dialog.setVisible(true);
            }
            catch(Exception ex)
            {
                if (ex.getMessage()=="SizeException")
                {
                    label_dialog.setText(size+" 字号不合适,请重新输入!");
                    dialog.setLocation(this.getX()+100,this.getY()+100);
                    dialog.setVisible(true);
                }
            }
            finally{}
        }
    }
    public void itemStateChanged(ItemEvent e)
    {
        Font font = textarea.getFont();
        int style = font.getStyle();
        if (e.getSource()==checkbox_bold)
        style = style ^ 1;
        if (e.getSource()==checkbox_italic)
        style = style ^ 2;
        textarea.setFont(new Font(font.getName(),style,font.getSize()));
    }
    public void mouseClicked(MouseEvent mec)
    {
        if (mec.getModifiers()==mec.BUTTON3_MASK)
        {
            popupmenu.show(textarea,mec.getX(),mec.getY());
        }
    }
    public void mousePressed(MouseEvent mep) {}
    public void mouseReleased(MouseEvent mer) {}
    public void mouseEntered(MouseEvent mee) {}
    public void mouseExited(MouseEvent mex) {}
    public void mouseDragged(MouseEvent med) {}
    public static void main(String arg[])
    {
        new EditorJFrame();
    }
      }

这是开发了一个模拟Windows记事本的小程序,这个程序完全可以正常运行,现在请读者分析一下这段代码所反映出来的问题。

(1)最容易看出来的:变量命名方式都是有问题的,与软件公司的编程规范中变量命名规范不符合。

(2)还是编码格式问题:程序中运算符前后没有空格,程序可读性很差。

这两个问题都是关于编码格式的问题,只要学习者还没有养成顽固的坏习惯,改正起来应该不难。

上面代码中最严重的问题是:这段程序的可维护性实在太差了,程序中初始化界面(由EditorJFrame构造器和addmyMenu方法完成)、事件监听器、事件处理逻辑都混在EditorJFrame类中,这会大大增加程序的维护成本。

备注:笔者只是从crazyit.org上看到此段代码,并不是针对某本Java图书。而且这个记事本小程序也很值得初学者认真学习,只是学完这个程序之后还需要进一步提高而已。

对于实际开发来说,应用程序大致可以分为:

M(Model):模型组件,通常封装应用的业务处理。

V(View):视图组件,封装应用的可视化界面。

C(Controller):控制器组件,负责模型组件和视图组件之间的调度、通信。

即使对于上面那个简单的应用程序,实际开发中依然可以用MVC规范将其划分为3个部分。

视图组件:视图组件应该主要包括EditorJFrame构造器和addmyMenu方法中的代码,视图组件负责应用的可视化界面。

控制器组件:事件监听器就是控制器。上面应用程序应该分别提供ActionListener、ItemListener和MouseListener等多个控制器组件。

模型组件:上面把对事件的处理代码都写在事件监听器中,这也是不对的。因为事件监听器只是控制器,它只应该负责各组件之间的调度、通信。对不同事件的具体处理应该由模型组件提供,这些代码应该抽取到模型组件中。

从上面分析可以看出,即使对于如此简单的一个记事本应用程序,将其按MVC模式进行划分将可以提供更好的可读性、可维护性;对于实际企业中更大的应用程序,往往还要将其分解成更细粒度的组件才能满足实际要求。

从上面介绍可以看出,IT公司并不要求“准程序员”是全能的,没多大可能要求你会使用AutoCAD、Photoshop、Flash等软件,甚至很少要求你“精通Java、精通C”,他们要的是能真正帮助企业开发、能给企业创造价值的人。

简单地说,IT公司要的是基本功扎实,能迅速融入实际开发的软件人才。只要基本功扎实,即使你已掌握的知识和公司所用的技术稍有差异,你也可以迅速融入实际开发中。

以Java编程为例,下面几个方面的基本功则是必需的。

Java程序运行的内存管理机制。程序在内存中运行,程序运行效果只是外在表现,程序运行的本质就是对内存状态的改变,一旦真正掌握了Java程序运行的内存管理机制,你将能“以不变应万变”,从本质上把握Java程序。

Java面向对象、Java基本语法中常见陷阱。这些陷阱往往会多次重复出现,如果你每次调试时都需要花费大量时间,显然你还不合格。

常见数据结构、排序算法。这是所有程序员的基础,是都应该掌握的基本功。

程序开发、调试、测试的方法。仅掌握编程语言的基本语法显然还不够,就像一个人要写文章,光会认字、写字显然不够,还需要掌握写文章的一些基本方法才行。