Archive

Author Archive

Appfuse 乱码问题

September 9th, 2011 leeing No comments

Appfuse是一个辅助快速开发的JAVA EE框架,本文主要阐述在Appfuse中出现的字符编码问题。

1.    DisplayTag表格导出Excel乱码问题。

 

(项目搭建初期导出的Excel中文会乱码)

解决方法:在项目的根目录中的pom.xml中加入一个依赖:

<dependency>

<groupId>displaytag</groupId>

<artifactId>displaytag-export-poi</artifactId>

<version>1.2</version>

</dependency>

同时,修改displaytag.properties ,在此文件中增加一行:export.excel.class=org.displaytag.export.excel.ExcelHssfView。

2.    DisplayTag表格上方出现乱码。 

 

在项目搭建的初始阶段,表格上方的”共找到。。。到。。条”这些全是乱码。

在Netbeans中打开displayTag.zh_CN.properties,看到的也全是乱码。

解决方法是,用记事本打开这个文件,另存为UTF-8格式;注意Netbeans对这种编辑方式支持并不好,所以直接使用记事本更简单快捷。

3.    在jsp文件中,输入中文时,提示保存为ISO-8859-1的格式,在部署页面中出现乱码。 

 

 

 

在Netbeans中如果直接保存会产生乱码。

解决方法:用记事本或其它文本编辑器,直接在此jsp文件中输入中文并保存为UTF-8格式即可。

但是请注意,由于JSTL已经提供了良好的i18N功能,在默认情况下,最好使用<fmt:message value=”">的形式,而不是直接在页面中使用中文。

4.    NamedQuery的字符编码问题

queryParams.put(“runningStatus”, “作为备件”) // 这种写法无法查询出结果

解决方案:

String temp = new String(“作为备件”.getBytes(), “UTF-8″); // 必须用这种方式

queryParams.put(“runningStatus”, temp);

NameQuery 主要出现在 model包下,具体请查看相应的源代码。

5.    Appfuse提供了文件上传功能,但没有提供文件下载功能。在自己写了个文件下载功能以后,文件下载时文件名,中文名会乱码

解决方案:

response.setHeader(“Content-Disposition”, “attachment;fileName=”+java.net.URLEncoder.encode(name, “UTF-8″));

其中,name为保存文件名的变量。

6.    MySQL中文问题

重新运行并配置MySQL,将默认的字符编码设置为UTF-8格式,并确保导入的数据也是UTF-8格式。

PS:本文是用 Word 2010 发表的,不过感觉没有 Windows live writer 好用。

 

Categories: Java EE Tags:

一道面试题:List 中的 Remove 方法

June 16th, 2011 leeing 2 comments

有一道题,是关于 List.remove( int ) 和 List.remove (Object ) 两个方法的,在 List 的元素类型为 Integer 的时候,究竟调用的哪个 API,即:删除对应的整数,或者是删除对应下标的元素 ?

下边来看 List 接口出现的 API:

remove
E remove(int index)
移除列表中指定位置的元素(可选操作)。将所有的后续元素向左移动(将其索引减 1)。返回从列表中移除的元素。
参数:
index – 要移除的元素的索引
返回:
以前在指定位置的元素
抛出:
UnsupportedOperationException – 如果列表不支持 remove 操作
IndexOutOfBoundsException – 如果索引超出范围 (index < 0 || index >= size())

 

remove
boolean remove(Object o)
从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。如果列表不包含元素,则不更改列表。更确切地讲,移除满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引 i 的元素(如果存在这样的元素)。如果此列表已包含指定元素(或者此列表由于调用而发生更改),则返回 true
指定者:
接口 Collection<E> 中的 remove
参数:
o – 要从该列表中移除的元素,如果存在的话
返回:
如果列表包含指定的元素,则返回 true
抛出:
ClassCastException – 如果指定元素的类型和此列表不兼容(可选)
NullPointerException – 如果指定的元素是 null,并且此列表不允许 null 元素(可选)
UnsupportedOperationException – 如果列表不支持 remove 操作

好吧,问题如下:

Read more…

Categories: Java Tags:

Hadoop平台优化综述 (2)

May 12th, 2011 leeing No comments

4.     从系统实现角度进行优化

4.1    在可移植性和性能之间进行权衡

论文[16]主要针对HDFS进行了优化,它分析了HDFS性能低下的两个原因:调度延迟和可移植性假设。

(1) 调度延迟

Hadoop采用的是动态调度算法,即:当某个tasktracker上出现空slot时,它会通过HEARBEAT(默认时间间隔为3s,当集群变大时,会适当调大)告诉jobtracker,之后jobtracker采用某种调度策略从待选task中选择一个,再通过HEARBEAT告诉tasktracker。从整个过程看,HDFS在获取下一个task之前,一直处于等待状态,这造成了资源利用率不高。此外,由于tasktracker获取新task后,其数据读取过程是完全串行化的,即:tasktracker获取task后,依次连接namenode,连接datanode并读取数据,处理数据。在此过程中,当tasktracker连接namenode和datanode时,HDFS仍在处于等待状态。

为了解决调度延迟问题,可以考虑的解决方案有:重叠I/O和CPU阶段(pipelining),task预取(task prefetching),数据预取(data prefetching)等

(2)可移植性假设

为了增加Hadoop的可移植性,它采用java语言编写,这实际上也潜在的造成了HDFS低效。Java尽管可以让Hadoop的可移植性增强,但是它屏蔽了底层文件系统,这使它没法利用一些底层的API对数据存储和读写进行优化。首先,在共享集群环境下,大量并发读写会增加随机寻道,这大大降低读写效率;另外,并发写会增加磁盘碎片,这将增加读取代价(HDFS适合文件顺序读取)。

为了解决该问题,可以考虑的解决方案有:修改tasktracker上的线程模型,现在Hadoop上的采用的模型是one thread per client,即每个client连接由一个线程处理(包括接受请求,处理请求,返回结果);修改之后,可将线程分成两组,一组用于处理client通信(Client Thread),一组用于存取数据(Disk Threads,可采用one thread per disk)。

Read more…

Categories: hadoop Tags:

Hadoop平台优化综述 (1)

May 12th, 2011 leeing 1 comment

1.     概述

随着企业要处理的数据量越来越大,MapReduce思想越来越受到重视。Hadoop是MapReduce的一个开源实现,由于其良好的扩展性和容错性,已得到越来越广泛的应用。Hadoop作为一个基础数据处理平台,虽然其应用价值已得到大家认可,但仍存在很多问题,以下是主要几个:

(1)     Namenode/jobtracker单点故障。 Hadoop采用的是master/slaves架构,该架构管理起来比较简单,但存在致命的单点故障和空间容量不足等缺点,这已经严重影响了Hadoop的可扩展性。

(2)     HDFS小文件问题。在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有1000 0000个小文件,每个文件占用一个block,则namenode需要2G空间。如果存储1亿个文件,则namenode需要20G空间。这样namenode内存容量严重制约了集群的扩展。

(3)     jobtracker同时进行监控和调度,负载过大。为了解决该问题,yahoo已经开始着手设计下一代Hadoop MapReduce(见参考资料1)。他们的主要思路是将监控和调度分离,独立出一个专门的组件进行监控,而jobtracker只负责总体调度,至于局部调度,交给作业所在的client。

(4)     数据处理性能。 很多实验表明,其处理性能有很大的提升空间。Hadoop类似于数据库,可能需要专门的优化工程师根据实际的应用需要对Hadoop进行调优,有人称之为“Hadoop Performance Optimization” (HPO)。

为了提高其数据性能,很多人开始优化Hadoop。总结看来,对于Hadoop,当前主要有几个优化思路:

(1)  从应用程序角度进行优化。由于mapreduce是迭代逐行解析数据文件的,怎样在迭代的情况下,编写高效率的应用程序,是一种优化思路。

(2)  对Hadoop参数进行调优。当前hadoop系统有190多个配置参数,怎样调整这些参数,使hadoop作业运行尽可能的快,也是一种优化思路。

(3) 从系统实现角度进行优化。这种优化难度是最大的,它是从hadoop实现机制角度,发现当前Hadoop设计和实现上的缺点,然后进行源码级地修改。该方法虽难度大,但往往效果明显。

以上三种思路出发点均是提高hadoop应用程序的效率。实际上,随着社会的发展,绿色环保观念也越来越多地融入了企业,因而很多人开始研究Green Hadoop,即怎样让Hadoop完成相应数据处理任务的同时,使用最少的能源(见参考资料[14][15])。

本文主要介绍了当前学术界的一些优化思路,有人试图从Hadoop自动配置角度对Hadoop进行优化,但更多的是从系统实现角度进行优化,概括其优化点和实验效果如下:

Read more…

Categories: hadoop Tags:

PeerSim 源代码分析之一:程序入口

March 17th, 2011 leeing No comments

PeerSim 的文档资料很少,有很多地方看上去概念很模糊,去年曾经翻译过官方的几篇文档,按顺序汇总如下:

当时翻译的时候,并没有深入地去学习,最近由于仿真的需要,又静下心来研究了几天,有些东西发现在文档中是无法得到一个很清晰的解释,看了一下PeerSim的源代码规模也并不是很大,所以决定 RTFSC (Read the F *** ing Source Code : –) ,源代码本身就是最好的学习资料,当然,这需要足够的耐心。

不过不得不说的是 PeerSim 的源代码的缩进真是有点混乱。

首先,是程序的入口 peersim.Simulator.java:

package peersim;

import java.io.*;

import peersim.cdsim.*;
import peersim.config.*;
import peersim.core.*;
import peersim.edsim.*;

/**
 * peersim.Simulator.java
 *
 * 程序的入口,主要作用就是读取配置文件,并根据仿真类型来调用仿真引擎。
 */
public class Simulator {

    // 某些静态变量,一看就懂。

    public static final int CDSIM = 0;

    public static final int EDSIM = 1;

    public static final int UNKNOWN = -1;

    protected static final String[] simName = {
        "peersim.cdsim.CDSimulator",
        "peersim.edsim.EDSimulator",};

    // 配置文件中的 simulation.experiments 参数,如果没有标明,则默认为
    // 进行1次实验
    public static final String PAR_EXPS = "simulation.experiments";

    // 设置程序的输出,默认为 stdout
    public static final String PAR_REDIRECT = "simulation.stdout";

    // 仿真类型,有3种,即 CDSIM,EDSIM 和 UNKNOWN
    private static int simID = UNKNOWN;

    // 根据配置文件返回当前的仿真类型
    public static int getSimID() {

        if (simID == UNKNOWN) {
            // 怎么判断类型?很简单,看配置文件里有没有
	    // 定义 simulation.cycles 的参数
            if (CDSimulator.isConfigurationCycleDriven()) {
                simID = CDSIM;
            } else if (EDSimulator.isConfigurationEventDriven()) {
                // 类似的,如果配置文件里有 simulation.endtime 的定义,
                // 就是 Event-driven 模式
                simID = EDSIM;
            }
        }
        return simID;
    }

    // 程序的入口,运行时要将配置文件的位置作为参数提供给 Simulator
    public static void main(String[] args) {
        long time = System.currentTimeMillis();

        System.err.println("Simulator: loading configuration");

        // 读入配置文件
        Configuration.setConfig(new ParsedProperties(args));

        // 设置输出到某一个 PrintStream,默认为 System.out
        PrintStream newout =(PrintStream)
		Configuration.getInstance(PAR_REDIRECT, System.out);

        if (newout != System.out) {
            System.setOut(newout);
        }

        // 设置实验的次数,默认为1次,可以通过设置 simulation.experiments
		// 来改变默认值。
        // 在这里说一下,PeerSim 的配置文件学习是第一步,想要编写仿真
        // 首先就要明白 PeerSim 是如何解析配置文件的,具体的解析可以看
        // peersim.config 包里边的类。
        int exps = Configuration.getInt(PAR_EXPS, 1);

        // 读取实验的类型,如果不能确定仿真类型,就退出。
        final int SIMID = getSimID();
        if (SIMID == UNKNOWN) {
            System.err.println(
    	"Simulator: unable to determine simulation engine type");
            return;
        }

        try {

            for (int k = 0; k < exps; ++k) { // 一次循环进行一次实验
                if (k > 0) {
                    // 仿真过程中的种子,可以通过在配置文件中的
		    	// random.seed 来设置。
                    // 如果不设置的话,就将当前的时间作为种子
                    long seed = CommonState.r.nextLong();
                    CommonState.initializeRandom(seed);
                }
                System.err.print(
			"Simulator: starting experiment " + k);
                System.err.println(" invoking " + simName[SIMID]);
                System.err.println("Random seed: "
			+ CommonState.r.getLastSeed());
                System.out.println("\n\n");

                // 作者说可以用反射机制的,不过这样写容易理解。
  			// 我个人觉得没必要用反射。
                // 根据仿真的类型,调用相应的仿真引擎。
                switch (SIMID) {
                    case CDSIM:
                        CDSimulator.nextExperiment();
				// 具体怎么运行且听下文分解
                        break;
                    case EDSIM:
                        EDSimulator.nextExperiment();
				// 同上
                        break;
                }
            }

        } catch (MissingParameterException e) {
            System.err.println(e + "");
            System.exit(1);
        } catch (IllegalParameterException e) {
            System.err.println(e + "");
            System.exit(1);
        }

        // undocumented testing capabilities
        // 这一部份源码没有任何说明,看样子作者是用来做测试的
        if (Configuration.contains("__t")) {
            System.out.println(System.currentTimeMillis() - time);
        }
        if (Configuration.contains("__x")) {
            Network.test();
        }

    }
}

好吧,程序的入口就分析到这里。下次就分析 Cycle-based 仿真核心 CDSimulator 的代码。

Categories: PeerSim Tags: