标签 java 下的文章

maven项目出现数组越界异常

解决方案:3.5的会出现这个问题,更换maven版本位3.3.9就ok了

[ERROR] 44410
java.lang.ArrayIndexOutOfBoundsException: 44410
	at org.codehaus.plexus.util.xml.pull.MXParser.parsePI(MXParser.java:2502)
	at org.codehaus.plexus.util.xml.pull.MXParser.parseEpilog(MXParser.java:1604)
	at org.codehaus.plexus.util.xml.pull.MXParser.nextImpl(MXParser.java:1434)
	at org.codehaus.plexus.util.xml.pull.MXParser.next(MXParser.java:1131)
	at org.apache.maven.model.io.xpp3.MavenXpp3Reader.read(MavenXpp3Reader.java:3856)
	at org.apache.maven.model.io.xpp3.MavenXpp3Reader.read(MavenXpp3Reader.java:595)
	at org.apache.maven.model.io.DefaultModelReader.read(DefaultModelReader.java:109)
	at org.apache.maven.model.io.DefaultModelReader.read(DefaultModelReader.java:82)
	at org.apache.maven.model.building.DefaultModelProcessor.read(DefaultModelProcessor.java:81)
	at org.apache.maven.model.building.DefaultModelBuilder.readModel(DefaultModelBuilder.java:535)
	at org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:1097)
	at org.apache.maven.model.building.DefaultModelBuilder.readParent(DefaultModelBuilder.java:829)
	at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:331)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:321)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:199)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.resolveCachedArtifactDescriptor(DefaultDependencyCollector.java:544)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.getArtifactDescriptorResult(DefaultDependencyCollector.java:528)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.processDependency(DefaultDependencyCollector.java:418)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.processDependency(DefaultDependencyCollector.java:372)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.process(DefaultDependencyCollector.java:360)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.doRecurse(DefaultDependencyCollector.java:513)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.processDependency(DefaultDependencyCollector.java:467)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.processDependency(DefaultDependencyCollector.java:372)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.process(DefaultDependencyCollector.java:360)
	at org.eclipse.aether.internal.impl.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:263)
	at org.eclipse.aether.internal.impl.DefaultRepositorySystem.collectDependencies(DefaultRepositorySystem.java:325)
	at org.apache.maven.project.DefaultProjectDependenciesResolver.resolve(DefaultProjectDependenciesResolver.java:169)
	at org.apache.maven.lifecycle.internal.LifecycleDependencyResolver.getDependencies(LifecycleDependencyResolver.java:195)
	at org.apache.maven.lifecycle.internal.LifecycleDependencyResolver.resolveProjectDependencies(LifecycleDependencyResolver.java:127)
	at org.apache.maven.lifecycle.internal.MojoExecutor.ensureDependenciesAreResolved(MojoExecutor.java:246)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:200)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
	at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
[ERROR]

感觉是maven自己的plexus-utils包有问题
我也有如上问题,我是再pom中添加了activiti的jar就会报数组越界,去掉activiti的jar就正常。 但是我必须用activiti,也不知道究竟是什么原因。

[WARNING] The POM for org.slf4j:slf4j-api:jar:1.7.6 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.slf4j:slf4j-api:[unknown-version]
[FATAL] Non-parseable POM D:\maven\repository\org\slf4j\slf4j-parent\1.7.6\slf4j-parent-1.7.6.pom: end tag not allowed in epilog but got / (position: END_TAG seen ...\r\n\r\n\r\n </... @398:16) @ D:\maven\repository\org\slf4j\slf4j-parent\1.7.6\slf4j-parent-1.7.6.pom, line 398, column 16
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.709 s
[INFO] Finished at: 2017-07-04T15:23:48+08:00
[INFO] Final Memory: 12M/219M
[INFO] ------------------------------------------------------------------------
[ERROR] 17166
java.lang.ArrayIndexOutOfBoundsException: 17166
at org.codehaus.plexus.util.xml.pull.MXParser.parsePI(MXParser.java:2502)
at org.codehaus.plexus.util.xml.pull.MXParser.parseEpilog(MXParser.java:1604)
at org.codehaus.plexus.util.xml.pull.MXParser.nextImpl(MXParser.java:1434)
at org.codehaus.plexus.util.xml.pull.MXParser.next(MXParser.java:1131)
at org.apache.maven.model.io.xpp3.MavenXpp3Reader.read(MavenXpp3Reader.java:3856)
at org.apache.maven.model.io.xpp3.MavenXpp3Reader.read(MavenXpp3Reader.java:595)
at org.apache.maven.model.io.DefaultModelReader.read(DefaultModelReader.java:109)
at org.apache.maven.model.io.DefaultModelReader.read(DefaultModelReader.java:82)

卫语句

大量的嵌套条件分支是很容易让人望而却步的代码,我们应该极力避免这种代码的出现。尽管结构化原则一直在说一个函数只能有一个出口,但是在大量的嵌套条件分支下,让我们忘了这所谓的规则吧。 有一个专业名词叫卫语句,可以治疗这种恐怖的嵌套条件语句。它的核心思想是,将不满足某些条件的情况放在方法前面,并及时跳出方法,以免对后面的判断造成影响,经过这项手术的代码看起来会非常的清晰。
1.使用卫语句取代嵌套表达式
2.卫语句就是把复杂的条件表达式拆分成多个条件表达式,比如一个很复杂的表达式,嵌套了好几层的if – then-else语句,转换为多个if语句,实现它的逻辑,这多条的if语句就是卫语句.
3有时候条件式可能出现在嵌套n次才能真正执行,其他分支只是简单报错返回的情况,对于这种情况,应该单独检查报错返回的分支,当条件为真时立即返回,这样的单独检查就是卫语句(guard clauses).卫语句可以把我们的视线从异常处理中解放出来,集中精力到正常处理的代码中。

java代码获取完整的Exception异常信息

下面的java代码可以获取完整的Exception异常信息:

import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionTest {
	public static void main(String[] args) {
		try {
			String aa = "";
			System.out.println(aa.substring(3));
		} catch (Exception e) {
			e.printStackTrace();
			StringWriter sw = new StringWriter();
			e.printStackTrace(new PrintWriter(sw, true));
			String str = sw.toString();
			System.out.println("==========");
			System.out.println(str);
		}
	}
}

控制台打印的信息:

java.lang.StringIndexOutOfBoundsException: String index out of range: -3
	at java.lang.String.substring(String.java:1875)
	at ExceptionTest.main(ExceptionTest.java:8)
==========
java.lang.StringIndexOutOfBoundsException: String index out of range: -3
	at java.lang.String.substring(String.java:1875)
	at ExceptionTest.main(ExceptionTest.java:8)
e.getmessage < e.tostring < e.getStackTrace +e.tostring = e.printStackTrace

利用PostMan开发调试Restful API

利用PostMan开发调试Restful API
下边的图片是postman发送不同类型的请求,注意url和参数的变化:

get

get


delete

delete


post

post


put

put


利用spring mvc实现restful api ,需要修改的部分:

@RestController
还有就是要注意参数获取的方式,

参考后端代码:

/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.sys.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.jeeplus.common.web.BaseController;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.SystemService;
/**
 * 用户Controller
 * @author jeeplus
 * @version 2013-8-29
 */
@RestController
@RequestMapping(value = "/user")
public class UserController2 extends BaseController {
	@Autowired
	private SystemService systemService;
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public User viewGET(@PathVariable("id") String id) {
        User user = new User();
        user = systemService.getUser(id);
        System.out.println("get method");
        return user;
    }
	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public User viewDELETE(@PathVariable("id") String id) {
        User user = new User();
        user = systemService.getUser(id);
        System.out.println("delete method");
        return user;
    }
	@RequestMapping(value = "", method = RequestMethod.POST)
    public User viewPOST(@ModelAttribute("user")User users) {
        User user = new User();
        user = systemService.getUser(users.getId());
        System.out.println("post method");
        return user;
    }
	@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public User viewPUT(@ModelAttribute("user")User users) {
        User user = new User();
        user = systemService.getUser(users.getId());
        System.out.println("put method");
        return user;
    }
}

Java内存泄露

问题的提出
Java的一个重要优点就是通过垃圾收集器(Garbage Collection,GC)自动管理内存的回收,程序员不需要通过调用函数来释放内存。因此,很多程序员认为Java不存在内存泄漏问题,或者认为即使有内存泄漏也不是程序的责任,而是GC或JVM的问题。其实,这种想法是不正确的,因为Java也存在内存泄露,但它的表现与C++不同。
随着越来越多的服务器程序采用Java技术,例如JSP,Servlet, EJB等,服务器程序往往长期运行。另外,在很多嵌入式系统中,内存的总量非常有限。内存泄露问题也就变得十分关键,即使每次运行少量泄漏,长期运行之后,系统也是面临崩溃的危险。
Java是如何管理内存
为了判断Java中是否有内存泄露,我们首先必须了解Java是如何管理内存的。Java的内存管理就是对象的分配和释放问题。在Java中,程序员需要通过关键字new为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。另外,对象的释放是由GC决定和执行的。在Java中,内存的分配是由程序完成的,而内存的释放是有GC完成的,这种收支两条线的方法确实简化了程序员的工作。但同时,它也加重了JVM的工作。这也是Java程序运行速度较慢的原因之一。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。
监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。
为了更好理解GC的工作原理,我们可以将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从main进程开始执行,那么该图就是以main进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。
以下,我们举一个例子说明如何用有向图表示内存管理。对于程序的每一个时刻,我们都有一个有向图表示JVM的内存分配情况。以下右图,就是左边程序运行到第6行的示意图。

java memory

java memory


Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。这种方式的优点是管理内存的精度很高,但是效率较低。另外一种常用的内存管理技术是使用计数器,例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。
什么是Java中的内存泄露
下面,我们就可以描述什么是内存泄漏。在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
在C++中,内存泄漏的范围更大一些。有些对象被分配了内存空间,然后却不可达,由于C++中没有GC,这些内存将永远收不回来。在Java中,这些不可达的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。
通过分析,我们得知,对于C++,程序员需要自己管理边和顶点,而对于Java程序员只需要管理边就可以了(不需要管理顶点的释放)。通过这种方式,Java提高了编程的效率
内存泄露

内存泄露


因此,通过以上分析,我们知道在Java中也有内存泄漏,但范围比C++要小一些。因为Java从语言上保证,任何对象都是可达的,所有的不可达对象都由GC管理。
对于程序员来说,GC基本是透明的,不可见的。虽然,我们只有几个函数可以访问GC,例如运行GC的函数System.gc(),但是根据Java语言规范定义, 该函数不保证JVM的垃圾收集器一定会执行。因为,不同的JVM实现者可能使用不同的算法管理GC。通常,GC的线程的优先级别较低。JVM调用GC的策略也有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC。但通常来说,我们不需要关心这些。除非在一些特定的场合,GC的执行影响应用程序的性能,例如对于基于Web的实时系统,如网络游戏等,用户不希望GC突然中断应用程序执行而进行垃圾回收,那么我们需要调整GC的参数,让GC能够通过平缓的方式释放内存,例如将垃圾回收分解为一系列的小步骤执行,Sun提供的HotSpot JVM就支持这一特性。
下面给出了一个简单的内存泄露的例子。在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个Vector中,如果我们仅仅释放引用本身,那么Vector仍然引用该对象,所以这个对象对GC来说是不可回收的。因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null。

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
	Object o=new Object();
	v.add(o);
	o=null;
}

Java和云计算的关系

Java是一种程序设计语言,云计算是一种新的商业计算模型和服务模式。他们实际上是没有直接关系的,但是由于Java 技术具有卓越的通用性、高效性、平台移植性和安全性,并且广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、智能手机、物联网和互联网,同时拥有全球最大的开发者专业社群。在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景,Java已经成为一个庞大而复杂的技术平台。
hadoop hadoop
Java与云计算的关系主要体现在以下几个方面:
Java在云计算中的优势:
Java使云计算更简单,Java具有简单性、兼容性、简易性、安全性、动态性、高性能、解释性、健壮性
Java与分布式计算:
基于JAVA的分布式程序设计:
基于Socket的编程
基于RMI的分布式编程
基于CORBA的分布式编程
Java与并行计算:
JDK 1.5引入java.util.cocurrent包
Java中的多线程技术实现并行计算( JET 平台)
Java SE 5 中的锁,原子量 并行容器,线程调度 以及线程执行
基于Java的分布并行计算环境Java PVM
云计算开源框架支持:
Hadoop是Java开发,很多其他的云计算相关开源软件也是由Java开发或者提供Java API
Java使得云计算的实现更为简单,而云计算让Java更有活力,找到一个新的结合点。Java在互联网应用有
着独特的优势,而云计算是基于互联网的新的商业计算模型和服务模式,两者相结合,势必创造更大价
值。

java竖线分割字符串的问题

例1:
String[] paraStr = “6010;320100;A”.split(“;”);
System.out.println(Arrays.toString(paraStr));
输出:[6010, 320100, A]
Ok
例2:
String[] paraStr = “6010|320100|A”.split(“|”);
System.out.println(Arrays.toString(paraStr));
输出:[, 6, 0, 1, 0, |, 3, 2, 0, 1, 0, 0, |, A]
NO,和期望值相差甚远
例3:
String[] paraStr = “6010+320100+A”.split(“+”);
System.out.println(Arrays.toString(paraStr));
输出:
Exception in thread “main” java.util.regex.PatternSyntaxException: Dangling meta character ‘+’ near index 0
+
异常!
有现象,才能总结出结论:
使用String.split方法时要注意的问题
在使用String.split方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果。
我们看jdk doc中说明
public String[] split(String regex)
Splits this string around matches of the given regular expression.
参数regex是一个 regular-expression的匹配模式而不是一个简单的String,他对一些特殊的字符可能会出现你预想不到的结果:
1.用竖线 | 分隔字符串,你将得不到预期的结果。
2.用 * 分隔字符串运行将抛出java.util.regex.PatternSyntaxException异常,用加号 + 也是如此。
显然,| + * 不是有效的模式匹配规则表达式,用”\*” “\+”转义后即可得到正确的字符串结果。
“|” 分隔串时虽然能够执行,但是却不是预期的目的,得到的是每个字符的分割,而不是字符串,”\|”转义后即可得到正确的字符串结果。
还有如果想在串中使用””字符,则也需要转义.首先要表达”ab”这个串就应该用”a\b”,如果要分隔就应该这样才能得到正确结果:
String[] aa = “aaa\bbb\bccc”.split(“\\“);
注意:除了使用“\|”外,也可以用”[.]” 进行分隔!
如:
String[] paraStr = “6010|320100|A”.split(“[|]”);
String[] paraStr = “6010.320100.A”.split(“[.]”);
http://www.cnblogs.com/haitao-fan/archive/2013/01/27/2878537.html

Java系统程序员修炼之道

从2002开始接触Java学会HelloWorld这么经典的程序到如今不知不觉已经十年啦,十年中亲耳听到过不少大牛的演讲,见到过项目中的神人在键盘上运指如飞的编程速度,当时就被震撼了。当编程越来越成体力活,我们还能有自己的思想,还能修炼为Java系统级别的程序员嘛?学习与修炼以下知识与技能,帮你早日达成愿望。
一:Java语言学习
线程(thread),串行化,反射,网络编程,JNI技术,容器(Map,List, Iterator), 类加载器(ClassLoader),输入输出流,垃圾回收机制, 有比较深入的了解,最起码做过项目应用。有过Java项目的性能优化经验,最起码掌握一种性能监视工具的使用,熟悉JVM参数,最起码知道可以在JVM启动时指定不同垃圾回收机制,以及不同垃圾回收机制之间的差别,熟悉JVM参数优化。
二:J2EE方面
最好知道JDBC规范是怎么回事情,面对Oracle数据库如果告诉你JDBC驱动不能用了,你还知道有OCI驱动可以。掌握常见的SQL语句,熟悉JMS, JNDI等组件,掌握一套web开发模式,从前台到后台,有能力整合好这样的框架。理解并掌握MVC思想,像SSH已经实现了MVC的分层,几乎不需要你自己再实现,假设你开发一个简单的Swing程序,你能MVC就说明你真的掌握了MVC的精髓。有能力在J2EE前端开发中构建自己的MVC模式,知道什么是WEB2.0,知道什么是SOA, SaaS, SaaP等含义
三:理解并能合理运用设计模式,UML建模
知道并理解设计模式中蕴含的几种基本原则如:里氏替换原则, 开闭原则,合成复用原则,依赖倒置原则有很好的理解,并能举例说明。对常用的设计模式如工厂模式,单例模式,观察者模式,责任链模式,桥接模式等知道灵活运用,明白什么是回调(Callback)。最后用一位高人话来总结设计模式,它是为了让软件更容易被别人读懂,更容易维护而产生,设计模式本质是程序员之间的交流,如果A用工厂模式设计一个模块B来接替,A只要说该模块是工厂模式实现,B维护起来应该容易得多,所以设计模式是关于交流,不关于代码。切忌滥用设计模式。学会使用UML建模工具至少熟悉一种URL建模工具。
四:注重用户体验,掌握KISS原则,知道欧卡姆剃刀原则
顾客就是上帝这个口号我们已经喊了N年了,程序员的劳动成果最终也需要转换为服务提供给客户,用户体验至关重要,常常看到的场景是功能实现了,软件很难使用,程序员有个很充足的理由我不是美工,其实注重用户体验跟美工八杆子也打不到一起,FoxMail的成功在很大程度是用户体验的成功,友好,清晰的用户提示,强的容错与纠错设计是获得好的用户体验的不二法门。傻瓜相机顾名思义傻子都会使用,这个就著名的KISS原则(Keep it simple and stupid)意思是UI设计要简单明了,傻子一看就知道怎么用,想想我们做出来的东西,对照说明书都不知道怎么用。另外一个就是最著名的例子IPhone手机外观设计,是典型的欧卡姆剃刀设计原则来完成人机交互。
五:自动测试与软件配置管理(SCM)实现
知道什么是软件配置管理,知道Hudson – http://java.net/projects/hudson/运用该工具SCM,知道怎么获取测试代码覆盖率, Java有效代码行数(NCSS),完成firebug, JDepend等工具集成ant/maven。熟悉并注重在开发过程中使用JUnit单元测试,理解白盒测试规范。
六:熟悉常见的网络通信协议
HTTP协议,知道POST, GET的区别是什么,阅读过HTTP相关的RFC文档。学会使用sniffer工具查看数据包,帮助查找与调试程序,知道TCP与UDP的区别,知道并理解E-Mail发送与接受的协议如SMTP, POP3,IMAP等协议,了解MIME与Base64编码。知道组播是怎么回事情。
七:面向市场,永远对新技术保持渴望
计算机技术的发展日新月异,做为IT行业的软件开发人员要不断的给自己充电,更新自己的技术与时代保持同步,同时还要面向市场,华为总裁任正非说过-“华为的技术革新必须面向市场”,作为程序员同样要有市场意识,很多人都后悔没有在android刚出来的时候加以关注学习。那些很早关注android开发技术的很多程序员因此获得丰厚回报。如今HTML5得到越来越多的浏览器厂家支持,你是否已经跟上脚步,开始学习。
八:保持谦虚,三人行必有我师
乔帮主说他要保持初心,努力学习,我等更应该保持谦虚,IT技术发展日新月异,在你眼中不可能实现的技术,也许别人早已经有思路。保持谦虚就有机会吸取别人身上的长处,古人有云:满招损,谦受益。一个得道的高人更是说出了”下下人,上上智”的禅语。永远不要拒绝帮助你周围的人解决难题,解决难题是进步最快途径。不要放弃任何一次可以提升自己技术与能力的机会。
九:养成总结的习惯,不断反思
上学的时候老师常让写小结,也没总结出来所以然,以至于工作以后再也不提这档子事情,建议每个项目做完以后对自己都有个小结,总结自己在项目里面学到了什么,反问自己能不能完成在不需要别人帮助的情况下自己完成这样的系统搭建,是否熟悉与掌握项目中所用到的技术,即使有些东西不是你负责完成的但是什么也不能阻挡一颗求知的心,总结要尽量详细记录你遇到那些难题是怎么一个一个的解决的,下次再遇到你是否可以很快解决或者避免这样的问题。有总结才有提高,孔子曰:学而不思则罔,如果我们只是coding到吐血,不思考,不总结提高,永远不可能有能有本质提高,秦相李斯有云:“泰山不让土壤,故能成其大,河海不择细流,故能就其深”,点滴积累不断总结方能量变导致质变。
十:数学功底与算法知识
用任何编程语言开发应用,都离不开核心算法支持,很多国外的软件单单从UI上看,恐怕写几年程序的人都可以模仿,但是UI之下的那些真实深浅不一,相信不是你想模仿就可以模仿的,为什么我们越来越山寨,因为我们没有核心竞争力,对于程序员来说算法与数学显然是他最重要的核心竞争力之一。《算法导论》,《编程珠玑》等书绝对值得读十遍。微软亚洲研究院视觉计算组负责人在一次演讲中说到他们招人的标准是“三好学生– 数学好,编程好,态度好”。可是现实的普遍情况却是 – 微机原理闹危机,汇编语言不会变,实变函数学十遍。计算机基础知识被大家普遍忽视。从今天开始好好学习吧……
十一:Java代码反编译与代码保护
Java编译产生字节码,因而可以被轻松的逆向工程(反编译),微软的C#生产的DLL也一样可以被轻松反编译。正式由于这个原因产生了许多Java开源的代码保护工具,而Proguard是其中佼佼者,已经被google集成在android之中用于Java代码保护,访问这里了解更多:http://proguard.sourceforge.net/
十二:努力成为某个行业或者领域骨干
面对漫长的职业生涯,要想不被淘汰,必须具备一招鲜吃遍天下的能力,选择自己感兴趣的方向,努力而深入的研究,计算机技术发展到今天已经细分很细,努力研究一种Java开源框架或者开源HTTP服务器源码或者研究过网络爬虫源码或者WEBKIT内核,不愁没有人要你。如果你是非常了解金融,企业ERP,证券,保险,移动应用行业的应用开发业务的人,一样不用愁工作。这些知识不随语言而改变,努力做一个有核心竞争力的Java程序员。
十三:提高语言与书面表达能力,掌握基础的项目管理知识
文档与语言表达能力是最好的向外界展现自己能力的方式,很多程序员编程能力很高,表达能力一般,Linux能够成功,除了归功于网络社区的力量之外,也得益于Linux作者本人给各大基金会写信,宣传推广,试想如果没有良好的书面语言表达能力,即使Linux系统再优秀,却无法被准确表达,失去各大基金会的支持,Linux还会像今天这么好的局面嘛。所以重视文档,重视提升沟通与表达能力,才有可能成为Java系统程序员。掌握基本的2/8原则,学会将模块细化分配给不同的人,预见并控制项目风险,把握项目进度,优化流程,合理的时间管理,了解TDD,熟悉敏捷开发模式,常规软件开发模式。
十四:掌握英语,良好的读写能力
英语是计算机的母语,掌握好英语对于阅读英文资料学习新技术大有帮助,我的建议是尽量读英文原版书,如果是算法方面的可能会困难一点,但是其它像设计模式,软件工程,OO编程思想等尽量读原版,提高自己的英文水平,多多访问开发者,code project,程序员天堂,Pc-magazine等英文IT网站。英语绝对是你必须修炼与提高的技能。此外英语好在外资企业尤其重要,只有外语足够好才可能在外资企业中突破职业瓶颈,向上发展。
转自:http://bbs.csdn.net/topics/390103026

由一个漏洞引发的思考

最近项目比较紧,没时间来写博客,意味着思考少了。两件事:
1、struts2最近爆出了一个漏洞,线上版本必须修补。但是线上的版本源代码已经不可恢复了,新版本代码又没开发、测试完成,代码版本管理没有做好,即使是自己一个人做项目也应该管理好代码。版本控制非常重要,虽说上一个版本不一定好!
2、新版程序发现一个问题,这个问题是在开发过程中很容易忽略掉的,而且必须放在并发访问中才能出现的问题。另外,由于日志输出没做好,导致调试很费劲。简单描述下该问题:
三句话:
1)从连接池获取一个连接
2)将字符型数字转换为整型数字
3)获取连接,查询数据,释放连接
问题出现在第二句话上,当第二句转换失败抛异常时,并未被处理,而是直接抛回给上层调用方法,所以,连接更本就不会被释放掉,就出现了资源枯竭,死锁的状态。
总结下:
真应该好好学习java啊  多线程  异常处理和异常处理对于程序的影响  程序执行流程  动态代理  线程池死锁 还有什么链接生成、关闭  如何查看resin堆栈信息 
先把异常处理 和 适当输出日志 弄好,这个是靠经验的!
 

Java开发者不一定最适合Hadoop

JNAN DASH的一位(IBM数据仓库BI)专家朋友几周前参加了在圣何塞举行的Hadoop会议。两年前也是这个时间,他参加了当时在纽约的Hadoop会议,但当时仅有200人,而这次不仅有2000多人参加,并且门票早已销售一空。显然,这很直观地证明了Hadoop会议引发了业内高度的兴趣。不止如此,他发现每一个主题演讲的PPT中有关Hadoop技术的幻灯片中都提到“我们正在招聘(we are hiring)”。
人才缺乏由此可见一斑。作为一个能够对大量数据进行分布式处理的软件框架,Hadoop可靠、高效而可伸缩。由于Hadoop很容易实现对搜索关键字进行内容分类,并可以通过并行处理加快处理速度,所以受到更行业的欢迎。而Hadoop带有用Java 语言编写的框架,因此在Linux生产平台上很理想。而在Hadoop上的应用程序也可以使用其他语言编写,比如 C++。
事实上,Hadoop使廉价服务器的大规模并行计算成为可能。企业可以收集更多的数据,保留时间可以更长,并对所有数据可以进行之前由于成本、复杂性和缺乏工具而无法进行的分析。互联网企业几乎都是Hadoop的用户,而如eBay、Facebook、LinkedIn、Netflix和Twitte的创新型尝试也为其他数据密集型行业,如金融、科技、电信和政府的应用铺平了道路。越来越多的IT人发现,Hadoop已经在其架构规划中占据一席之地。但Hadoop成为绝对主流的另一大挑战是,如何找到擅长这一技术的专业人才。
Cloudera、IBM、Hortonworks、MapR是值得关注的四家Hadoop企业。而这几家都有大量投资于培训计划,教IT专业人员如何部署,配置和管理Hadoop的产品。显然,这些企业清楚地认识到,人才将是限制Hadoop企业级应用发展不容回避的问题。
但另一面,Cloudera的客户解决方案副总裁Omer Trajman却表示:“直接雇佣新人是不可思议的。”在他看来,“最可行的办法是在企业内部寻找人才来学习Hadoop。”因为,“最成功的公司一般不需要大举招聘。因为在企业内部,完全可以了解员工的基本技能,比如谁有科学、统计、数据处理、利用Java来开发和分析的背景,找到这些已经在相关业务领域中拥有专门知识的人才,然后再做Hadoop培训,教会他们如何使用Hadoop工具,就可以成为合格的人才。”
当然,随着对Hadoop的重视程度更高,业内学习Hadoop的人也在增加。相关业内人士表示:“几年前我在面试技术人员时,问他们是否认识Hadoop?而通常的答案是ha-what?但是如今,知道和运用Hadoop的人已经越来越多了。”
不过,问题也随之而来。企业需要明确什么样类型的人是适合招聘的Hadoop人才?
“我们原以为需要找一个铁杆的Java开发者”,MapR商业分销Return Path的负责人表示,“但事实并非如此。最适合Hadoop的人才不一定是Java工程师。反而是那些能够理解集群、收集一些工具,指出如何实现协同工作,并能处理Hadoop生态系统中出现的许多问题,而并不仅限于Hadoop 1.0的人才是我们需要的技能型人才。”
这篇文章发表在:2012-07-13