说实话写Java程序总是大手大脚的,很少在乎内存。以前最多就是用system.gc()命令,今天看一个开源的程序,无意中发现作者在写Java时也用了很多查看内存的方法,这里转载一篇相关的文章。

最近在网上看到一些人讨论到java.lang.Runtime类中的 freeMemory(),totalMemory(),maxMemory()这几个方法的一些问题,很多人感到很疑惑,为什么,在java程序刚刚启 动起来的时候freeMemory()这个方法返回的只有一两兆字节,而随着java程序往前运行,创建了不少的对象,freeMemory()这个方法 的返回有时候不但没有减少,反而会增加。这些人对freeMemory()这个方法的意义应该有一些误解,他们认为这个方法返回的是操作系统的剩余可用内 存,其实根本就不是这样的。这三个方法反映的都是java这个进程的内存情况,跟操作系统的内存根本没有关系。下面结合 totalMemory(),maxMemory()一起来解释。
maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操作系统那里挖到的最大的内存。如果添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。
totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有 内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖 -Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。
freeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程 序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可 能会有些大。
把下面的源代码编译以后,在class文件所在的目录里面,分别用java -cp . Untitled1 和java -cp . -Xms80m -Xmx80m Untitled1 运行,看看结果如何,有助于理解上面的阐述。
public class Untitled1 {
    public Untitled1() {
    }

    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().freeMemory());
        System.out.println(Runtime.getRuntime().totalMemory());
        System.out.println(Runtime.getRuntime().maxMemory());
        long t = System.currentTimeMillis();
        try {
            Thread.sleep(30000);
        } catch (Exception ee) {
            ee.printStackTrace();
        }
        String[] aaa = new String[2000000];
        System.out.println(Runtime.getRuntime().freeMemory());
        System.out.println(Runtime.getRuntime().totalMemory());
        System.out.println(Runtime.getRuntime().maxMemory());
        try {
            Thread.sleep(30000);
        } catch (Exception ee) {
            ee.printStackTrace();
        }
        for (int i = 0; i < 2000000; i++) {
            aaa[i] = new String("aaa");
        }
        System.out.println(Runtime.getRuntime().freeMemory());
        System.out.println(Runtime.getRuntime().totalMemory());
        System.out.println(Runtime.getRuntime().maxMemory());
        try {
            Thread.sleep(30000);
        } catch (Exception ee) {
            ee.printStackTrace();
        }
    }

}

原文链接:http://blog.sina.com.cn/s/blog_473d30e1010007dm.html

LaTeX 的对参考文献的处理

Posted by 冰河 at 21:34 No Responses » 38,555 Views
252010
    LaTeX 的对参考文献的处理实在是非常的方便,我用过几次,有些体会,写出来供大家
参考。当然,自己的功力还不够深,有些地方问题一解决就罢手了,没有细究。

    LaTeX 对参考文献的处理有这么一些优点:

1. 可以维护一个 bib 文件,在你的整个研究生涯可以只维护这样一个文件,就象一个数
据库,每个参考文献是一个记录,由一个唯一的 ID (例如下面的 MartinDSP00)描述。
比如我的 myreference.bib 文件里一条典型的文献是这样的:

@article{MartinDSP00,
     author = "A. Martin and M. Przybocki",
     title = "The {NIST} 1999 speaker recognition evaluation --- an overview",

     journal = "Digital Signal Processing",
     volume = "10",
     pages = "1--18",
     year = "2000",}
    
    其中 {NIST} 中的大括号不会被显示,它的作用是保证将来的生成的参考文献中 NIST
 四个字保持原样,不会被小写。

2. 需要引用文献的时候,在正文里加入:

ibliographystyle{ieeetr}
ibliography{myreference}

    就可以用 cite{} 来引用文献库中的论文了,如 cite{MartinDSP00}。上面第一行是
控制文献显示格式的,这个后面再讲。此时,myreference.bib 文件在正文 tex 文件的同
一目录下,以保证 LaTeX 可以找到该 bib 文件。

3. 编译正文之后,生成 aux 文件,然后用 bibtex 在当前目录生成 bbl 文件,再编译正
文两次,完整的 dvi 就生成了。这样,LaTeX 保证了所有用 cite 引用到的文献都已被
列出,并且自动编号。同时,如果没有用
ocite 命令,LaTeX 还保证所有列出的参考文
献都在正文中得到了引用。

4. 关于 bib 文件
    前面提到 bib 文件的维护问题。我一般不对里面的文献排序,如果文献比较多,需要
查找的话,可以通过查询关键字来实现。bib 文件把 @ 所定义的 entry 之外的所有东西
看作是注释。比如在上面 @article 的例子里,如果我在大括号之外写些东西的话,bibt
ex 是不会关心的,就当它不存在。所以我就把文献的关键字写在这里,将来通过搜索关键
字来查找某些文献。其实也可以搞一个临时的 LaTeX 文件,使用
ocite{*} 命令,然后
编译成 dvi,这样就得到了一个 bib 文件中所有参考文献的列表,当然是可以按照作者名
字排序的。
    另外,很多 journal(学术期刊)或者 booktitle(国际会议)都是重复的,为了规范
化,可以定义缩写,如

@string(ICASSP = "Proc. of the International Conference on Acoustics, Speech,
and Signal Processing (ICASSP)")

    然后
   
    @conference{QL.ICA98,
     author = "Qi Li and Biing-Hwang Juang",
     title   = "Speaker Verification Using Verbal Information Verification for A
utomatic Enrollment",
     booktitle = ICASSP,
     year = "1998",}

    这样在执行 bibtex 之后,ICASSP 会被替换成它的全称。

5. bib 中的中文文献
    中文文献和英文的格式不同,并且使用全角的标点符号,有一点难办。我的解决办法是
这样的:

    @misc{Xie.1995,
     note = "谢锦辉,《隐 {Markov} 模型及其在语音处理中的应用》,华中理工大学出
版社,1995年4月",
     key = "Xie",}

    唯一的缺陷是参考文献中最后是以英文的 "." 而不是 "。" 结束的。还好我的中文文
献不多,无伤大雅,否则就手工修改一下 bbl 文件吧。

6. 关于参考文献的显示格式、排序,及其他
    前面提到参考文献的排序问题,以及引用序号是 LaTeX 提供的 ID 还是数字的问题。
其实不止这些,参考文献的显示格式也是可以定制的。参考文献以正文中引用顺序排序,
还是以文献第一作者的 last name 排序,是通过一些 bst 文件来控制的。而使用哪种 b
st 格式,可通过 bibliographystyle 命令控制。LaTeX 默认提供了这么几种格式,如:
plain、alpha、unsrt等。具体意义见相关文档,这些 bst 在 texmfibtexstase 可
被找到。
    bst 控制的格式非常细致,除了上面讲过的排序方式等,还有:作者名字是否用缩写,
作者名字放在文献的起始还是结束,文章 title 要不要大小写(即 "Speaker Verificat
ion Using ..." 还是 "Speaker verification using "),title 用什么区分(用不用引
号括起来,用不用斜体等),刊物名字的格式(要不要全部大写,要不要粗体,要不要斜
体,要不要括起来),等等等等。打开 bst 文件看一下就知道,绝对是想要什么形式,就
可以得到什么形式。最关键的是,在文章定稿之后,完全可以用几个命令重新定义参考文
献的格式!
   
    给个例子:采用 IEEE 给出的 bst 格式(即 ieeetr.bst),声明:

ibliographystyle{ieeetr}

    就可以使用了。最终格式是这样的(按正文引用顺序排序):
    [4] D. A. Reynolds, "Comparison of background normalization
        methods for text-independent speaker verication," in
        EUROSPEECH, 1997.
       
7. 如何定制参考文献的显示格式
    其实 bst 文件有很多,总能找到自己需要的。如果这些还不能满足,可以通过生成自
己的 bst 文件来定制。这有两个方法,第一是手写(反正我是写不出来),第二是通过工
具。custom-bib 是一个定制 bst 文件的包,解压缩后用 LaTeX 编译其中的主 tex 文件
,便会进行交互式的 bst 定制过程,具体过程我就不讲了。把生成的自定义的 bst 放到
 LaTeX 相应目录下,刷新文件名数据库就可以使用了。

原文链接:http://xb9he.bokee.com/6688578.html

Latex:表格制作全攻略

Posted by 冰河 at 16:29 8 Responses » 82,093 Views
212010

给出一个制作复杂表格的例子,制作表格主要用到multicolumn,multirow和cline,其中,要使用multirow,必须usepackage{multirow}

如果要制作出如下图所示的表格:

Latex表格制作全攻略

则可以通过如下的代码:

\begin{table*}

\begin{tabular}{|c|c|c|c|c|}

hline hline

multirow{2}{*}{Multi-Row} & multicolumn{2}{|c|}{Multi-Column} & multicolumn{2}{|c|}{multirow{2}{*{Multi-Row and Col}} \

cline{2-3}

& column-1 & column-2 & multicolumn{2}{|c|}{} \

hline

label-1 & label-2 & label-3 & label-4 & label-5 \

hline

end{tabular}

end{table*}

其中,multirow{2}{*}{text}的第一个参数表示行的数目,*表示由系统自动调整文字,text表示要写入的文字

multicolumn与multicolumn类似,功能是跨多列, multicolumn{2}{|c|}{text}表示跨2行,文字采用中心对齐的方式,text是要写入的文字。

multicolumn和multirow可以组合使用,跨多行多列,只需要将multirow作为multicolumn的text即可。

最后,cline用于画横线 cline{i-j}表示从第i列画到第j列。

hline画一整条横线。

multicolumn使用比较简单,因为latex的表格本来就是按行组织的。下面附上multirow的使用文档:

http://www.ctex.org/documents/packages/table/multirow.htm

学好VC++的十大良好习惯

Posted by 冰河 at 21:02 No Responses » 3,615 Views
142010

每到年底各大媒体就争先恐后热火朝天地搞总结,什么十大人物,十大品牌,十大美女,十大帅哥等等五花八门乱七八糟的让人充满好奇充满怀疑,这事确实让人有点郁闷,就如同男足国家队的国产教练如沈墙扶们每一次踢球失败后都要说这么一句:我们回去后要好好总结,下次会打得更好! 这话听了几十年了,耳朵都生虫了,但还是无法看到中国猪球队有象人样的表现.因此,总结在某一程度上来说只不过是一种形式罢了,总结不代表就能改过原有的不足,也不代表就能进步了,甚至有点俗不可耐,尽管如此,阿蒙亦明知故俗,前人说过了入乡了就要随俗,因此你生活在这种环境里,你无法对这些无聊无趣的东东置之不理,除非你是天才,天才往往在非天才的人看来是很怪异的,处处与现实格格不入,可阿蒙不是天才,所以还得赶快总结,要不就离题,又被大家骂了,:)

(一)充分利用MSDN,因为我个人觉得它胜过任何一本编程参考书; MSDN是 Microsoft 当前提供的有关编程信息的最全面的资源,它包含微软最新的技术数据库,加上易学易用的全文检索功能,让您迅速找到任何您需要的技术参考数据,让您随时拥有与全世界菁英同步的技术,掌握最丰富的程序开发资源。我经常收到很多朋友的EMAILS,他们所提的问题往往都非常的简单,MSDN完全可以解答这些问题,但他们好象不太喜欢用,这是让我郁闷的地方,是因为英文不好呢,还是没有学会充分利用各种资源来解决问题的方法呢?

(二)提高英文水平,养成多上英文网站多看英文资料多买老外原版英文书; 有关程序员与英文水平的讨论已太多太多, 我个人认为要成为程序员,高中的英语水平够了,甚至不懂英语的一些人,也同样可以成为较好的程序员,因为开发工具的发展将是越来越傻瓜,但如果你是仅仅满足于能运用某种工具开发某个软件模块,那是没话说了.真正热衷技术肯干钻研乐于接受挑战的程序员是不满足于现状的,他们总感觉有太多的未知,于是总在不停地学习,如今信息技术发展得太快,而大部分的技术最先出现的时候都是英文版本的,要几个月或者几年以后才有中文版本的书出来,因此要想跟上步伐,一定要努力提高自己的英文水平,这样才能同步跟上信息技术。你可能担心自己的英语水平不行,没关系,刚开始多查字典,"万事开头难",必须有持之以恒的精神,不久你就会发现计算机英语其实很容易的。何况很多 英文技术站点确实比国内做得好啊!比如http://www.codeguru.com, http://www.codeproject.com, http://www.programmersheaven.com 等等.

(三)加强自我管理,善于作自我总结,分析自已的优点及缺点。 中国境内百分之八十以上的领导人在百分之八十以上的场合的讲话中都有类似的观点,所以在这里我是不多说了,反正这一条用在什么行业什么地方都不会有错的,人生最大的敌人不是就是自已吗?管好自已认清自已,那还有什么搞不定的?

(四)养成良好的文档习惯 程序员大多都不喜欢写文档,我以前也是特讨厌,在我的思想里,所谓的文档就是一些废话,一句话硬是用十句话来代替的无聊透顶,就如同部分中文系男生的爱情表白,明明就是"我爱你"三个字,他硬是把月亮啊太阳啊大海啊高山啊石头啊天使啊乱七八糟的都拉上关系了,尽管听起来浪漫,但在我认为不实用,:), 甚至太肉麻了,一个男子汉干嘛这么罗里罗嗦的……良好的文档是正规研发流程中非常重要的环节,一个好的程序是先写好设计文档再进行编程的,在设计文档的指导下,才能写出安全的代码。如果你不写文档,一开始就写程序,这样你就不会按已设计好的路线走,而是想到哪写到哪。小功能还好说,要是大功能,就容易混乱甚至失控.那么如何写文档呢?其实我认为没有统一的标准,虽然国家及一些NB的人总结了很多的模板,但每个人的习惯不同,如果你不加以修改或创新,就套用某个标准,我相信写起来会很吃力及说不清的难受,因此我觉得只要能将你的设计思想及实现算法或步骤描述清楚就是好的文档,我强烈建议广大程序员朋友们在写文档时要善于用图表来说明你的思想,我们不是作家,也可能作文都经常性地不及格,写出五官端正的文章对我们来说可能不容易啊!好好地利用 VISIO,ROSE或别的工具来表达你的思想吧!

(五)代码风格要规范,严谨,效率要高。 这个不用说了,所以一定要记住了!不过,这一点有时可能与人的性格有关,如果你是经常丢三落四经常胡子长长经常钮扣扣错经常吃个快餐要一个小时的人,那你在CODING的时候可千万要注意了,CODING是CODING,生活是生活,不要写出的程序也是那样就不好了!

(六)掌握好跟踪调试技巧. 跟踪调试程序是一件繁琐而又复杂的事情,所以掌握必要的调试策略及技巧却可以使这些工作变得轻松起来.强烈建议你去看一下老美Everett N.McKay及Mike Wooding写的书<>,你一不定受益匪浅.

(七)养成自我测试的习惯 测试工作应由测试工程师来做,但在你写完一个模块或一个软件时,还是要自已先测试一下,保证不要出现一些低级的错误,何况这些错误让测试工程师看到了,狂扁你一顿,你很没FACES的.

(八)善于交流善于沟通,特别是经常与一些高手交流一下学习的心得体会; 有人说,程序员的性格大多内向不喜欢说话,其实是有些误会了,不是不喜欢而是话不投机,我的脑袋一天到晚都在不停地转,函数,数据,算法啊充满了我的世界, 我那还有时间与你谈一些无聊的话题,话要找对人了,才容易谈下去,书上说过"听君一席话,胜读十年书",你要找的就是这种豁然开朗!现在技术的论坛越来越来,这将成为程序员交流一个重要的地方,也有人说:"读君一长贴,胜读十年书",:)

(九)阶段性地做一下专题总结 知识要温故而知新,因此我建议程序员要养成阶段性地做专题总结的习惯,比如你这个月学习或在做与多线程有关的模块或项目,那么在你做完后,你就可以好好地总结一下所有与多线程相关的技术,包括理论知识,实践方法以及各种技巧及优秀文章等等,这对你各种能力的提高将有很大的帮助,你试过了吗,如果没有,那就快点行动吧!

(十)要有持之以恒的精神 这是废话,因为我揍不齐十大,所以将它也算上,中国自古以来喜欢号召大众学习某种精神,比如马克思的,列宁的,***的,邓小平的,雷峰的等,这些精神使社会更安定人民生活更美好,那么程序员要有什么样的精神呢?我不是我说了就算了的,我只是想说明要学好任何一门技术,最好要有持之以恒精益求精的精神,特别是学一些比较抽象比较难的技术,比如VC++,我想它应比别的开发语言都要难学些,或许你已经开始了两年了,但感觉还是不爽仿佛也没掌握什么,这个时候你除了思考一下你的学习方法以外,还必须坚定你的目标及信念!

132010

Figures

To insert a figure in a LaTeX document, you write lines like this:

\begin{figure}
    \centering
    \includegraphics[width=3.0in]{imagefile1}
    \caption{Caption for figure}
    \label{fig:sample_figure}
\end{figure}

The whole block is enclosed between \begin{figure} and \end{figure}. The command \includegraphics does the actual insertion of the image. Here the file name of the inserted image is imagefile1. If you are using LaTeX to process your document, .eps extension is appended automatically to the file name. If you are using pdfLaTeX, it appends .pdf, .png, or .jpg when searching for the image file.

By default, figures are looked for in the current directory (the one in which your .tex file is located). If you want to specify a path for the \includegraphics command, remember to use forward slashes (/) as directory separators, not backslashes. For example, if your figures are in a sub-directory named “figures” inside the current directory, you write something like this: \includegraphics[width=3.0in]{figures/imagefile1}.

You can also specify the width of the image. The height of the figure is scaled proportionally so the image doesn’t get distorted. Specify the width as a parameter (enclosed in brackets [ ]) to the \includegraphics command. Acceptable measurement units are for example in, mm, and cm. You can make the figure’s width equal to the width of paragraph text lines by using [width=\linewidth], or, for example, three quarters of the text width by using [width=0.75\linewidth].

Here we have used a \centering command to center the figure in the column. The \caption command gives a caption for the figure. We have also added a \label, which is useful when you want to refer to the figure in your text (see References).

Remember to always keep the commands in this order: First \includegraphics, then \caption, and finally \label. This way you get figure references right and captions underneath figures. Additionally, keep the \label and \caption commands always inside the \begin{figure}\end{figure} structure.

You can specify the locations where the figure (or table) is allowed to be placed by using placement parameters. For example, to put a figure at the bottom of page, you type \begin{figure}[b]. To allow a figure to be placed only at the top of page, write \begin{figure}[t]. To allow both locations, use [tb]. Other options are described, for instance, in Chapter 9 of Online tutorials on LaTeX.

If you don’t yet know how to create EPS images for LaTeX documents, read the Creating figures tutorial.

Subfigures

If you want to divide a figure into many smaller parts, use the \subfigure command. First, you have to add this in the beginning of your .tex file:

\usepackage{subfigure}

Let’s add three small figures in place of one normal figure:

\begin{figure}
    \centering
    \subfigure[First caption]
    {
        \includegraphics[width=1.0in]{imagefile2}
        \label{fig:first_sub}
    }
    \\
    \subfigure[Second caption]
    {
        \includegraphics[width=1.0in]{imagefile2}
        \label{fig:second_sub}
    }
    \subfigure[Third caption]
    {
        \includegraphics[width=1.0in]{imagefile2}
        \label{fig:third_sub}
    }
    \caption{Common figure caption.}
    \label{fig:sample_subfigures}
\end{figure}

The result is:

Write as many \subfigure commands as you need. \subfigure takes an argument (enclosed in brackets [ ]) which specifies the caption for that subfigure. You don’t need to write the labels (a), (b), (c), etc., because LaTeX adds them automatically. Then put the \includegraphics and \label commands between { and } of the subfigure. Here we use an image file named imagefile2.eps. We have also specified a width for each image using the optional width parameter of the \includegraphics command.

Note the \\ after the first subfigure. This command creates a line break. In this case, it separates the three subfigures into two rows. Without the \\ all the three subfigures may end up in just one row. You can try the \\ also in other places and see its effect.

Finally, we put one more \caption and \label. These are for the whole three-part figure element.

Tables

A table in LaTeX may look a bit scary bunch of code at first. But you can copy and paste the basic lines that are needed. Then inserting your own text into the table is a piece of cake. Here we go:

\begin{table}
\renewcommand{\arraystretch}{1.3}
\caption{Simple table}
\label{tab:example}
\centering
\begin{tabular}{c|c}
    \hline
    Heading One  &  Heading Two\\
    \hline
    \hline

    Three   &   Four\\
    \hline

    Five    &   Six\\
    \hline
\end{tabular}
\end{table}

The result will look like this (using IEEE’s style):

Hence it’s a table with two columns and three rows. Here is how you organize the text in a table: In each table cell write the the text that you want to appear in the cell. Then type & when you want to jump to the next column. A new table row begins when you type \\. You can insert horizontal lines using the command \hline.

Here we have specified the column format like this: \begin{tabular}{c|c}. Every letter c, l, or r denotes a column and | represents a vertical line between columns. c creates a column with centered text, l is for left aligned text, and r for right aligned. Thus, c|c creates two columns with centered text and a vertical line between them.

To get double lines between columns, use || instead of single |. To get no line between columns, omit the |. More columns can be added by using more c, l, or r letters. For example, this produces four columns with no vertical lines: lccc. Now the leftmost column is left aligned and the others are centered.

You may wonder about the strange line \renewcommand{\arraystretch}{1.3}. This is needed for adjusting the white space around text in the table cells. The value 1.3 produces quite a pleasing look.

If you want to have the caption underneath the table, move the \caption and \label lines after the \end{tabular} line. Remember that the \caption command must be before \label.

Double column figures and tables

If you are writing a two column document and you would like to insert a wide figure or table that spans the whole page width, use the “starred” versions of the figure and table constructs. Like this:

\begin{figure*}
    \centering
    \includegraphics[width=\textwidth]{imagefile1}
    \caption{This is a wide figure}
    \label{fig:large}
\end{figure*}

You can use also subfigures inside figure*. An adequate width specifier for a double column figure is width=\textwidth. This makes the figure wide enough to span the whole body width (all columns) of the page.

A double column table is created in a similar way by using \begin{table*} and \end{table*}. Write the contents of the table in the usual way.

Note that double column figures and tables have some limitations. They can’t be placed at the bottom of pages. Additionally, they will not appear on the same page where they are defined. So you have to define them prior to the page on which they should appear.

Equations

Short mathematical expressions can be inserted within paragraph text by putting the math between $ signs. For example:

... angle frequency $\omega = 2\pi f$ ...

This is called an inline equation. The result is: .

In equations, the normal text symbols are written as such, for example 2 and f. Greek symbols are named for example \alpha, \beta and so on. You don’t need to remember these because in WinEdt and TeXnicCenter you can use symbol toolbars, which have buttons for Greek letters and other math symbols.

Numbered equations are separate from paragraph text and LaTeX numbers them automatically. The contents are written using the same ideas as inline equations but now we write \begin{equation} and \end{equation} instead of $ signs. For example:

\begin{equation}
    \label{eq:kinetic_energy}
    E_{k} = \frac{1}{2}mv^{2}
\end{equation}

The result is:

Here we learn some structures which are often used in equations: The \frac command creates a fraction. Write the contents of the numerator and denominator inside the curly braces. Subscripts and superscripts are created using _{} and ^{}. (If the content of the subscript or superscript is a single symbol, you can omit the curly braces like this: E_k and v^2.)

Remember that an empty text line produces a paragraph break. Thus, omit empty lines before and after your equations, unless you really need a paragraph break there. This way you can easily explain the meaning of the variables (“where m is the mass and v is…”) so that the word “where” won’t start a new paragraph and won’t become indented.

You can freely type spaces in equations. LaTeX ignores extra spaces and determines automatically where (and how wide) space is needed (for example, on both sides of the = sign). However, line breaks are not allowed. Spaces are needed also to separate LaTeX commands. For instance, if you want to print , you must type \beta A, not \betaA. The latter one won’t compile because LaTeX is looking for a command named betaA.

Occasionally spaces in equations may need some fine adjustment. For example, consider the following two equations:

Equation (1) has been created by simply typing f_{res} = 500 MHz. It seems to have several problems:

  • The unit “MHz” and the subscript “res” have an incorrect spacing between letters. This is a common problem in variable names, subscripts, and units that consist of several letters. LaTeX understands “res” as a product of variables r, e, and s. Thus it adds a small space between each multiplicand. To fix the problems, write \mathrm{res} and \mathrm{MHz} . The “mathrm” stands for math “roman” (upright) font style.
  • The unit “MHz” and the subscript “res” should be typed with upright font, not italic. The aforementioned \mathrm command fixes this problem. If you, instead, want to use italic font, replace \mathrm with \mathit.
  • In equation (1), there is hardly any space between the number and the unit. LaTeX has thought that you want to multiply 500 times “MHz” and thus it removes all spaces you write here. To force a visible space, use command \,.

Here is the final fixed content of the equation, which produces the result (2) as shown above:

f_{\mathrm{res}} = 500 \, \mathrm{MHz}

If you have problems with a long equation that is wider than the space available on the page, you can split your math on several lines like this: First put \usepackage{amsmath} in the beginning of your LaTeX file. Then use \begin{split}...\end{split}:

\begin{equation}
\label{eq:long_equation}
\begin{split}
    F &= a + b + c + d + e + f + g \\
    &+ h + i + j + k + l + m \\
    &= a + \ldots + m \\
    &= 0
\end{split}
\end{equation}

The result looks like this:

To start a new line in your equation, add \\ to the end of the line. Additionally, put an & before the signs that should be aligned in a straight vertical line. Here we have aligned the = and + symbols.

Like shown above, amsmath can often provide a LaTeX solution to more demanding math problems. See the documentation of amsmath at TeX Catalogue Online or at CTAN.

原文链接:http://www.electronics.oulu.fi/latex/examples/example_3/index.html

LaTex数学宏包汇总集锦

Posted by 冰河 at 22:19 No Responses » 31,950 Views
122010

algorithm2e

它提供一个 Algorithm2e 环境,用于在 LaTeX2e  中排版算法步骤。它将算法步骤定义为浮动体;它提供一组关键词供排版使用,关键词既可修改也可创新。

源文件

Christophe Fiorio

algorithms

它定义了 algorithmic 和 algorithm 两个环境和一组命令,可用于排版算法步骤,对其中的关键词可以采用不同的显示效果。两种环境可分别使用,也可同时使用;其中 algorithm 环境还可以处理图形之类的浮动体。

源文件 示例

Rogério Brito

amsbsy

它定义了排版黑体数学符号的命令 \boldsymbol 和 \pmb。该宏包现已经被更新的宏包 bm 所取代。

源文件

Frank Mittelbach

amscd

它定义了一个 CD 环境,适用于排版较简单的只有单向箭头的矩形交换图表。

源文件

Frank Mittelbach

amscls

它定义了 amsart、amsbook 和 amsproc 三种数学源文件类型,它们包括了美国数学学会所有出版物的样式。它还提供了一个可独立使用的定理宏包 amsthm

源文件

AMS

AMSFonts

美国数学学会根据其印刷和电子出版物以及在线资料库的样式要求,编造的一组用于排版数学出版物的数学符号字体库宏包套件,它包含有:amsfontsamssymbeufrakeucal 四个宏包。

eucal 可修改 LaTeX 的数学字体命令 \mathcal 。当加载该宏包后,使用 \mathcal 命令,调出的是欧拉书写体,而不是通常的计算机现代书写体。它还有一个 mathscr 选项,使其可与数学字体命令 \mathscr 结合使用。

eufrak 设置了哥特字体,这是一种书写或印刷字体,外观非常华丽,多见于中世纪时的神学文献。如果已加载了 amsfonts 宏包,该宏包就是多余的。

源文件

AMS

amsfonts

它定义了大写空心粗体字命令 \mathbb 和欧拉字体命令 \mathfrak 以及数学公式中各种相应的字体,如:粗数学斜体和粗希腊字母下标、求和积分等大符号下标、 欧拉数学字体、斯拉夫字体等。

大写空心粗体字一般用于表示数学和物理学中的向量或集合。

现在常用的数学字体命令及其字体样式见下表所示:

LaTeX技巧251:latex数学宏包汇总集锦

要使用其中蓝色的字体命令就要调用 amsfonts 宏包。

源文件

AMS

AMSLaTeX

美国数学学会主要有三种类型的出版物:论文、学报和书籍或专论,每一种都有详细严格的出版样式要求。

标准 LaTeX 本身就有很强的数学排版能力,但对于非常专业而复杂的数学公式和数学结构,还是需要定义一些新命令和环境来简化源文件的编辑过程。

1982年,美国数学学会根据其刊物出版要求,委托开发了用于排版数学刊物的 TeX 系统:AMSTeX,1987年又将其移植到 LaTeX,成为 AMSLaTeX。现在它已成为 LaTeX-2e 的一个数学宏包套件。

AMSLaTeX 套件包括有:amsbsyamscd、amsgen、amsmath、amsopn、ams-text、amsxtra、amsthm 、upref 和 amscls 等宏包。

AMS

amsmath

它定义了各种显示多行公式的环境和一系列排版数学公式的命令,可用以改进和提高方程式、多行上\下标等数学结构的排版效果。 例如,它提供的一条命令:\cfrac,用来排版连分数,要比标准 LaTeX 中的 \frac 命令输出效果更加美观。

该宏包还有11个选项,可以影响极限、方程和方程序号等数学式的放置,而这些选项的设置要优先于源文件中其他相关选项的设置。

当调用该宏包的同时,另外三个与之相关的宏包:amsbsy、amsopn amstext,也自动被加载了。

源文件

AMS

应用举例 源文件 AMS

amsopn

它提供命令:\DeclareMath0perator{\新函数命令}{新函数名},在导言区用来自定义类似 \sim 和 \lim 等新的算符 或函数;也可以在正文中用它提供的命令:\operatorname{函数名},自定义临时使用的函数。举例说明:

LaTeX技巧251:latex数学宏包汇总集锦 LaTeX技巧251:latex数学宏包汇总集锦

在实际排版中,大都用 amsmath 宏包替代该宏包。

源文件

Michael Downes

amssymb

宏包套件 AMSFonts 中的一个宏包,它定义了 amsfonts 宏包里 msam 和 mabm 字库中全部数学符号的命令。当调用该宏包时,amsfonts 宏包也同时被加载了。

下表为 Latex 和 AMS 所提供的数学符号及其命令,其中蓝色符号命令表示需要调用amssymb 宏包:

希腊字母:
LaTeX技巧251:latex数学宏包汇总集锦
其他字母:
LaTeX技巧251:latex数学宏包汇总集锦
各种普通符号:
LaTeX技巧251:latex数学宏包汇总集锦
二元运算符号:
LaTeX技巧251:latex数学宏包汇总集锦
量关系符号:
LaTeX技巧251:latex数学宏包汇总集锦
箭头关系符号:
LaTeX技巧251:latex数学宏包汇总集锦
其他关系符号:
LaTeX技巧251:latex数学宏包汇总集锦
累积符号:
LaTeX技巧251:latex数学宏包汇总集锦
成对界限符号:
LaTeX技巧251:latex数学宏包汇总集锦
单界限符号:
LaTeX技巧251:latex数学宏包汇总集锦
垂直箭头符号:
LaTeX技巧251:latex数学宏包汇总集锦
声调符号:
LaTeX技巧251:latex数学宏包汇总集锦
函数符号:
LaTeX技巧251:latex数学宏包汇总集锦

源文件

AMS

amstext

它定义命令 \text,可用于在数学公式中插入少量文本,并可调整上下标中文本字体的尺寸。

源文件

Frank Mittelbach

amsthm

它定义了一个 proof 环境,用来排版定理和证明,能自动在最后添加证毕符号。它还提供一个命令:\newtheorem{定理环境名}{标题}[计数器名],可自定义定理类 环境。

源文件

AMS

应用举例 源文件 Michael Downes

bm

bm 的是黑体数学符号的英文缩写,该宏包可使数学公式以粗体的方式来显示。它提供一个 \bm{数学式} 命令,在数学模式中,只要把数学符号或数学式置于大括号中就会由粗体来显示。

源文件

David Carlisle

calc

TeX 中的算数运算通常是由 \advance 和 \multiply 这样的底层命令来完成的,一般只用来开发新宏包,难以为普通用户所使用。

该宏包定义的几条命令增强了 LaTeX 的算术运算能力,而且非常容易理解。

它是标准 LaTeX2e 工具宏包套件之一。

源文件

Kresten Krab Thorup

delarray

编排矩阵、数组或行列式一般都采用下列方法:

LaTeX技巧251:latex数学宏包汇总集锦 LaTeX技巧251:latex数学宏包汇总集锦

左右括号必须辅以 \left 和 \right 命令,其大小才能够自动与内容匹配。如果论文中这类数学式很多,就显得非常麻烦,容易遗漏;另外,为了约束这些数学式的位置,通常要在 array 环境中添加位置选项,如 [t] 或 [b] 等,但这样会造成括号不匹配:

LaTeX技巧251:latex数学宏包汇总集锦 LaTeX技巧251:latex数学宏包汇总集锦

采用 delarray 宏包就可以解决上述问题:

LaTeX技巧251:latex数学宏包汇总集锦 LaTeX技巧251:latex数学宏包汇总集锦

源文件

David Carlisle

easybmat

它提供了一个 BMAT 环境,可编排列宽相等、或行高相等、或列宽相等且行高相等的块状矩阵,并可在矩阵的行列之间加上各种式样的界线。BMAT 环境的一个主要特点就是可以嵌套,最多可达8层;BMAT 最多可处理30行30列。

它可能会与 booktabs,array 等表格宏包冲突。

Enrico Bertolazzi

eqnarray

它将标准 LaTeX 中的 eqnarray 环境与 array 环境相结合,定义了一个新的环境:equationarray。在该环境中,公式组可以排成三列以上,在某些方面类似 amsmath 宏包提供的 align 环境。该宏包需要与 array 宏包配合使用。

源文件

Roland Winkler

exscale

它提供一套按比例伸缩的数学扩展字体。

源文件

Frank Mittelbach

举例

mathdesign

它将系统默认的数学字体重新定义,所有字符都有标准体和粗体,并附带多重圆积分,欧元等特殊符号。它有七个选项,可以影响希腊字母等某些字符的字体。

该宏包会与 amsfonts 或 mathrsfs 等数学宏包发生冲突,应避免同时使用,因为对同一命令各有不同的定义。

Paul Pichaureau

示例

mathenv

它提供了一些使用更简便、效果更优美的数学命令和环境。

在它所提供的数学环境中都有一个标签选项,可用于交叉引用;这些环境都有带*号的形式,所不同的是它们不产生公式序号。其中:MultiLine 环境可以排版多行长公式、System 环境用于公式组且共用一个序号、EqSystem 环境也是用于公式组的,但每行公式各有分序号,如(1.1),(1.2)…。

它还重新定义了命令:\( 、\) 、\[ 、\] 、\{ 和 \} ,使其可以在数学模式中直接使用,无需 \left 和 \right 命令配合。

源文件

F. Bosisio

mathptmx

在标准 LaTeX 中,默认的字体族为计算机现代罗马字体;在数学环境中,大写希腊字母为直立体,小写希腊字母为倾斜体。

加载该宏包可将系统默认的字体族改为 Adobe Times,并将文稿中的数学字符转成虚拟mathptmx 字体。它只有一个 slantedGreek 选项,使用此选项,数学模式中的大写希腊字母也成为倾斜体。如需变为直立体,比如 \Gamma 改为 \upGamma 即可,而小写希腊字母则不行。它没有粗体数学字符,\boldmath 命令无效,也不推荐使用 bm 宏包,可 以用命令 \mathbf 获得粗体数学字符。

该宏包是 psnfss 宏包套件之一,它将 times 和 mathptm 两个宏包的功能合为一体。

源文件

Walter Schmidt

示例源文件

mdwmath

它提供了一个带星号的开根命令 \sqrt*,所生成的根号没有上面的横线,如 √a ,这样其中操作数的字体尺寸就不受根号的限制了;同时,它改进了标准开根命令 \sqrt,使其生成的根式更加美观;另外它还定义了几个特殊的数学符号。

源文件

Mark Wooding

ntheorem

它增强了 LaTeX 的定理类环境功能,(例如:定理、推论、定义和证明等都可以归为定理类),改进了定理类环境的页面设置;当使用 thmmarks 选项,可以自动恰当地放置定理类环境的结束标记;它还能像图形目录那样生成定理类环境目录。

当它载后,标准 LaTeX 中的 \newtheorem 命令改由该宏包控制。

它可与 theorem 宏包兼容。

源文件

Wolfgang May

subeqn

有时需要对方程式中的子方程式进行编号,以便注释和引用,但在标准 LaTeX 中则无法做到。

为解决这一问题,该宏包定义了两个环境 subequations 和 subeqnarray,可以对方程式中的子方程式进行编号,得到如(1a)、(1b)和(1c)这样的编号。 举例

该宏包可在源文件类型的 leqno 和 fleqn 选项中工作,前者把方程式的序号放在左边而不是右边,后者将方程式缩排左对齐而不是居中;它不能与 subeqnarray 宏包兼容。

源文件

Donald Arseneau

subeqnarray

它提供了 subeqnarray 和 subeqnarray*两个环境,使用其定义的 \slabel 命令,可对多行公式组中的每一行进行编号,如给出 (1a),(1b), (1c)等。

源文件

Johannes L. Braams

举例

theorem

它是 LaTeX 工具宏包套件之一,通过定义不同的 theorem 环境,可自己设置定理、定义和引理等的式样。

源文件

Frank Mittelbach

tmmaths

它支持使用 Times 字族和 TM-Math 字族排版。当该宏包加载后,默认字体为 Adobe
Times;可选用 MicroPress TM-Math 字体编排数学公式;\mathbold 命令可以排印斜粗体字母,包括希腊字母。

源文件

Walter Schmidt

vector

在标准 LaTeX 中,向量可以在数学模式里用 \vec 命令生成,例如:$\vec{a}$ ;但在实际应用中,向量符号常为粗罗马字体或带有下划线。

vector 宏包定义了一组新命令,用于排版各种式样的向量符号,包括粗体的、带下划线的以及戴帽子的单位向量等,并可成组横\竖排列,成为隐式或显式向量序列。向量符号的字体可以是 boldface roman 或 sans serif ;下划线可以是直线或波浪线。

源文件

Nick Efford

yhmath

它提供了一组大型数学分界符,其中有花括号、圆括号、方括号、三角括号和重音号等;另外还提供很多大尺寸数学符号,如根号、圆积分号和求和号等。这些符号都存于 cmex10  字库中。

源文件

Yannis Haralambousy

图例

youngtab

它可以用于排版群论中的 Young-Tableaux 方格式。该宏包定义了两个命令:\yng 和 \young,前者能生成空方格,后者可在方格中标注,这两个命令都很简单以免拼写错误。它附有四个选项,可对方格式的样式产生影响。

源文件

Volker Börchers

参考链接:http://zzg34b.w3.c361.com/package/maths-2.htm

.htaccess文件大家都不陌生吧。不认识的自己去搜一下……顺便告诉你,这是个好东西,值得一学。

似乎网上关于.htaccess编写方法的教程很有限,相信博主们也没有几个是自己写的吧?
我在这里就搜了几个常用规则,总结一下rewrite规则的用法。当然这只是.htaccess功能的一小部分,但是相当实用。
如果熟练掌握rewrite规则的编写,能够加强对网站URL的控制,对用户体验、SEO都十分有利。

注:所有规则来源于网络,我只作解释。

一、防盗链功能

1
2
3
4
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+.)?mysite.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]

逐行讲解一下:

1.打开Rewrite功能。有可能服务器设置里已经是全局下打开了,但是多写也没事。
2.RewriteCond指令,定义生效条件,用于寻找匹配条件的地址。后面内容用正则表达式匹配。代表含义是发送的请求不由mysite.com而来,那就是盗链啦。末尾的[NC]代表忽略大小写。
3.发送请求的主机前缀不为空。
4.RewriteRule指令,定义重写规则,把匹配的地址按此规则重写。本例中把这些后缀为这些图片格式的,都替换到某一个图片下。[L]表示这是最后一段规则。

只这四行就实现了防盗链是不是很神奇(- -||),编写起来是不是又觉得复杂。
这里总结了几个常用参数(不是全部):

RewriteCond下:
[NC]
不分字母大小写
[OR] 用于连接下一条规则

RewriteRule
下:
[R] 强制重定向,[R=code]
code默认为302
[F] 禁用URL,返回HTTP 403 错误
[L] 这是最后一条规则,之后内容无用

还有一篇关于正则表达式的教程(很详细):http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm

二、网址规范化

1
2
3
4
Options +FollowSymLinks
rewriteEngine on
rewriteCond %{http_host} ^yourdomain.com [NC]
rewriteRule ^(.*)$ http://www.yourdomain.com/$1 [R=301,L]

这个是把所有二级域名都重定向到www.yourdomain.com的例子,现在看来是不是很简单了?
需要注意的是,这里的Options +FollowSymLinks不是必须的,但在某些服务器如果不设置FollowSymLinks,可能引起500错误。

再来看一个好玩的重定向

1
2
3
4
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} (Googlebot)
RewriteRule ^ http://abc.com/ [R=301,L]

1.打开Rewrite功能。
2.RewriteBase指令,设置目录级重写的基准URL。可以理解成把该目录(这个.htaccess所在目录)假定为基准的URL前缀。本例中这样的写法无用。
3.RewriteCond指令。匹配所有USER_AGENT为Googlebot的发送请求。
4.RewriteRule指令。本例中把这些请求都重定向到了abc.com。

在本例中,这个配置应该是黑客所为,把google蜘蛛指向某个网站,等于伪造PR。

三、临时错误页面

当你的网站在升级、修改的时候,你最好让访客转到指定的页面,而不是没做完的页面或者是错误页。
这时我们做一个302转跳就好。

1
2
3
4
RewriteEngine on
RewriteCond %{REQUEST_URI} !/maintenance.html$
RewriteCond %{REMOTE_ADDR} !^123.123.123.123
RewriteRule $ /error.html [R=302,L]

1.继续打开Rewrite功能。- -|
2.REQUEST_URI请求的URL值。这里指所有访问maintenance.html页面的请求。
3.REMOTE_ADDR向服务器发送请求的IP地址。本例中此处应设为你自己的IP,这样就只有你能访问。
4.RewriteRule指令。本例中把这些请求都重定向到了error.html 。

在本例,我们总结几个常用的正则表达式和特殊符号。

(.*) 用于匹配某一区域内所有内容。如 abc/def/ghi 可用 (.*)/(.*)/(.*) 匹配。
([a-zA-Z_]+) 匹配英文单词,允许用-和_连接。
([0-9]+) 匹配多位数字,通常用于匹配ID。
([0-9]) 只匹配一位的数字。

^ 表示正则的开始
$ 表示正则的结束

四、重定向RSS地址到Feedburner

除了可以更改模板里的RSS地址外,.htaccess也能实现RSS地址的更改,并更加方便。

1
2
3
4
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} !FeedBurner    [NC]
RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC]
RewriteRule ^feed/?([_0-9a-z-]+)?/?$ http://feeds2.feedburner.com/yourname [R=302,NC,L]

有了上面的总结,本例其实就很简单了吧。
唯一要注意的是这样操作要确保填写正确的HTTP_USER_AGENT。其实你不常换模板的话。。可能还是直接改模板更省事。

在最后,为懒虫们推荐几个好东东:
在线.htaccess生成器htaccessEditor
在线正则表达式检查器http://www.sman.cn/Blog/attachments/month_0711/320071117123354.html
mod_rewrite模块中文参考手册http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/mod/mod_rewrite.html

P.S. 其实我以为rewrite也只是APACHE一个模块而已,做到边查边写足矣,实在不行直接去搜一个规则也未尝不可。没有必要费太大力气去学。不过其中的正则表达式还是非常实用的,值得深入学习。

原文链接:http://www.suoyishuo.com/archives/how-to-write-htaccess-rewrite.html

完整的代码如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* JAVA操作SSL协议,通过Socket访问Https的程序代码例子。
*
*
*/
public class ReadHttpsURL {
// 默认的HTTPS 端口      visit
static final int HTTPS_PORT = 443;
public static void main(String argv[]) throws Exception {
// 受访主机
String host = “www.google.com”;
// 受访的页面
String url = “/adsense/?sourceid=aso&subid=ZH_CN-ET-AS-ADSBY6&medium=link&hl=zh_CN”;
// 自定义的管理器
X509TrustManager xtm = new Java2000TrustManager();
TrustManager mytm[] = { xtm };
// 得到上下文
SSLContext ctx = SSLContext.getInstance(“SSL”);
// 初始化
ctx.init(null, mytm, null);
// 获得工厂
SSLSocketFactory factory = ctx.getSocketFactory();
// 从工厂获得Socket连接
Socket socket = factory.createSocket(host, HTTPS_PORT);
// 剩下的就和普通的Socket操作一样了
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write(“GET ” + url + ” HTTP/1.0

“);
out.flush();
System.out.println(“start   work!”);
String line;
StringBuffer sb = new StringBuffer();
while ((line = in.readLine()) != null) {
sb.append(line + ”
“);
}
out.close();
in.close();
System.out.println(sb.toString());
}
}
/**
* 自定义的认证管理类。
*
*
*/
class Java2000TrustManager implements X509TrustManager {
Java2000TrustManager() {
// 这里可以进行证书的初始化操作
}
// 检查客户端的可信任状态
public void checkClientTrusted(X509Certificate chain[], String authType) throws CertificateException {
System.out.println(“检查客户端的可信任状态…”);
}
// 检查服务器的可信任状态
public void checkServerTrusted(X509Certificate chain[], String authType) throws CertificateException {
System.out.println(“检查服务器的可信任状态”);
}
// 返回接受的发行商数组
public X509Certificate[] getAcceptedIssuers() {
System.out.println(“获取接受的发行商数组…”);
return null;
}
}

在web应用交互过程中,有很多场景需要保证通信数据的安全;在前面也有好多篇文章介绍了在Web Service调用过程中用WS-Security来保证接口交互过程的安全性,值得注意的是,该种方式基于的传输协议仍然是Http,采用这种方式可扩 展性和数据交互效率比较高;另外一种实现方式就是用Https,他是在协议层对Http的再次封装,加入了SSL/TLS,采用该协议进行通信的数据全部 都会被加密,由于目前Web开发编程中对此都有了一定程度的封装,所以采用Https对外提供服务,除了证书以外,对编程能力的要求并不高,相对于前者门 槛较低,但是由于对双方通信的所有数据都进行加密,而且交互过程中还有多次握手等,所以效率较低;以下就介绍下在Java中访问Https链接时会出现的 一些问题;

在Java中要访问Https链接时,会用到一个关键类HttpsURLConnection;参见如下实现代码:

// 创建URL对象
URL myURL = new URL(“https://www.sun.com”);

// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
HttpsURLConnection httpsConn = (HttpsURLConnection) myURL
.openConnection();

// 取得该连接的输入流,以读取响应内容
InputStreamReader insr = new InputStreamReader(httpsConn
.getInputStream());

// 读取服务器的响应内容并显示
int respInt = insr.read();
while (respInt != -1) {
System.out.print((char) respInt);
respInt = insr.read();
}

在取得connection的时候和正常浏览器访问一样,仍然会验证服务端的证书是否被信任(权威机构发行或者被权威机构签名);如果服务端证书不被信任,则默认的实现就会有问题,一般来说,用SunJSSE会抛如下异常信息:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

上面提到SunJSSE,JSSE(Java Secure Socket Extension)是实现Internet安全通信的一系列包的集合。它是一个SSL和TLS的纯Java实现,可以透明地提供数据加密、服务器认证、 信息完整性等功能,可以使我们像使用普通的套接字一样使用JSSE建立的安全套接字。JSSE是一个开放的标准,不只是Sun公司才能实现一个 SunJSSE,事实上其他公司有自己实现的JSSE,然后通过JCA就可以在JVM中使用。
关于JSSE的详细信息参考官网Reference:http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html
以及Java Security Guide:http://java.sun.com/j2se/1.5.0/docs/guide/security/

在深入了解JSSE之前,需要了解一个有关Java安全的概念:客户端的TrustStore文件。客户端的TrustStore文件中保存着被客 户端所信任的服务器的证书信息。客户端在进行SSL连接时,JSSE将根据这个文件中的证书决定是否信任服务器端的证书。在SunJSSE中,有一个信任 管理器类负责决定是否信任远端的证书,这个类有如下的处理规则:
1、若系统属性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安装路径下的lib/security/目录中寻找并使用这个文件来检查证书。
2、若该系统属性没有指定TrustStore文件,它就会去jre安装路径下寻找默认的TrustStore文件,这个文件的相对路径为:lib/security/jssecacerts
3、若jssecacerts不存在,但是cacerts存在(它随J2SDK一起发行,含有数量有限的可信任的基本证书),那么这个默认的TrustStore文件就是lib/security/cacerts

那遇到这种情况,怎么处理呢?有以下两种方案:
1、按照以上信任管理器的规则,将服务端的公钥导入到jssecacerts,或者是在系统属性中设置要加载的trustStore文件的路径;证书导入可以用如下命令:keytool -import -file src_cer_file –keystore dest_cer_store;至于证书可以通过浏览器导出获得;
2、实现自己的证书信任管理器类,比如MyX509TrustManager,该类必须实现X509TrustManager接口中的三个method;然后在HttpsURLConnection中加载自定义的类,可以参见如下两个代码片段,其一为自定义证书信任管理器,其二为connect时的代码:

package test;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class MyX509TrustManager implements X509TrustManager {

/*
* The default X509TrustManager returned by SunX509.  We’ll delegate
* decisions to it, and fall back to the logic in this class if the
* default X509TrustManager doesn’t trust it.
*/
X509TrustManager sunJSSEX509TrustManager;

MyX509TrustManager() throws Exception {
// create a “default” JSSE X509TrustManager.

KeyStore ks = KeyStore.getInstance(“JKS”);
ks.load(new FileInputStream(“trustedCerts”),
“passphrase”.toCharArray());

TrustManagerFactory tmf =
TrustManagerFactory.getInstance(“SunX509″, “SunJSSE”);

tmf.init(ks);

TrustManager tms [] = tmf.getTrustManagers();

/*
* Iterate over the returned trustmanagers, look
* for an instance of X509TrustManager.  If found,
* use that as our “default” trust manager.
*/
for (int i = 0; i < tms.length; i++) {
if (tms[i] instanceof X509TrustManager) {
sunJSSEX509TrustManager = (X509TrustManager) tms[i];
return;
}
}

/*
* Find some other way to initialize, or else we have to fail the
* constructor.
*/
throw new Exception(“Couldn’t initialize”);
}

/*
* Delegate to the default trust manager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}

/*
* Delegate to the default trust manager.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException excep) {
/*
* Possibly pop up a dialog box asking whether to trust the
* cert chain.
*/
}
}

/*
* Merely pass this through.
*/
public X509Certificate[] getAcceptedIssuers() {
return sunJSSEX509TrustManager.getAcceptedIssuers();
}
}

// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance(“SSL”, “SunJSSE”);

sslContext.init(null, tm, new java.security.SecureRandom());

// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

// 创建URL对象
URL myURL = new URL(“https://ebanks.gdb.com.cn/sperbank/perbankLogin.jsp”);

// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();
httpsConn.setSSLSocketFactory(ssf);

// 取得该连接的输入流,以读取响应内容
InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream());

// 读取服务器的响应内容并显示
int respInt = insr.read();
while (respInt != -1) {
System.out.print((char) respInt);
respInt = insr.read();
}

对于以上两种实现方式,各有各的优点,第一种方式不会破坏JSSE的安全性,但是要手工导入证书,如果服务器很多,那每台服务器的JRE都必须做相同的操作;第二种方式灵活性更高,但是要小心实现,否则可能会留下安全隐患;

java模拟网站登录

Posted by 冰河 at 13:18 No Responses » 25,561 Views
202010

web登陆无非就是网页获取,cookie 的管理,post和get方式的模拟。

1.网页内容获取 java.io.InputStream   in;
java.net.URL url = new java.net.URL(www.xyz.com/content.html);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection)
url.openConnection();
connection = (java.net.HttpURLConnection) url.openConnection();
//模拟成IE
connection.setRequestProperty(“User-Agent”,”Mozilla/4.0 (compatible; MSIE 6.0; Windows 2000)”);
connection.connect();
in = connection.getInputStream();
java.io.BufferedReader breader =
new BufferedReader(new InputStreamReader(in , “GBK”));
String str=breader.readLine());
while(st != null){
System.out.println(str); str=breader.readLine());
}
2.cookie管理
1.直接的方式
取得cookie:
HttpURLConnection huc= (HttpURLConnection) url.openConnection();
InputStream is = huc.getInputStream();
// 取得sessionID.
String cookieVal = hc.getHeaderField(“Set-Cookie”);
String sessionId;
if(cookieVal != null)
{
sessionId = cookieVal.substring(0, cookieVal.indexOf(“;”));
}
发送设置cookie:
HttpURLConnection huc= (HttpURLConnection) url.openConnection();
if(sessionId != null)
{
huc.setRequestProperty(“Cookie”, sessionId);
}
InputStream is = huc.getInputStream();

2.利用的jcookie包(http://jcookie.sourceforge.net/ )
获取cookie:
URL url = new URL(“http://www.site.com/”);
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
huc.connect();
InputStream is = huc.getInputStream();
Client client = new Client();
CookieJar cj = client.getCookies(huc);

新的请求,利用上面获取的cookie:
url = new URL(“http://www.site.com/”);
huc = (HttpURLConnection) url.openConnection();
client.setCookies(huc, cj);

3.post方式的模拟
URL url = new URL(“www.xyz.com”);
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
//设置允许output
huc.setDoOutput(true);
//设置为post方式
huc.setRequestMethod(“POST”);
huc.setRequestProperty(“User-Agent”,”Mozilla/4.7 [en] (Win98; I)”);
StringBuffer sb = new StringBuffer();
sb.append(“userName=”+userNme);
sb.append(“&password=”+password);

//post信息
OutputStream os = huc.getOutputStream();
os.write(sb.toString().getBytes(“GBK”));
os.close();

BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream()))
huc.connect();
String line = br.readLine();
while(line != null){
System.out.printli(line);
line = br.readLine();
}

© 2009 - 2024 冰河的博客