Quantcast
Channel: IT瘾工作推荐
Viewing all 167 articles
Browse latest View live

机器人和自动化抢走印度的低技术工作

$
0
0
在印度南部的一个闷热工厂里, Royal Enfield摩托车公司的机器人正在做着涂漆的工作。涂装线下只需要少数工人。四个机器人就能干15个人类工人三班倒的工作,而且它们不会犯错。机器人和自动化技术正在振兴曾经沉睡的印度工厂,推动了生产力提高,更高效的执行低技术任务。在理论上,增加产量有利于经济增长,但对印度总理Narendra Modi来说,问题是机器人抢走了非熟练劳动者的工作。当低技术工作被机器抢走后,印度破碎的教育系统和受教育程度不高的劳动人口还没有为更复杂的任务做好准备。印度2013年的机器人销量达到了 1,900台,相比中国去年的5.6万还有很大距离。









Facebook内部高效工作PPT指南

$
0
0

1643

Facebook 内部分享:不论你如何富有,你都赚不到更多的时间,你也回不到过去。没有那么多的假如,只有指针滴答的时光飞逝和你应该好好把握的现在,以下25张PPT的分享将为您带来时间价值管理的技巧。

1、时间常有,时间优先。

1615

2、时间总会有的:每天只计划 4~5 小时真正的工作。

1616

3、当你在状态时,就多干点;不然就好好休息:有时候会连着几天不是工作状态,有时在工作状态时却又能天天忙活 12 小时,这都很正常的。

1617

4、重视你的时间,并使其值得重视:你的时间值 1000 美元/小时,你得动起来。

1618

5、不要多任务,这只会消耗注意力;保持专注,一心一用。

1619

6、养成工作习惯,并持之以恒,你的身体会适应的。

1620

7、在有限的时间内,我们总是非常专注并且有效率。

1621

8、进入工作状态的最佳方式就是工作,从小任务开始做起,让工作运转起来。

1622

9、迭代工作,期待完美收工会令人窒息:“做完事情,要胜于完美收工” Facebook 办公室墙壁上贴的箴言。动手做,胜过任何完美的想象。

1623

10、工作时间越长,并不等于效率越高。

1624

11、按重要性工作,提高效率。

1625

12、有会议就尽早安排,用于准备会议的时间往往都浪费掉了。

1627

13、把会议和沟通 (邮件或电话) 结合,创造不间断工作时间:一个小会,也会毁了一个下午,因为它会把下午撕成两个较小的时间段,以至于啥也干不成。PS:当看到一个程序员冥思苦想时,不要过去打扰,甚至一句问候都是多余的。

1629

14、一整天保持相同的工作环境。在项目/客户之间切换,会效率低。

1630

15、工作—放松—工作=高效(番茄工作法)—拖延症—高效。

1631

16、把不切实际的任务分割成合理的小任务,只要每天都完成小任务,你就会越来越接近那个大目标了。

1632

17、从来没有两个任务会有相同的优先级,总会有个更重要,仔细考虑待办事情列表。

1633

18、必须清楚白天必须完成的那件事,是什么。“Only ever work on the thing that will have the biggest impact” 只去做那件有着最大影响的事情。—— Jason Cohen 1634

19、把任务按时间分段,就能感觉它快被搞定了。

1635

20、授权并擅用他人的力量。—君子善假于物(人)也,如果某件事其他人也可以做到八成,那就给他做!

1636

21、把昨天翻过去,只考虑今天和明天昨天的全垒打赢不了今天的比赛。—好汉不提当年勇。

1637

22、给所有事情都设定一个期限。不要让工作无期限地进行下去。

1638

23、针对时间紧或有压力的任务,设置结束时间,万事皆可终结

1639

24、多记,多做笔记

1640

25、进入高效状态后,记下任何分散你注意力的东西比如Google搜索词、灵光乍现的想法、新点子等等。如果你把它们记下来,它就不会再蹦来蹦去了。

1641

26、休息,休息一下~

1642

 


© 推荐 for 互联网的那点事. | 猛击下载: iPhone客户端猛击下载: Android客户端

Twitter 数据分析师独家披露他们的工作内容(上)

$
0
0

本文来源:Medium 译文创见首发 由 TECH2IPO/创见 花满楼 编译 转载请注明出处

创见干货:

数据分析到底是什么?很多人都在嘴边讨论它们,却没有几个人真正见过它。这是当下科技行业最为火爆的职位,今天就让我们走进 Twitter 的数据分析世界,看看科技公司对于一个数据分析师的要求是什么?他们的实际工作内容究竟是哪些?


到了今年 6 月 17 日,Robert Chang 就在 Twitter 工作两年了。根据他个人的工作经历,Twitter 数据分析(以下简称为 DS)有了下面三个层面的变化:

1.机器学习已经在 Twitter 多个核心产品中扮演越来越重要的角色,而这之前完全是「机器学习」的禁区。最典型的例子就是「当你离开时」这个功能。当用户离开页面或者电脑,去干别的事情后再次返回页面,电脑会立刻给你推送出来某些由你关注的人所发出,而有可能被你错过的「优质内容」。

2.开发工具越来越优秀了。整个团队摆脱了对 Pig 的依赖,全新的数据管道是在 Scalding 中写出来的。

3.从团队组织上而言,Twitter 已经转向了一个嵌入式的模型中。其中数据分析比以往更加紧密地与产品/工程团队发生着联系。

在 Twitter 的工作确实是令人兴奋的,因为你能站在这个平台上,引领目前世界最前沿的数据科技,打造最具竞争力的优势。而同时,人们对于大数据的渴望也一天比一天高。

Dan Ariely 曾经有一句话说得特别好:

「大数据其实有点儿像青少年的性。每一个人都兴致勃勃地谈论它,但是没有任何一个人真的知道该怎么做。每一个人都觉得身边的人都在尝试,为了不落人后,于是每个人都在外面宣城自己也已经有『伴儿』了」

现如今,有太多的人在如何成为一名优秀称职的数据分析师上表达着看法,给出自己的建议。Robert Chang 毫无疑问也是受益者。但是他回过头来再想想大家的讨论,会觉得人们往往更加侧重于去谈「技术」、「工具」、「技能组合」,而在 Chang 看来,那些东西确实很重要,但是让新人们知道数据分析师每一天的生活到底是什么样子的,具体的工作内容都是什么,这也非常重要。

于是,Chang 凭借着自己在 Twitter 工作两年的经历,以自己作为例子,首次打开 Twitter 数据分析师这扇神秘的大门。

A 型数据分析师 VS B 型数据分析师

Chang 在没来 Twitter 之前,总觉得数据分析师一定是在任何领域都能看堪称「独角兽」,不管是数据还是数学专业,都是顶尖人才。除了技术上很牛之外,书面写作和口头交流的能力也会特别强。更重要的是他们能够分清楚当下工作的轻重缓急,领导和管理一个项目团队。是啊,如今本身就是以数据为主导的文化,作为「数据分析师」,当然要给这个文化注入灵魂与活力啊!

在 Chang 加入 Twitter 的几个月后,他逐渐意识到:符合上述形容的「独角兽」确实存在,但是对于大部分人来说,上述的要求未免有点儿太不切实际了。 人们没有办法做到面面俱到。后来,Chang 通过 Quora 中的一篇回答,更深刻地理解了数据分析师的角色。在那篇文章中,数据分析师分成了两种类型:

A 型数据分析师他们主要负责「分析」。他们最关心数据背后的意义,往往使用统计等方式探知真相。其实他们的工作有点儿像「统计学家」,但是不一样的地方是,统计学专业涉及的内容他们统统掌握,但是他们还会一些统计学课本里面压根不曾出现的内容:比如数据清洗,如何处理超大数据组,数据视觉化,有关数据层面的报告撰写等等。

B 型数据分析师B 型负责「建造」。他们跟前一种分析师有着相似的统计学背景,但他们同时还是非常牛叉的程序员,又或者是训练有素的软件工程师 。B 型数据分析师往往感兴趣于「如何利用数据来生产」。他们建立一些能够与用户互动的模型,往往以「推荐/推送」的形式出现,比如「你也许会认识的人」,「广告」,「电影」,「搜索结果」等等功能。

Chang 看到这样清楚的划分,非常后悔如果早几年有这么清楚的概念认识该多好啊。这样他就能够有选择性的发力,择其一方向来继续发展。这是数据分析师职场规划首先要考虑的标准。

Chang 的个人专业背景是「数学」、「运营研究」、「统计学」。所以他更倾向于把自己定位于 A 型数据分析师,但是与此同时他对 B 型分析师能够涉及那么多的工程开发工作而向往不已。

初创公司早期、快速发展的初创公司、以及实现规模化发展的初创公司中的数据分析师职位区别

在选择投身于科技行业的时候,最经常遇到的一个问题就是到底是加入一个大的科技公司好呢?还是加入一个小的科技公司好。在这个话题上已经有很多争论了,但是在「数据分析」上面的争论并不是很多。 所以在本章节要具体谈到的是,不同公司的规模、发展阶段中,数据分析师不同的角色定位。

处于不同发展阶段的科技公司生产数据的量与速度都是不一样的。一个还在尝试着寻找到「产品市场契合点」的初创公司完全不需要 Hadoop,因为公司本身就不存在多少的数据需要处理;而一个处在快速发展中的初创公司往往会遭遇更频密的数据冲击,也许 PostgreSQL 或者 Vertica 更适合这家公司的需要;而像 Twitter 这样的公司如果不借助 Hadoop 或者 Map-Reduce 框架,就完全无法有效地处理所有数据。

Chang 在 Twitter 学到的最有价值的一点内容就是:数据分析师从数据中提取出价值的能力,往往跟公司本身数据平台的成熟度有着密不可分的关系。如果你想要明白自己从事的是哪种类型的数据分析工作,首先去做做调研,看看你意向中的这家公司的底层系统架构能够在多大程度上支持你的目标,这不仅仅对你好,也对公司好,借此看你个人的职业发展目标是否跟公司的需要契合起来。

在初创公司早期,最主要的分析重点是为了实现 ETL 进程,模块化数据,并且设计基模架构,将数据记录应用到上面。这样数据就能够追踪并存储。此处的目标是打下分析工具的基础,而不是分析本身。,

在快速发展的初创公司的中期,因为公司在快速发展,那么数据也在不断的增长。数据平台需要适应不断发展的新形势,新条件,在已经打好基础的前提下,开始逐渐实现向分析领域的过渡。一般来说,此时的分析工作主要围绕着制定 KPI,推动增长,寻找下一次增长机会等工作展开。

实现了规模增长的公司。当公司实现了规模化增长,数据也开始呈几何倍数的增长。此时公司需要利用数据来创造,或者保持某种竞争性优势,比如更好的搜索结果,更加相关的推荐内容,物流或者运营更加的高效合理。这个时候,诸如 ML 工程师,优化专家,实验设计师都可以参与进来一展拳脚了。

在 Chang 加入 Twitter 的时候,Twitter 已经有了非常成熟的平台以及非常稳定的底层结构。整个数据库内容都是非常干净,可靠的。ETL 进程每天轻松处理着数百个「任务调度」工作。(Map-Reduce)。更重要的是,在数据分析领域的人才都在数据平台、产品分析、用户增长、实验研究等多个领域,多个重点工作齐头并进一起展开。

关于 Chang 本人的经历

他是在用户增长领域安排的第一名专职数据分析师。事实上,这花了他们好几个月来研究产品、工程、还有数据分析到底该如何融合,才能实现这样一个岗位角色。Chang 的工作与产品团队紧密连接,根据这方面的工作经验,他将自己的工作职责划分成为了下面几类内容:

产品分析

数据传输通道

实验(A/B 测试)

建模

下面将会按照排列次序逐一解释

产品分析

对于一家消费级科技公司来说,产品分析意味着利用数据来更好地理解用户的声音和偏好。不管什么时候用户与产品进行着互动,Twitter 都会记录下来最有用的数据,存储好它们,以待未来某一天分析之用。

这个过程被称之为「记录」(logging)或者「工具化」(instrumentation),而且它还不断地自我演进。 通常情况下,数据分析往往很难实现某个具体的分析,因为数据要么是不太对,要么是缺失,要么是格式错误的。在这里,跟工程师保持非常好的关系非常有必要,因为数据分析能够帮助工程师确认 bug 的位置,或者系统中一些非预期的行为。反过来,工程师可以帮助数据分析弥补「数据鸿沟」,使得数据内容变得丰富,彼此相关,更加准确。

下面举出来了 Chang 在 Twitter 展开的几项与产品有关的分析案例:

推送通知分析:有多少用户能用得到「推送通知」?不同类型的推送通知具体的点击率都分别是多少?

SMS 发送率:在不同的数字载体上,Twitter 的 SMS 发送率都是怎么计算的?是不是在发展中国家这个发送率相对比较低?我们该怎样提升这个数字?

多账户:为什么在某些国家,一个人持有多个账户的比例会相对较高?背后是什么动机让一个人持有多个账户?

分析会以多种形式展开。有些时候公司会要求你对一次简单的数据拉取进行最直白的解读,又或者你需要想出一些新的方式方法来机选一个全新,且重要的运营指标。(比如 SMS 发送率),最后你会更加深刻地理解用户的行为。(比如一个人拥有多个账户)

在产品分析中不断研究,得到真知灼见,这是一个不断迭代演进的过程。它需要不断地提出问题,不断地理解商业情境,找出最正确的数据组来回答相应的问题。随着时间的累积,你将成为数据领域的专家,你会正确地估计出来执行一次分析大概得花多长时间。更重要的是,你将逐渐从一个被动响应的状态,逐渐过渡到主动采取行动的状态,这其中会牵连出来很多有趣的分析,这些内容都是产品负责人曾经压根没有考虑过的,因为他们不知道这些数据存在,又或者不同类型的数据以某种特殊的方式组合到一起竟然会得出如此惊人的结论。

此处需要的技能

保存和工具化:确认数据鸿沟。与工程部门建立良好的协作关系;

有能力引导和确认相关的数据组,知道正确使用它们的方式;

理解不同形式的分析,能够在不同的分析执行之前就正确地估算出难易程度,所需时间长短;

掌握你的查询语言。一般来说是利用 R 或者 Python 来实现数据再加工;

数据管道

即使 A 型数据分析师不太可能自己编写代码,直接应用到用户那里,但是出乎很多人意料的是,包括 Chang 在内的很多 A 型数据分析师确实在给代码库写东西,目的只有一个:为了数据管道处理。

如果你从 Unix 那里听说过「对一系列命令的执行」,那么一个数据管道就意味着多个系列命令的执行,我们能够不断周而复始地自动捕捉,筛选,集合数据。

在来到 Twitter 之前,Chang 的分析绝大部分都是点对点的。在 Chang 的本地机器上,代码执行上一次或者几次。这些代码很少得到审查,也不太可能实现版本控制。但是当一个数据通道出现的时候,一系列的功能就浮出水面:比如「依赖管理」、「调度」、「源头分配」、「监控」、「错误报告」以及「警告」。

下面介绍了创建一个数据管道的标准流程:

你忽然意识到,如果一个数据组能够周而复始地自我重新产出,那么这个世界估计会因此受益;

在确认了需求之后,你开始设计「生产数据组」的「数据架构」;

开始编写你的代码,不管是在 Pig,Scalding,或者 SQL 中。这取决于你的数据环境是什么;

提交代码,进行代码审查(code review),准备后得到回馈,并做相应额外的修改。要么是因为你的设计逻辑不太对,要么是你的代码出于速度和效率的目的并没有优化到位;

应该有一个「测试」和「试运转」的环境,确保所有的运行都在既定的轨道上。

将你的代码融合到主库中

建立「监控」、「错误报告」以及「警告」等功能,以防止未来出现预期之外的状况。

很显然,数据通道比一个点对点的分析工具来说更加复杂,但是优势也非常明显,因为它是自动化运行着的,它所产出的数据能够进一步强化面板,这样更多的用户能够消费你的数据/结果。

另外,更加重要但是往往被人忽略的一点结果是,对于如何打造最优化的工程设计,这是一个非常棒的学习过程。如果你在日后需要开发一个特别定制的数据通道,比如机器学习,之前所做的工作就成为了扎实的基础。

在此处需要用到的技能:

版本控制,目前最流行的就是 Git;

知道如何去做「代码审核」,并且知道如何有效地给予反馈;

知道如何去测试,如何去试运行,当出现错误的时候知道如何「debug」;

「依赖管理,调度,资源分配,错误报告,警告」功能的设置。

接下来的篇章中,我们将谈到除了“产品分析”之外,其余的三种工作内容,它们分别是: 数据传输通道、实验(A/B 测试)、以及建模。

MapReduce程序的工作过程 - 1000sprites

$
0
0

     还记得2.5年前就搭建好了Hadoop伪分布式集群,安装好Eclipse后运行成功了WordCount.java,然后学习Hadoop的步伐就变得很慢了,相信有很多小伙伴和我一样。自己对MR程序(特指Hadoop 1.x版本)的工作过程一直都不是很清楚,现在重点总结一下,为MR编程打好基础。由于MapReduce是基于HDFS的操作,因此要想深入理解MapReduce(解决的是分布式计算问题),首先得深入理解HDFS(解决的是分布式存储问题)。

一. HDFS框架组成

hdfsarchitecture

HDFS采用master/slaver的主从架构,一个HDFS集群包括一个NameNode节点(主节点)和多个DataNode节点(从节点),并提供应用程序的访问接口。NameNode,DataNode和Client的解释,如下所示:

  • NameNode负责文件系统名字空间的管理与维护,同时负责客户端文件操作(比如打开,关闭,重命名文件或目录等)的控制及具体存储任务的管理与分配(比如确定数据块到具体DataNode节点的映射等);
  • DataNode负责处理文件系统客户端的读写请求,提供真实文件数据的存储服务;
  • Client是客户端,一般指的是访问HDFS接口的应用程序,或者HDFS的Web服务(就是让用户通过浏览器来查看HDFS的运行状况)等。

1. 文件的读取

Client与之交互的HDFS、NameNode、DataNode文件的读取流程,如下所示:

捕获

  • Client向远程的NameNode发起RPC请求;(1)
  • NameNode会返回文件的部分或者全部Block列表,对于每个Block,NameNode都会返回该Block副本的DataNode地址;(2)
  • Client会选择与其最接近的DataNode来读取Block,如果Client本身就是DataNode,那么将从本地直接读取数据;(3)
  • 读完当前Block后,关闭与当前的DataNode连接,并为读取下一个Block寻找最近的DataNode;(4)
  • 读完Block列表后,并且文件读取还没有结束,Client会继续向NameNode获取下一批Block列表;(5)
  • 读完一个Block都会进行Cheeksum验证,如果读取DataNode时出现错误,Client会通知NameNode,然后从该Block的另外一个最近邻DataNode继续读取数据。Client读取数据完毕之后,关闭数据流。(6)

2. 文件的写入

Client与之交互的HDFS、NameNode、DataNode文件的写入流程,如下所示:

捕获

  • Client向远程的NameNode发起RPC请求;(1)
  • NameNode便会检查要创建的文件是否已经存在,创建者是否有权限进行操作等,如果满足相关条件,就会创建文件,否则会让Client抛出异常;(2)
  • 在Client开始写入文件的时候,开发库(即DFSOutputStream)会将文件切分成一个个的数据包,并写入”数据队列“,然后向NameNode申请新的Block,从而得到用来存储复本(默认为3)的合适的DataNode列表,每个列表的大小根据NameNode中对replication的设置而定;(3)
  • 首先把一个数据包以流的方式写入第一个DataNode,其次将其传递给在此管线中的下一个DataNode,然后直到最后一个DataNode,这种写数据的方式呈流水线的形式;(假设复本为3,那么管线由3个DataNode节点构成,即Pipeline of datanodes)(4)
  • 当最后一个DataNode完成之后,就会返回一个确认包,在管线里传递至Client,开发库(即DFSOutputStream)也维护着一个”确认队列”,当成功收到DataNode发回的确认包后便会从“确认队列”中删除相应的包;(5)
  • 如果某个DataNode出现了故障,那么DataNode就会从当前的管线中删除,剩下的Block会继续在余下的DataNode中以管线的形式传播,同时NameNode会再分配一个新的DataNode,以保持replication设定的数量。Client写入数据完毕之后,关闭数据流。(6)

说明:HDFS默认Block的大小为64M,提供SequenceFile和MapFile二种类型的文件。

 

二. MapReduce框架组成

MapReduce框架的主要组成部分和它们之间的相关关系,如下所示:

20141219140722943

 

上述过程包含4个实体,各实体的功能,如下所示:

  • Client:提交的MapReduce作业,比如,写的MR程序,或者CLI执行的命令等;
  • JobTracker:协调作业的运行,本质是一个管理者;
  • TaskTracker:运行作业划分后的任务,本质就是一个执行者;
  • HDFS:用来在集群间共享存储的一种抽象文件系统。

直观来说,NameNode就是一个元数据仓库,就像Windows中的注册表一样。SecondaryNameNode可以看成NameNode的备份。DataNode可以看成是用来存储作业划分后的任务。在通常搭建的3台Hadoop分布式集群中,Master是NameNode,SecondaryNameNode,JobTracker,其它2台Slaver都是TaskTracker,DataNode,并且TaskTracker都需要运行在HDFS的DataNode上面。

上述用到的类,或者进程的功能,如下所示:

  • Mapper和Reducer

基于Hadoop的MapReduce应用程序最今本的组成部分包括:一个Mapper抽象类,一个Reducer抽象类,一个创建JobConf的执行程序。

  • JobTracker

JobTracker属于master,一般情况应该部署在单独的机器上,它的功能就是接收Job,负责调度Job的每一个子任务Task运行在TaskTracker上,并且监控它们,如果发现有失败的Task就重启它即可。

  • TaskTracker

TaskTracker是运行于多节点的slaver服务,它的功能是主动通过心跳与JobTracker进行通信接收作业,并且负责执行每一个任务。

  • JobClient

JobClient的功能是在Client提交作业后,把一些文件上传到HDFS,比如作业的jar包(包括应用程序以及配置参数)等,并且把路径提交到JobTracker,然后由JobTracker创建每一个Task(即MapTask和ReduceTask)并将它们分别发送到各个TaskTracker上去执行。

  • JobInProgress

JobClient提交Job后,JobTracker会创建一个JobInProgress来跟踪和调度这个Job,并且把它添加到Job队列中。JobInProgress根据提交的Job Jar中定义的输入数据集(已分解成FileSplit)创建对应的一批TaskInProgress1用于监控和调度Task。

  • TaksInProgress2

JobTracker通过每一个TaskInProgress1来运行Task,这时会把Task对象(即MapTask和ReduceTask)序列化写入相应的TaskTracker中去,TaskTracker会创建对应的TaskInProgress2用于监控和调度该MapTask和ReduceTask。

  • MapTask和ReduceTask

Mapper根据Job Jar中定义的输入数据<key1, value1>读入,生成临时的<key2, value2>,如果定义了Combiner,MapTask会在Mapper完成后调用该Combiner将相同Key的值做合并处理,目的是为了减少输出结果。MapTask全部完成后交给ReduceTask进程调用Reducer处理,生成最终结果<key3, value3>。具体过程可以参见[4]。

 

三. MapReduce工作原理

整个MapReduce作业的工作工程,如下所示:

20141219104145474

1. 作业的提交

JobClient的submitJob()方法实现的作业提交过程,如下所示:

  • 通过JobTracker的getNewJobId()请求一个新的作业ID;(2)
  • 检查作业的输出说明(比如没有指定输出目录或输出目录已经存在,就抛出异常);
  • 计算作业的输入分片(当分片无法计算时,比如输入路径不存在等原因,就抛出异常);
  • 将运行作业所需的资源(比如作业Jar文件,配置文件,计算所得的输入分片等)复制到一个以作业ID命名的目录中。(集群中有多个副本可供TaskTracker访问)(3)
  • 通过调用JobTracker的submitJob()方法告知作业准备执行。(4)

2. 作业的初始化

  • JobTracker接收到对其submitJob()方法的调用后,就会把这个调用放入一个内部队列中,交由作业调度器(比如先进先出调度器,容量调度器,公平调度器等)进行调度;(5)
  • 初始化主要是创建一个表示正在运行作业的对象——封装任务和记录信息,以便跟踪任务的状态和进程;(5)
  • 为了创建任务运行列表,作业调度器首先从HDFS中获取JobClient已计算好的输入分片信息(6)。然后为每个分片创建一个MapTask,并且创建ReduceTask。(Task在此时被指定ID,请区分清楚Job的ID和Task的ID)。

3. 任务的分配

  • TaskTracker定期通过“心跳”与JobTracker进行通信,主要是告知JobTracker自身是否还存活,以及是否已经准备好运行新的任务等;(7)
  • JobTracker在为TaskTracker选择任务之前,必须先通过作业调度器选定任务所在的作业;
  • 对于MapTask和ReduceTask,TaskTracker有固定数量的任务槽(准确数量由TaskTracker核的数量和内存大小来决定)。JobTracker会先将TaskTracker的MapTask填满,然后分配ReduceTask到TaskTracker;
  • 对于MapTrask,JobTracker通过会选取一个距离其输入分片文件最近的TaskTracker。对于ReduceTask,因为无法考虑数据的本地化,所以也没有什么标准来选择哪个TaskTracker。

4. 任务的执行

  • TaskTracker分配到一个任务后,通过从HDFS把作业的Jar文件复制到TaskTracker所在的文件系统(Jar本地化用来启动JVM),同时TaskTracker将应用程序所需要的全部文件从分布式缓存复制到本地磁盘;(8)
  • TaskTracker为任务新建一个本地工作目录,并把Jar文件中的内容解压到这个文件夹中;
  • TaskTracker启动一个新的JVM(9)来运行每个Task(包括MapTask和ReduceTask),这样Client的MapReduce就不会影响TaskTracker守护进程(比如,导致崩溃或挂起等);
  • 子进程通过umbilical接口与父进程进行通信,Task的子进程每隔几秒便告知父进程它的进度,直到任务完成。

5. 进程和状态的更新

一个作业和它的每个任务都有一个状态信息,包括作业或任务的运行状态,Map和Reduce的进度,计数器值,状态消息或描述(可以由用户代码来设置)。这些状态信息在作业期间不断改变,它们是如何与Client通信的呢?

1

 

  • 任务在运行时,对其进度(即任务完成的百分比)保持追踪。对于MapTask,任务进度是已处理输入所占的比例。对于ReduceTask,情况稍微有点复杂,但系统仍然会估计已处理Reduce输入的比例;
  • 这些消息通过一定的时间间隔由Child JVM—>TaskTracker—>JobTracker汇聚。JobTracker将产生一个表明所有运行作业及其任务状态的全局视图。可以通过Web UI查看。同时JobClient通过每秒查询JobTracker来获得最新状态,并且输出到控制台上。

6. 作业的完成

当JobTracker收到作业最后一个任务已完成的通知后,便把作业的状态设置为"成功"。然后,在JobClient查询状态时,便知道作业已成功完成,于是JobClient打印一条消息告知用户,最后从runJob()方法返回。

 

四. Shuffle阶段和Sort阶段

Shuffle阶段是指从Map的输出开始,包括系统执行排序以及传送Map输出到Reduce作为输入的过程。Sort阶段是指对Map端输出的Key进行排序的过程。不同的Map可能输出相同的Key,相同的Key必须发送到同一个Reduce端处理。Shuffle阶段可以分为Map端的Shuffle和Reduce端的Shuffle。Shuffle阶段和Sort阶段的工作过程,如下所示:

2

如果说以上是从物理实体的角度来讲解MapReduce的工作原理,那么以上便是从逻辑实体的角度来讲解MapReduce的工作原理,如下所示:

1. Map端的Shuffle

  • Map函数开始产生输出时,并不是简单地把数据写到磁盘,因为频繁的磁盘操作会导致性能严重下降。它的处理过程更复杂,数据首先写到内存中的一个缓冲区,并做一些预排序,以提升效率;
  • 每个MapTask都有一个用来写入输出数据的循环内存缓冲区(默认大小为100MB),当缓冲区中的数据量达到一个特定阈值时(默认是80%)系统将会启动一个后台线程把缓冲区中的内容写到磁盘(即spill阶段)。在写磁盘过程中,Map输出继续被写到缓冲区,但如果在此期间缓冲区被填满,那么Map就会阻塞直到写磁盘过程完成;
  • 在写磁盘前,线程首先根据数据最终要传递到的Reducer把数据划分成相应的分区(partition)。在每个分区中,后台线程按Key进行排序(快速排序),如果有一个Combiner(即Mini Reducer)便会在排序后的输出上运行;
  • 一旦内存缓冲区达到溢出写的阈值,就会创建一个溢出写文件,因此在MapTask完成其最后一个输出记录后,便会有多个溢出写文件。在在MapTask完成前,溢出写文件被合并成一个索引文件和数据文件(多路归并排序)(Sort阶段);
  • 溢出写文件归并完毕后,Map将删除所有的临时溢出写文件,并告知TaskTracker任务已完成,只要其中一个MapTask完成,ReduceTask就开始复制它的输出(Copy阶段);
  • Map的输出文件放置在运行MapTask的TaskTracker的本地磁盘上,它是运行ReduceTask的TaskTracker所需要的输入数据,但是Reduce输出不是这样的,它一般写到HDFS中(Reduce阶段)。

2. Reduce端的Shuffle

  • Copy阶段:Reduce进程启动一些数据copy线程,通过HTTP方式请求MapTask所在的TaskTracker以获取输出文件。
  • Merge阶段:将Map端复制过来的数据先放入内存缓冲区中,Merge有3种形式,分别是内存到内存,内存到磁盘,磁盘到磁盘。默认情况下第一种形式不启用,第二种Merge方式一直在运行(spill阶段)直到结束,然后启用第三种磁盘到磁盘的Merge方式生成最终的文件。
  • Reduce阶段:最终文件可能存在于磁盘,也可能存在于内存中,但是默认情况下是位于磁盘中的。当Reduce的输入文件已定,整个Shuffle就结束了,然后就是Reduce执行,把结果放到HDFS中。

 

五. 其它

HDFS和MapReduce是Hadoop的基础架构。除了上述讲解之外,还有MapReduce容错机制,任务JVM重用,作业调度器等都还没有总结。彻底理解了MapReduce的工作原理之后就可以大量的MapReduce编程了,计划将Hadoop自带实例看完后,再研读《Mahout实战》,同步学习《Hadoop技术内幕:深入解析YARN架构设计与实现原理》,正式迈入Hadoop 2.x版本的大门。

 

参考文献:

[1] 《Hadoop权威指南》(第二版)

[2] 《Hadoop应用开发技术详解》

[3] Hadoop 0.18文档: http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html

[4] WordCount源码剖析: http://blog.csdn.net/recommender_system/article/details/42029311

[5] 外部排序技术之多路归并排序: http://blog.chinaunix.net/uid-25324849-id-2182916.html


本文链接: MapReduce程序的工作过程,转载请注明。

RAID5工作原理是什么?

$
0
0

RAID5工作原理是什么?

 

RAID 5 是一种存储性能、数据安全和存储成本兼顾的存储解决方案。 以四个硬盘组成的RAID 5为例,其数据存储方式如图4所示:图中,P0为D0,D1和D2的奇偶校验信息,其它以此类推。由图中可以看出,RAID 5不对存储的数据进行备份,而是把数据和相对应的奇偶校验信息存储到组成RAID5的各个磁盘上,并且奇偶校验信息和相对应的数据分别存储于不同的磁盘上。当RAID5的一个磁盘数据发生损坏后,利用剩下的数据和相应的奇偶校验信息去恢复被损坏的数据。

 

  RAID 5可以理解为是RAID 0和RAID 1的折衷方案。RAID 5可以为系统提供数据安全保障,但保障程度要比Mirror低而磁盘空间利用率要比Mirror高。RAID 5具有和RAID 0相近似的数据读取速度,只是多了一个奇偶校验信息,写入数据的速度比对单个磁盘进行写入操作稍慢。同时由于多个数据对应一个奇偶校验信息,RAID 5的磁盘空间利用率要比RAID 1高,存储成本相对较低。

 

  RAID5校验位算法原理

 

  P=D1 xor D2 xor D3 … xor Dn (D1,D2,D3 … Dn为数据块,P为校验,xor为异或运算)

 

  XOR(Exclusive OR)的校验原理如下表:

 

  

A值B值Xor结果
000
101
011
110

 

 

  这里的A与B值就代表了两个位,从中可以发现,A与B一样时,XOR结果为0,A与B不一样时,XOR结果就是1,而且知道XOR结果和A与B中的任何一个数值,就可以反推出另一个数值。比如A为1,XOR结果为1,那么B肯定为0,如果XOR结果为0,那么B肯定为1。这就是XOR编码与校验的基本原理。

 RAID的保存原理是用Bit Striping及当前主流Block Striping的分割方式,将Data分散保存至各硬盘中,
当硬盘有受损时则经由XOR运算,再将存在其他各硬盘内的Parity Blocks及Data Stripe磁区的
Data Blocks进行计算而重建资料Rebuild。

其图解如下

RAID 5 Striping 架构 :: RAID-5 Striping Mode

 

RAID 5 受损运作模式 :: RAID-5 Degraded Mode

 

RAID 5 XOR 复原 :: RAID-5 XOR Data Recovery

 

参考: http://blog.itpub.net/787018/viewspace-666279/

参考注意:在看RAID5时,多个数据对应一个奇偶校验信息



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Java Servlet工作原理问答

$
0
0

导读

本文来自stackoverflow的问答,讨论了Java Servlet的工作机制,如何进行实例化、共享变量和多线程处理。

问题:Servlet是如何工作的?Servlet 如何实例化、共享变量、并进行多线程处理?

假设我有一个运行了大量 Servlet的 web 服务器。通过 Servlet之间传输信息得到 Servlet上下文,并设置 session 变量。

现在,如果有两名或更多使用者向这个服务发送请求,接下来 session 变量会发生什么变化?究竟是所有用户都是用共同的变量?还是不同的用户使用的变量都不一样?如果是后者,服务器如何区分不同用户?

另一个相似的问题,如果有 *n*名用户访问一个特定的 Servlet,那么该 Servlet是仅在第一个用户首次访问的时候实例化,还是分别为每个用户实例化?

回答(BalusC):

ServletContext

当 Servlet 容器(比如 Apache Tomcat)启动后,会部署和加载所有 web 应用。当web 应用被加载,Servlet 容器会创建一次 ServletContext,然后将其保存在服务器的内存中。web 应用的 web.xml被解析,找到其中所有 servletfilterListener@WebServlet@WebFilter@WebListener注解的内容,创建一次并保存到服务器的内存中。对于所有过滤器会立即调用 init()。当 Servlet 容器停止,将卸载所有 web 应用,调用所有初始化的 Servlet 和过滤器的 destroy()方法,最后回收 ServletContext和所有 Servlet、Filter 与 Listener实例。

当问题中的 Servlet配置的 load-on-startup或者 @WebServlet(loadOnStartup)设置了一个大于 0 的值,则同样会在启动的时候立即调用 init()方法。“load-on-startup”中的值表示那些 Servlet 会以相同顺序初始化。如果配置的值相同,会遵循 web.xml中指定的顺序或 @WebServlet类加载的顺序。另外,如果不设置 “load-on-startup” 值, init()方法只在第一次 HTTP 请求命中问题中的 Servlet 时才被调用。

HttpServletRequest 与 HttpServletResponse

Servlet 容器附加在一个 web 服务上,这个 web 服务会在某个端口号上监听 HTTP 请求,在开发环境中这个端口通常为 8080,生产环境中通常为 80。当客户端(web 浏览器)发送了一个 HTTP 请求,Servlet 容器会创建新的 HttpServletRequestHttpServletResponse对象,传递给已创建好并且请求的 URL 匹配 url-patternFilterServlet实例中的方法,所有工作都在同一个线程中处理。

request 对象可以访问所有该 HTTP 请求中的信息,例如 request header 和 request body。response 对象为你提供需要的控制和发送 HTTP 响应方法,例如设置 header 和 body(通常会带有 JSP 文件中的 HTML 内容)。提交并完成HTTP 响应后,将回收 request 和 response 对象。

HttpSession

当用户第一次访问该 web 应用时,会通过 request.getSession()第一次获得 HttpSession。之后 Servlet 容器将会创建 HttpSession,生成一个唯一的 ID(可以通过 session.getId()获取)并储存在服务器内存中。然后 Servlet 容器在该次 HTTP 响应的 Set-Cookie头部设置一个 Cookie,以 JSESSIONID作为 Cookie 名字,那个唯一的 session ID 作为 Cookie的值。

按照 HTTP cookie 规则(正常 web 浏览器和 web 服务端必须遵循的标准),当 cookie 有效时,要求客户端(浏览器)在后续请求的 Cookie头中返回这个 cookie。使用浏览器内置的 HTTP 流量监控器,你可以查看它们(在 Chrome、Firefox23+、IE9+ 中按 F12,然后查看 Net/Network 标签)。Servlet 容器将会确定每个进入的 HTTP 请求的 Cookie头中是否存在名为 JSESSIONID的 cookie,然后用它的值(session ID)从服务端内存中找到关联的 HttpSession

你可以在 web.xml中设置 session-timeout,默认值为 30 分钟。超时到达之前 HttpSession会一直存活。所以当客户端不再访问该 web 应用超过 30 分钟后,Servlet 容器就会回收这个 session。后续每个请求,即使指定 cookie 名称也不能再访问到相同的 session。Servlet 容器会创建一个新的 Cookie

另一方面,客户端上的 session cookie 有一个默认存活时间,该事件和该浏览器实例运行时间一样长。所以,当客户端关闭该浏览器实例(所有标签和窗口)后,这个 session 就会被客户端回收。新浏览器实例不再发送与该 session 关联的 cookie。一个新的 request.getSession()将会返回新的 HttpSession并设置一个拥有新 session ID 的 cookie。

概述

  • ServletContext与 web 应用存活时间一样长。它被所有 session 中的所有请求共享。
  • 只要客户端一直与相同浏览器实例的web应用交互并且没有超时,HttpSession就会存在。
  • HttpServletRequestHttpServletResponse的存活时间为客户端发送完成到完整的响应(web 页面)到达的这段时间。不会被其他地方共享。
  • 所有 ServletFilterListener对象在 web 应用运行时都是活跃的。它们被所有 session 中的请求共享。
  • 你设置在 HttpServletRequestHttpServletResponseHttpSession中的所有属性在问题中的对象存活时都会一直保持存活。

线程安全

即便如此,你最关心的可能是线程安全。你现在应该学习到 Servlet 和 filter 被所有请求共享。那是 Java 的一个优点,使得多个不同线程(读取 HTTP 请求)可以使用同一个实例。否则为每个请求重新创建线程的开销实在过于昂贵。

但你应该也意识到永远不要将任何 request 或 session 域中的数据赋值给 servlet 或 filter 的实例变量。它将会被所有其他 session 中的所有请求共享。那是非线程安全的!下面的示例对这种情况进行了展示:

public class ExampleServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } 
}

请参考:

相关文章

从事造价工作需要多少施工知识?

$
0
0

有很多朋友问过同样一个问题,就是学造价是不是要先做几年施工员再转行比较好,今天咱们来谈谈这个问题。

感谢 @陈子善先生的提醒, 本文中的造价师是指在造价咨询公司工作的造价师,对于在施工单位做成本管理的造价师并不是特别适用。

先上结论,没必要。

首先先回答一个问题,有些人会说,你如果都施工工艺一窍不通,那么叫人怎么说服别人同意你的方案?

首先,不做施工员不代表对施工工艺一窍不通,对于大部分工艺,造价师只要做到了解就够了,而部分较为重要的工艺,造价师要做到熟悉,但是完全没有必要去掌握一门工艺,对施工工艺有一知半解,已经足够做好一份造价工作。掌握一门施工工艺,或许能让你如虎添翼,但是值不值得花上大量时间掌握,还需要商榷。

其次,造价师为什么和方案要扯上关系?就目前来说,不管在哪一个单位任职,一般情况下造价人员都没有责任去承担出具设计方案的责任,造价师大部分时间只要按照给定的方案做出准确的造价就行了,即使是要做方案比选,只要委托方给出不同的方案,做出不同的造价对比就行了,怎么也轮不到造价师来确定方案。

既然造价人员需要了解和熟悉施工工艺,那为什么不建议先去施工单位后再转行呢?

很简单,施工单位熟悉工艺的效率是非常低下的,大家都明白,工程项目的周期是比较长的,修一公里的路和修十公里的路你所掌握的施工工艺也可能是完全一样的,在施工单位待上一年,并不代表你学习了非常多的施工工艺。而有些同学运气差点的,到一个施工单位待了半年,结果整整半年都在打桩基础,重复又重复,其他的什么都没学到,这个同学就是我。

(图为桩基础施工的下钢筋笼)

在施工单位,宝贵的是应急处理能力,比如说钻孔遇到溶洞了如何处理、钢筋笼上浮了如何处理等等,而不是对施工工艺的熟悉和了解程度,在施工单位培养出来的能力,到了造价岗位不一定用得上,举我一个以前说过的简单例子,我有时候会做一些绿化项目,秋枫是什么?勒杜鹃是什么?金山棕是什么?全摆到我面前来,我一个都认不出。可是这并不影响我做项目,我只要了解种树需要挖土、栽植、回填、支撑、保养、浇水,那就够了,然后在网上对苗木进行询价,单价就出来了。我为什么要去施工单位学习怎么种树,怎么把树种好,怎么保养一株苗木呢?这些对造价工作毫无意义。

(你说这是啥?)

像我做公路项目的,一个大型项目通常都包含路基 、路面、桥梁、涵洞、隧道、交安、机电、绿化等不同的专业,我如果每个工艺都想熟悉起来,我是不是要在施工单位混上十年再转行呢?那如果我在施工单位熟悉掌握了路基路面,那么在大型项目到来的时候,我是不是该向老板反映下我只做路基路面部分,其他专业给其他同事做呢?这事儿咱想都不敢想。就算真的不懂了,问下同事总行了吧?再不济的情况下,拿别人做的项目照抄总行了吧?下次记住就行了。

(隧道盾构机)

在互联网发达的今天,造价人员根本没必要到施工单位熟悉施工工艺,网络上可以找到各种施工视频、图片和动画等等辅助我们进行学习,而像二建和一建考试,很多老师讲实务课程的时候也会充分讲解各种施工工艺,学习的途径非常非常多,花几天时间搜集下视频图片,然后都看一遍,效率比去施工单位上班高多了吧。


而另一方面,每一年的时间是非常宝贵的,造价人员要学习的知识是非常多,如果你是打算从事造价工作,那么花费一年两年的时间在施工单位学习,你所学到的对造价有用的知识绝对不会比待在造价公司里多,现代社会是个分工明确的社会,造价人员有造价人员的工作方式,想走哪一条路,就该直接走哪一条路。

先做施工再转行做造价,忽略了一些自己无法控制的因素,现在很多造价公司都要招有经验的人员,你如果拿着几年施工经验去投造价公司的简历,造价公司不一定会要,就算进了公司,很多时候也是从基层的算量做起,很有可能你的待遇还是腰斩,我想并不是有很多人能下这么大一个决心。

最后希望大家还是能多和我交流一下,毕竟我的阅历和眼界也有限,多多交流才能共同进步,这也是我写这个专栏的目的。



来源:知乎 www.zhihu.com
作者: 杨嘉宁

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。 点击下载

锤子CTO钱晨:加班要么是你笨,要么是工作安排不合理

$
0
0

锤子科技的 CTO 钱晨博士今年 53 岁,他把有些许灰白的头发剃得很短,显得精神抖擞。加入锤子科技前,他在中国手机界的黄埔军校摩托罗拉北京研发中心工作了 13 年,离开时任职高级工程经理。

1998 年,36 岁的钱晨入职 MOTO,在之后的 13 年里,钱晨从一名普通工程师,做到工程产品经理,再之后负责管理 ODM(原始设计商)。在 MOTO 的初创阶段,钱晨以一年升一级的速度快速晋升。

雷军曾经在一次采访中提到,他前后花了三个月时间,想邀请钱晨加盟小米,最终未能成行。罗永浩随后抓住机会,磨了半年,说服钱晨入职锤子科技,担任 CTO。

他经历过国营单位、跨国企业和创业公司;他喜欢收藏字画古玩、爱饮茶讲风水;他自己连续 4 年每晚加班到 11 点,却不认同手下的人加班;他认为好的福利意味着公司堕落,每年四十天年假他从未享受过。

Lagou 约到了钱晨博士,跟他聊了聊他眼中的职场与人生。“不是倚老卖老,是因为这些事儿自己都摔过疼过,所以能谈谈。”

锤子 CTO 钱晨:不佩服有手艺的人,佩服有方向感的人

“加班是因为你笨”

钱晨入职 MOTO 后,前 4 年里几乎天天加班。“每天早晨 9 点到,晚上 11 点走。但我从来不觉得这是值得炫耀的东西,要学的东西太多了,当时根本学不完。”

在锤子当 CTO 以后,钱晨开始寻找能在 8 小时内做完事的下属。

“我认为生活更重要。我给工程师们提的要求是,不希望看到他们加班。我看到他加班就意味着,要么是他太笨,要么是老板对他的工作安排不合理,或者他答应我的工作不合理。”

锤子硬件团队现在的氛围是,钱晨不加班,他走的时候从不去看手下的工程师是否加班。他认为加班文化是一种恶俗文化,如果有公司倡导加班文化,那说明这个公司在赤裸裸地剥削。

提到在 MOTO 四年的加班,他说那是自己乐意。“我有我的追求,我想做更大的事儿,我想在短时间内做更多的事儿。因为只有实验室有条件让我去做,回家干不了。”第五年,钱晨成为领导,开始投入到对字画、手表、古玩的研究中,生活里的各种乐趣出现,他慢慢不再加班。

如果在公司里能学到东西,如果有做大事的追求,如果觉得生活无聊不如工作,那就去加班吧。但记住,千万不要跟老板炫耀,千万不要忘了生活。

“学不到东西的时候,就是离开的时候”

MOTO 是一个按照级别排位的公司,从 1 级开始,最高 18 级。1998 年,钱晨入职时被定为 8 级员工。

之后的 4 年,钱晨以一年一级的节奏快速晋升。2002 年,钱晨升到 12 级,成为高级工程经理。后 9 年,钱晨一直呆在这个位置上。

“9 年里,很多猎头来挖,但我没走。MOTO 这个学校太大,有很多东西要学。”钱晨把自己在 MOTO13 年的工作经历划分成三段,先是做工程师,学工程和设计;然后当工程产品经理,学习开发与设计产品;再之后管理 ODM,学习把 MOTO 好的设计与产品质量标准传达出去。

MOTO 是当时全国待遇最高的外企之一,很多漂亮的姑娘在这里做前台。“2003 年 MOTO 一个前台可以拿到六七千的工资。但是有什么职业生涯吗?前台再往上还能做什么,做到秘书,然后呢,没了。”

“公司大小,工资,福利,这些都不重要。你在一个公司,要看自己是在一个节点上,还是在一根线上。如果你在一个节点,你会看到四个方向,而如果你在一根线上趴着,你就只能看到这根线。”

比如销售是节点部门,它上接产品,下接客户。广告可能就不是节点部门,因为它处于产品末端。“我在 MOTO 呆了那么久,一直处在节点部门,我做研发,跟生产、销售、品质都在打交道。”

假如你在公司的市场部负责售卖一款肥皂,销量不好。你并不知道这款肥皂卖这个价格,也不知道销量不好的原因是价格不合理或者品质问题亦或其他原因。你没有参与任何与之相关的促销决策或者市场分析。那么这时候,你就不在一个节点岗位上,而只是一个执行者。

“如果这个人够聪明,几年后他会成为节点。他会去观察别人怎么卖,其他商家为什么能卖出去。但如果他傻卖,混日子,天天想着吃饭晒微博。他以为这就是生活,其实这不是。因为他在这个公司没有未来,他学不到东西。”

当你觉得学不到东西的时候,就是离开的时候。

“我在 MOTO 被训练的是眼光和志向”

钱晨离开 MOTO 是 2011 年,当时 MOTO 还未被谷歌收购。“但从公司的种种迹象上来开,我觉得它做的都是要卖的动作,所以我就走了。”

钱晨读过人大的 EMBA,用他的话来说,虽然特无聊,连毕业证也没要,但还是学了一些观察公司的基本方法。

离开 MOTO 时,钱晨对手机行业不再有热情。他转而投身上游的芯片生产企业,入职 Marvell 芯片公司,担任硬件总监。“但这个公司超级无聊,胸无大志,最近也解散了。”

“我在 MOTO 被训练的根本不是怎么做事,训练的是眼光和志向。公司的价值观很重要,要去有追求的公司。看他们员工最有兴趣的点是什么。MOTO 和诺基亚到了最后,员工最有兴趣的点都变成这个公司福利好。”

在钱晨看来,福利好是一种堕落的公司文化,他不看好谷歌。“谷歌一再宣扬自己福利好,但是真正有本事的人,他会在乎这件事吗?没本事才在乎这个。”

在 MOTO 工作的后期,钱晨每年有四十天年假,但他从未享受过。“如果我休八周假,这意味着什么,意味着我在公司没有价值。你说是选择休息四十天,还是让自己变得更有价值一点?”

刚入职 MOTO 时,作为 8 级员工,钱晨月薪九千。加班 4 年成为 12 级领导后,月薪 3 万。“3 万可以生活无忧了,但能以此为乐趣吗?工资高都是相对的,最重要的是你获取的乐趣在哪里。”

加入锤子科技后,钱晨开心了不少。

“这里有很多特别年轻有活力的人,我看他们是如何看待一个产品,尤其是他们如何敢冒险。他们看似散漫,但做起事却有灵气,这些我在摩托已经看不到了。老罗天天跟他们乐此不疲地折腾这件事,我也跟着老罗天天嗨,让自己眼界又开阔了。”

“喜欢聪明而焦虑的工程师”

“我认为工程师必备的素质,是聪明。如果他聪明同时充满焦虑,我就会很喜欢。”钱晨说。

他对聪明的解读是,思维方式多样,有考虑问题的综合能力。招聘的时候,他会问“喜马拉雅山和乞力马扎罗山有什么共同点”,看应聘者能否总结出两者的共性。

另一个要求是耐压。工作一定有压力,不会天天快乐。所以他会问应聘者,“假如你在街上看见一个流氓,他抽你一嘴巴,你怎么办?”或者直接说,“笔试成绩这么差,还好意思来面试吗?”

对这些问题的回答能够看出一个人是否乱了方寸,钱晨需要聪明与耐压的员工。“这是基本需求,进来以后再慢慢练,慢慢淘,淘出一些沟通能力好,有大视野的人。”

优秀的硬件工程师是用钱砸出来的,十年成就一个。

“我们让你做一个很小的东西,这个小东西是形式,关键看你怎么把它化成一个有高度的东西。

首先,让老板觉得你是个有效率的人。
第二,让老板觉得你是个有方法的人。
第三,让老板觉得你是个勤快的人。”

让老板感受到这几点,不需要拍马屁,只需要 Value added (增值)。给老板增值,给部门加分。

如果你是电子工程师,那么做完一个小物件,要整理成一个有信息干量的东西给老板。老板会观察你,觉得这小家伙还可以多做一点,就又给你多加一点。加完一点你又完成,他觉得还可以再给你加一点。逐渐你的面就宽了,做的东西会越来越多。

“我带工程师的时候,觉得最重要的是给他成长的空间。一个是知识的成长,一个是眼力的成长。如果一个小孩有这两方面的成长,我就会特有成就感。”

在以“工匠精神”著称的锤子科技,钱晨曾经这样解读过他眼中的工匠精神:做事认真,光认真不够,还要大气,还要有智慧。你要有创新,要有自己的设计语言。自己不原谅自己,这是一个关键点。要想出别人想不出的东西。

但即便如此,工匠在钱晨眼中依然称不上优秀。

“我不佩服有手艺的人,我佩服有方向感的人。Rudy Krolopp 是 MOTO 当年发明第一部移动电话的人,我佩服。乔布斯是第一个发明 smart phone 的人,我佩服。他们给大家带来了新的生活方式,剩下的事真的就只是做个好工匠而已。”

在网络上,钱晨给自己取名“工头 Jeff”,他没将自己定义为牛人,“真正的大公司都是靠体系结构活着,MOTO 当年像我这样的人有上百个。”但罗永浩依然认为自己挖到了宝,找到了最合适的 CTO。
来自: lagounews


三招教你写好工作汇报,早日升职加薪迎娶白富美

$
0
0

花了一天的时间参加了李忠秋老师结构思考力课程的上海站社群答谢活动,99RMB听了一天的课程,首先说结论:“非常值!”

作为全场100多号人里面20个看过《金子塔》原理,并且是7个看完这本书的人里面的站起来大言不惭的讲这本书本身写的不够金字塔的人,对这门课程的第一感觉是实用,第二感觉是用心!

首先讲实用,课程去掉了金字塔中很多繁杂的东西,加入了很多本土化基于企业实际情况的更接地气的案例(如果你有听过另外一门同类课程,老师都是拿我党的公文做案例的时候,你就明白这个是多么的难能可贵了),所讲内容非常切合企业的真实工作需求,学完之后就能够立即用上,课堂最后的案例演练也证明了这一点。

第二个就是用心,说真心话,把简单的东西讲复杂真的很容易,但是把复杂的东西讲简单,是需要智慧和耐心的,就从本身课程的设计上来讲就是符合结构化思考的,这个也能看出老师本身的知行合一。课程中大量的案例,总结,提炼,教学活动都是经过精心设计的,非常有助于学学员的理解和接受,这点真的难能可贵!

以下是这次课程大概内容的笔记,提前预警,凭记忆写作,可能会有错误或疏漏!

一、结构思考力概念介绍

这部分内容很少,大概的介绍了结构思考的概念和收益,不知道现场有多少人注意到了,其实在这个过程中也蕴含了一个非常强大的结构模式,就是传说中的why-what-how.

 why-为什么要学习思考力?

总结起来就是一句话:结构思考力能够让你思考清晰,表达有力,生活清爽,工作高效!

 what-什么事结构思考力?

结构思考力是一种帮助人们察觉并改善自身思考结构的思考艺术,通过结构思考力“理解、重构、呈现”循环方法的运用,我们可以从结构的视角更加全面、清晰地看待和认知失误,有效改善思考质量。

其实这个概念的定义就有点类似于课程中讲到的序言的写作模式。

how-如何做到结构思考呢?

同样还是高度总结概括成了三点,分别是:

  • 理解:隐性思维显性化
  • 重构:显性思维结构化
  • 呈现:结构思维形象化

二、理解-隐性思维显性化

在理解部分,老师通过了关于书法介绍的案例导入,系统的介绍了理解的三个步骤,分别是:

  • 第一步,【识别】:识别信息中的事实理由以及结论,找出信息中哪些是观点类的,哪些是事实描述类的信息,观点类的信息哪些是结论,哪些是理由,并将其区分开来。第二步,【判断】:判断事实与观点的对应关系,并画出结构图。然后,找出这些事实和观点的对立关系,依据事实、理由、结论的对应关系画出树形图。第三步,【概括】一句话概括出所有内容。接受信息除了前两步做到看清楚想明白,最后还要简单扼要地概括出所有内容,做到说简洁。

其中在这里关于序言的描述部分老师给了一个非常牛叉的万能公式:

在-----的基础上,从-----,----,----,N个方面,说明了-------。

据说这个公式是新东方为了对付我大天朝的语文老师而创立,仔细回想一下貌似真的是非常有道理的,比如说服丈母娘把同意把女儿嫁给你的时候,就可以这么描述,在两个人相爱的基础上,从经济条件,年龄要求,学历层次,家庭背景四个方面,说明了你女儿应该嫁给我是正确的选择!(这个是已婚人士的自我YY),这样一来当年就省下了好多事情!

三、重构:显性思维结构化

重构部分主要讲了两个模块四个步骤,分别从横向和纵向两个维度做了讲解,纵向部分的要点是结论先行,以上统一;横向部分的要点是归类分组,逻辑递进,总结起来就是四个字 论证类比

(在此不得不对李老师牛叉的总结能力表示深深的叹服,请接收我深深的敬意)。

  • 【结论先行】每次表达的时候都先讲结论,并且每个结论只表达一个中心思想,类似于我们写议论文中的论点部分;这里给的一个技巧是:多问所以呢?
  • 【以上统下】要求在在任何层次上的思想都必须是下一层次思想的高度总结概括,并且是一个结论;
  • 【归类分组】每一个模块的内容和思想都必须在同一个框架之内,符合上面的结论,一般建议是每个小组内容在3-7条;这里的给到的工具是源自麦肯锡的“MECE”法则。
  • 【逻辑递进】每一个组的内容也要按照一定的逻辑顺序进行安放排列,这样能够更有效的传递出想要传递的信息;主要包括三种:时间顺序,结构顺序和重要性顺序

四:呈现:结构思维形象化

关于呈现部分,因为时间因素并没有讲太多,主要是从流程步骤上做了一些演示和示范,也包括三部分,分别是配关系,得图示,上包装,简称配得上!

课堂当中还展示一些关于如何提炼精简和总结的案例,包括各种各样的关系图,具体的细节都在下面这张结构罗盘中,我就不详细解释了,个人的感觉是这种东西第一要有意识,第二要看多积累,第三就是要多思考,第四这个还跟天赋和文学素养有关。我会告诉你我当年在混某国企的时候,为了写好PPT,我专门买了本《文心雕龙》么?


图来自于李忠秋老师结构思考力课件,版权归原作者所有

最后以一首小诗对课程感受和内容作了简短的总结:

参加李忠秋老师结构思考力上海一日答谢课

价格实惠内容好,老师有料颜值高!结论先行很重要,万能公式别小瞧;论证类比说重构,透过结构看思考;思维呈现配得上,工作汇报賊有效!

【如果你觉得内容对你有帮助,请点击分享或打赏,你的认可是我写作的动力!】



 

Android开发——DiskLruCache用法详解以及工作原理深度解析

$
0
0

概述
LruCache在加载大图、多图时解决了内存泄露的问题,但是另外一个问题随之而来:图片从内存移除后,用户又要重新加载已经移除的图片时,只能从网络上重新加载一次,显然非常耗时,这是照片墙应用最常用的功能。Google又提供了一套硬盘缓存的解决方案:DiskLruCache(非Google官方编写,但获得官方认证)。只可惜,Android Doc中并没有对DiskLruCache的用法给出详细的说明,而网上关于DiskLruCache的资料也少之又少,因此今天我准备专门写一篇博客来详细讲解DiskLruCache的用法,以及分析它的工作原理,这应该也是目前网上关于DiskLruCache最详细的资料了。

    那么我们先来看一下有哪些应用程序已经使用了DiskLruCache技术。在我所接触的应用范围里,Dropbox、Twitter、网易新闻等都是使用DiskLruCache来进行硬盘缓存的,其中Dropbox和Twitter大多数人应该都没用过,那么我们就从大家最熟悉的网易新闻开始着手分析,来对DiskLruCache有一个最初的认识吧。
     初探
     相信所有人都知道,网易新闻中的数据都是从网络上获取的,包括了很多的新闻内容和新闻图片,如下图所示:
     但是不知道大家有没有发现,这些内容和图片在从网络上获取到之后都会存入到本地缓存中,因此即使手机在没有网络的情况下依然能够加载出以前浏览过的新闻。而使用的缓存技术不用多说,自然是DiskLruCache了,那么首先第一个问题,这些数据都被缓存在了手机的什么位置呢? 其实DiskLruCache并没有限制数据的缓存位置,可以自由地进行设定,但是通常情况下多数应用程序都会将缓存的位置选择为 /sdcard/Android/data/<application package>/cache 这个路径。选择在这个位置有两点好处:第一,这是存储在SD卡上的,因此即使缓存再多的数据也不会对手机的内置存储空间有任何影响,只要SD卡空间足够就行。第二,这个路径被Android系统认定为应用程序的缓存路径,当程序被卸载的时候,这里的数据也会一起被清除掉,这样就不会出现删除程序之后手机上还有很多残留数据的问题。 那么这里还是以网易新闻为例,它的客户端的包名是com.netease.newsreader.activity,因此数据缓存地址就应该是 /sdcard/Android/data/com.netease.newsreader.activity/cache ,我们进入到这个目录中看一下,结果如下图所示:

     可以看到有很多个文件夹,因为网易新闻对多种类型的数据都进行了缓存,这里简单起见我们只分析图片缓存就好,所以进入到bitmap文件夹当中。然后你将会看到一堆文件名很长的文件,这些文件命名没有任何规则,完全看不懂是什么意思,但如果你一直向下滚动,将会看到一个名为journal的文件,如下图所示:
     那么这些文件到底都是什么呢?看到这里相信有些朋友已经是一头雾水了,这里我简单解释一下。上面那些文件名很长的文件就是一张张缓存的图片,每个文件都对应着一张图片,而journal文件是DiskLruCache的一个日志文件,程序对每张图片的操作记录都存放在这个文件中,基本上看到journal这个文件就标志着该程序使用DiskLruCache技术了。
    下载
     好了,对DiskLruCache有了最初的认识之后,下面我们来学习一下DiskLruCache的用法吧。由于DiskLruCache并不是由Google官方编写的,所以这个类并没有被包含在Android API当中,我们需要将这个类从网上下载下来,然后手动添加到项目当中。DiskLruCache的源码在Github上托管,地址如下:
https://github.com/JakeWharton/DiskLruCache下载好了源码之后,只需要在项目中新建一个libcore.io包,然后将DiskLruCache.java文件复制到这个包中即可。
     打开缓存
     这样的话我们就把准备工作做好了,下面看一下DiskLruCache到底该如何使用。首先你要知道,DiskLruCache是不能new出实例的,如果我们要创建一个DiskLruCache的实例,则需要调用它的open()方法,接口如下所示:
1
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) ;
open()方法接收四个参数,第一个参数指定的是数据的缓存地址,第二个参数指定当前应用程序的版本号,第三个参数指定同一个key可以对应多少个缓存文件,基本都是传1,第四个参数指定最多可以缓存多少字节的数据。
     其中缓存地址前面已经说过了,通常都会存放在 /sdcard/Android/data/<application package>/cache 这个路径下面,但同时我们又需要考虑如果这个手机没有SD卡,或者SD正好被移除了的情况,因此比较优秀的程序都会专门写一个方法来获取缓存地址,如下所示:
1
public File getDiskCacheDir(Context context, String uniqueName) {
2
    String cachePath;
3
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
4
            || !Environment.isExternalStorageRemovable()) {
5
        cachePath = context.getExternalCacheDir().getPath();
6
    } else {
7
        cachePath = context.getCacheDir().getPath();
8
    }
9
    return new File(cachePath + File.separator + uniqueName);
10
}
     可以看到,当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则就调用getCacheDir()方法来获取缓存路径。前者获取到的就是 /sdcard/Android/data/<application package>/cache 这个路径,而后者获取到的是 /data/data/<application package>/cache 这个路径。
接着又将获取到的路径和一个uniqueName进行拼接,作为最终的缓存路径返回。那么这个uniqueName又是什么呢?其实这就是为了对不同类型的数据进行区分而设定的一个唯一值,比如说在网易新闻缓存路径下看到的bitmap、object等文件夹。 接着是应用程序版本号,我们可以使用如下代码简单地获取到当前应用程序的版本号:
1
public int getAppVersion(Context context) {
2
    try {
3
        PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
4
        return info.versionCode;
5
    } catch (NameNotFoundException e) {
6
        e.printStackTrace();
7
    }
8
    return 1;
9
}
     需要注意的是,每当版本号改变,缓存路径下存储的所有数据都会被清除掉,因为DiskLruCache认为当应用程序有版本更新的时候,所有的数据都应该从网上重新获取。
后面两个参数就没什么需要解释的了,第三个参数传1,第四个参数通常传入10M的大小就够了,这个可以根据自身的情况进行调节。 因此,一个非常标准的open()方法就可以这样写:
1
DiskLruCache mDiskLruCache = null;
2
try {
3
    File cacheDir = getDiskCacheDir(context, "bitmap");
4
    if (!cacheDir.exists()) {
5
        cacheDir.mkdirs();
6
    }
7
    mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);
8
} catch (IOException e) {
9
    e.printStackTrace();
10
}
     首先调用getDiskCacheDir()方法获取到缓存地址的路径,然后判断一下该路径是否存在,如果不存在就创建一下。接着调用DiskLruCache的open()方法来创建实例,并把四个参数传入即可。
有了DiskLruCache的实例之后,我们就可以对缓存的数据进行操作了,操作类型主要包括写入、访问、移除等,我们一个个进行学习。
     写入缓存
     先来看写入,比如说现在有一张图片,地址是http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg,那么为了将这张图片下载下来,就可以这样写:
1
private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
2
    HttpURLConnection urlConnection = null;
3
    BufferedOutputStream out = null;
4
    BufferedInputStream in = null;
5
    try {
6
        final URL url = new URL(urlString);
7
        urlConnection = (HttpURLConnection) url.openConnection();
8
        in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
9
        out = new BufferedOutputStream(outputStream, 8 * 1024);
10
        int b;
11
        while ((b = in.read()) != -1) {
12
            out.write(b);
13
        }
14
        return true;
15
    } catch (final IOException e) {
16
        e.printStackTrace();
17
    } finally {
18
        if (urlConnection != null) {
19
            urlConnection.disconnect();
20
        }
21
        try {
22
            if (out != null) {
23
                out.close();
24
            }
25
            if (in != null) {
26
                in.close();
27
            }
28
        } catch (final IOException e) {
29
            e.printStackTrace();
30
        }
31
    }
32
    return false;
33
}
     这段代码相当基础,相信大家都看得懂,就是访问urlString中传入的网址,并通过outputStream写入到本地。有了这个方法之后,下面我们就可以使用DiskLruCache来进行写入了,写入的操作是借助DiskLruCache.Editor这个类完成的。类似地,这个类也是不能new的,需要调用DiskLruCache的edit()方法来获取实例,接口如下所示:
1
public Editor edit(String key) throws IOException
可以看到,edit()方法接收一个参数key,这个key将会成为缓存文件的文件名,并且必须要和图片的URL是一一对应的。那么怎样才能让key和图片的URL能够一一对应呢?直接使用URL来作为key?不太合适,因为图片URL中可能包含一些特殊字符,这些字符有可能在命名文件时是不合法的。其实最简单的做法就是将图片的URL进行MD5编码,编码后的字符串肯定是唯一的,并且只会包含0-F这样的字符,完全符合文件的命名规则。
那么我们就写一个方法用来将字符串进行MD5编码,代码如下所示:

1
public String hashKeyForDisk(String key) {
2
    String cacheKey;
3
    try {
4
        final MessageDigest mDigest = MessageDigest.getInstance("MD5");
5
        mDigest.update(key.getBytes());
6
        cacheKey = bytesToHexString(mDigest.digest());
7
    } catch (NoSuchAlgorithmException e) {
8
        cacheKey = String.valueOf(key.hashCode());
9
    }
10
    return cacheKey;
11
}
12

13
private String bytesToHexString(byte[] bytes) {
14
    StringBuilder sb = new StringBuilder();
15
    for (int i = 0; i < bytes.length; i++) {
16
        String hex = Integer.toHexString(0xFF & bytes[i]);
17
        if (hex.length() == 1) {
18
            sb.append('0');
19
        }
20
        sb.append(hex);
21
    }
22
    return sb.toString();
23
}
代码很简单,现在我们只需要调用一下hashKeyForDisk()方法,并把图片的URL传入到这个方法中,就可以得到对应的key了。
因此,现在就可以这样写来得到一个DiskLruCache.Editor的实例:

1
String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
2
String key = hashKeyForDisk(imageUrl);
3
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
有了DiskLruCache.Editor的实例之后,我们可以调用它的newOutputStream()方法来创建一个输出流,然后把它传入到downloadUrlToStream()中就能实现下载并写入缓存的功能了。注意newOutputStream()方法接收一个index参数,由于前面在设置valueCount的时候指定的是1,所以这里index传0就可以了。在写入操作执行完之后,我们还需要调用一下commit()方法进行提交才能使写入生效,调用abort()方法的话则表示放弃此次写入。
因此,一次完整写入操作的代码如下所示:

1
new Thread(new Runnable() {
2
    @Override
3
    public void run() {
4
        try {
5
            String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
6
            String key = hashKeyForDisk(imageUrl);
7
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
8
            if (editor != null) {
9
                OutputStream outputStream = editor.newOutputStream(0);
10
                if (downloadUrlToStream(imageUrl, outputStream)) {
11
                    editor.commit();
12
                } else {
13
                    editor.abort();
14
                }
15
            }
16
            mDiskLruCache.flush();
17
        } catch (IOException e) {
18
            e.printStackTrace();
19
        }
20
    }
21
}).start();
由于这里调用了downloadUrlToStream()方法来从网络上下载图片,所以一定要确保这段代码是在子线程当中执行的。注意在代码的最后我还调用了一下flush()方法,这个方法并不是每次写入都必须要调用的,但在这里却不可缺少,我会在后面说明它的作用。
现在的话缓存应该是已经成功写入了,我们进入到SD卡上的缓存目录里看一下,如下图所示:

     可以看到,这里有一个文件名很长的文件,和一个journal文件,那个文件名很长的文件自然就是缓存的图片了,因为是使用了MD5编码来进行命名的。

读取缓存
     缓存已经写入成功之后,接下来我们就该学习一下如何读取了。读取的方法要比写入简单一些,主要是借助DiskLruCache的get()方法实现的,接口如下所示:

1
public synchronized Snapshot get(String key) throws IOException
很明显,get()方法要求传入一个key来获取到相应的缓存数据,而这个key毫无疑问就是将图片URL进行MD5编码后的值了,因此读取缓存数据的代码就可以这样写:

1
String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
2
String key = hashKeyForDisk(imageUrl);
3
DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
     很奇怪的是,这里获取到的是一个DiskLruCache.Snapshot对象,这个对象我们该怎么利用呢?很简单,只需要调用它的getInputStream()方法就可以得到缓存文件的输入流了。同样地,getInputStream()方法也需要传一个index参数,这里传入0就好。有了文件的输入流之后,想要把缓存图片显示到界面上就轻而易举了。所以,一段完整的读取缓存,并将图片加载到界面上的代码如下所示:
1
try {
2
    String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
3
    String key = hashKeyForDisk(imageUrl);
4
    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
5
    if (snapShot != null) {
6
        InputStream is = snapShot.getInputStream(0);
7
        Bitmap bitmap = BitmapFactory.decodeStream(is);
8
        mImage.setImageBitmap(bitmap);
9
    }
10
} catch (IOException e) {
11
    e.printStackTrace();
12
}
     我们使用了BitmapFactory的decodeStream()方法将文件流解析成Bitmap对象,然后把它设置到ImageView当中。如果运行一下程序,将会看到如下效果:
OK,图片已经成功显示出来了。注意这是我们从本地缓存中加载的,而不是从网络上加载的,因此即使在你手机没有联网的情况下,这张图片仍然可以显示出来。
     移除缓存
     学习完了写入缓存和读取缓存的方法之后,最难的两个操作你就都已经掌握了,那么接下来要学习的移除缓存对你来说也一定非常轻松了。移除缓存主要是借助DiskLruCache的remove()方法实现的,接口如下所示:
1
public synchronized boolean remove(String key) throws IOException
相信你已经相当熟悉了,remove()方法中要求传入一个key,然后会删除这个key对应的缓存图片,示例代码如下:

1
try {
2
    String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";  
3
    String key = hashKeyForDisk(imageUrl);  
4
    mDiskLruCache.remove(key);
5
} catch (IOException e) {
6
    e.printStackTrace();
7
}
     用法虽然简单,但是你要知道,这个方法我们并不应该经常去调用它。因为你完全不需要担心缓存的数据过多从而占用SD卡太多空间的问题,DiskLruCache会根据我们在调用open()方法时设定的缓存最大值来自动删除多余的缓存。只有你确定某个key对应的缓存内容已经过期,需要从网络获取最新数据的时候才应该调用remove()方法来移除缓存。
    
     其它API
     除了写入缓存、读取缓存、移除缓存之外,DiskLruCache还提供了另外一些比较常用的API,我们简单学习一下。 1. size() 这个方法会返回当前缓存路径下所有缓存数据的总字节数,以byte为单位,如果应用程序中需要在界面上显示当前缓存数据的总大小,就可以通过调用这个方法计算出来。比如网易新闻中就有这样一个功能,如下图所示:
2.flush() 这个方法用于将内存中的操作记录同步到日志文件(也就是journal文件)当中。这个方法非常重要,因为DiskLruCache能够正常工作的前提就是要依赖于journal文件中的内容。前面在讲解写入缓存操作的时候我有调用过一次这个方法,但其实并不是每次写入缓存都要调用一次flush()方法的,频繁地调用并不会带来任何好处,只会额外增加同步journal文件的时间。比较标准的做法就是在Activity的onPause()方法中去调用一次flush()方法就可以了。 3.close() 这个方法用于将DiskLruCache关闭掉,是和open()方法对应的一个方法。关闭掉了之后就不能再调用DiskLruCache中任何操作缓存数据的方法,通常只应该在Activity的onDestroy()方法中去调用close()方法。
4.delete()

这个方法用于将所有的缓存数据全部删除,比如说网易新闻中的那个手动清理缓存功能,其实只需要调用一下DiskLruCache的delete()方法就可以实现了。

解读journal
前面已经提到过,DiskLruCache能够正常工作的前提就是要依赖于journal文件中的内容,因此,能够读懂journal文件对于我们理解DiskLruCache的工作原理有着非常重要的作用。那么journal文件中的内容到底是什么样的呢?我们来打开瞧一瞧吧,如下图所示:


由于现在只缓存了一张图片,所以journal中并没有几行日志,我们一行行进行分析。第一行是个固定的字符串“libcore.io.DiskLruCache”,标志着我们使用的是DiskLruCache技术。第二行是DiskLruCache的版本号,这个值是恒为1的。第三行是应用程序的版本号,我们在open()方法里传入的版本号是什么这里就会显示什么。第四行是valueCount,这个值也是在open()方法中传入的,通常情况下都为1。第五行是一个空行。前五行也被称为journal文件的头,这部分内容还是比较好理解的,但是接下来的部分就要稍微动点脑筋了。

第六行是以一个DIRTY前缀开始的,后面紧跟着缓存图片的key。通常我们看到DIRTY这个字样都不代表着什么好事情,意味着这是一条脏数据。没错,每当我们调用一次DiskLruCache的edit()方法时,都会向journal文件中写入一条DIRTY记录,表示我们正准备写入一条缓存数据,但不知结果如何。然后调用commit()方法表示写入缓存成功,这时会向journal中写入一条CLEAN记录,意味着这条“脏”数据被“洗干净了”,调用abort()方法表示写入缓存失败,这时会向journal中写入一条REMOVE记录。也就是说,每一行DIRTY的key,后面都应该有一行对应的CLEAN或者REMOVE的记录,否则这条数据就是“脏”的,会被自动删除掉。

如果你足够细心的话应该还会注意到,第七行的那条记录,除了CLEAN前缀和key之外,后面还有一个152313,这是什么意思呢?其实,DiskLruCache会在每一行CLEAN记录的最后加上该条缓存数据的大小,以字节为单位。152313也就是我们缓存的那张图片的字节数了,换算出来大概是148.74K,和缓存图片刚刚好一样大,如下图所示:


前面我们所学的size()方法可以获取到当前缓存路径下所有缓存数据的总字节数,其实它的工作原理就是把journal文件中所有CLEAN记录的字节数相加,求出的总合再把它返回而已。

除了DIRTY、CLEAN、REMOVE之外,还有一种前缀是READ的记录,这个就非常简单了,每当我们调用get()方法去读取一条缓存数据时,就会向journal文件中写入一条READ记录。因此,像网易新闻这种图片和数据量都非常大的程序,journal文件中就可能会有大量的READ记录。

那么你可能会担心了,如果我不停频繁操作的话,就会不断地向journal文件中写入数据,那这样journal文件岂不是会越来越大?这倒不必担心,DiskLruCache中使用了一个redundantOpCount变量来记录用户操作的次数,每执行一次写入、读取或移除缓存的操作,这个变量值都会加1,当变量值达到2000的时候就会触发重构journal的事件,这时会自动把journal中一些多余的、不必要的记录全部清除掉,保证journal文件的大小始终保持在一个合理的范围内。

好了,这样的话我们就算是把DiskLruCache的用法以及简要的工作原理分析完了。至于DiskLruCache的源码还是比较简单的, 限于篇幅原因就不在这里展开了,感兴趣的朋友可以自己去摸索。下一篇文章中,我会带着大家通过一个项目实战的方式来更加深入地理解DiskLruCache的用法。感兴趣的朋友请继续阅读 Android照片墙完整版,完美结合LruCache和DiskLruCache 。

 

转自  http://www.mobile-open.com/2014/3104.html

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Java GC的工作原理详解

$
0
0

JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆、栈、本地方法栈、方法区等部分组成,另外JVM分别对新生代和旧生代采用不同的垃圾回收机制。

首先来看一下JVM内存结构,它是由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示。

JVM学习笔记 JVM内存管理和JVM垃圾回收

JVM内存组成结构

JVM内存结构由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示:

 

JVM内存组成结构

 

1)堆

所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成,结构图如下所示:

 

JVM内存结构之堆

 

新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象

2)栈

每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果

3)本地方法栈

用于支持native方法的执行,存储了每个native方法调用的状态

4)方法区

存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(PermanetGeneration)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。介绍完了JVM内存组成结构,下面我们再来看一下JVM垃圾回收机制。

JVM垃圾回收机制

JVM分别对新生代和旧生代采用不同的垃圾回收机制

新生代的GC:

新生代通常存活时间较短,因此基于Copying算法来进行回收,所谓Copying算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和FromSpace或ToSpace之间copy。新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到survivor,最后到旧生代,

用javavisualVM来查看,能明显观察到新生代满了后,会把对象转移到旧生代,然后清空继续装载,当旧生代也满了后,就会报outofmemory的异常,如下图所示:

 

outofmemory的异常

 

在执行机制上JVM提供了串行GC(SerialGC)、并行回收GC(ParallelScavenge)和并行GC(ParNew)

1)串行GC

在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定

2)并行回收GC

在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数

3)并行GC

与旧生代的并发GC配合使用

旧生代的GC:

旧生代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行GC(SerialMSC)、并行GC(parallelMSC)和并发GC(CMS),具体算法细节还有待进一步深入研究。

以上各种GC机制是需要组合使用的,指定方式由下表所示:

 

GC机制组合使用



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



当 40% 的工作都由自由职业者完成时,你还能保住饭碗吗?

$
0
0

在接下来的 4 年中,美国将有 40% 的工作由那些不限于服务一家企业的自由工作者完成,他们不必拘泥于上下班时间,想什么时候干活就什么时候干活。

在不久的将来,多达 700 万美国人将有机会自由选择工作地点,舒适的家中、附近的小咖啡馆或者是充满异国情调的沙滩上都能够成为他们的办公场所。是什么导致了在职场中发生这一戏剧性的变化?这对未来将有什么影响呢?

自由职业者的崛起

优秀的人才总是很难被寻觅到,比这更难的就是让他们长久的待在企业中,但是新的工作形式将为企业发掘人才与任用人才打开新的思路。平均每 4 年人们就会换一家公司工作,如今的公司不再需要为员工提供终身制就业保障,自由职业者已经成为了公司快速且可靠的人才来源。

「人们的工作方式已经翻开了新的一页,相比工业时代,如今技术的发展使得人们能够更快且更容易找到工作,因此人们可以更多地考虑如何平衡工作与生活。」Upwork 公司 CEO Stephane Kasriel 解释了自由职业的兴起。

曾经对于自由职业者来说,如何确保手头有足够的项目的可做是最大的障碍,但是现在这一担忧已经烟消云散。如今的自由职业者想要找到可做的项目并不费力,有不少公司会经常在类似 Upwork 与 Freelancer 这样的网站上发布兼职职位。

自由职业者的工作时间与工作地点完全可以随心而定,他们自己给自己标价,他们能够同时服务多个企业,而不是被一个雇主给束缚住。

但是随着自由职业者逐渐增长为职场新趋势,这也影响了职场中人的职业发展,而如何与自由职业者配合工作也成为了必须面对的问题。

自由职业者对未来职场意味着什么?

更多的集中式办公场地

在未来的城市中心将会出现更多的集中式办公场地,它们不仅仅能为那些独自一人的自由工作者提供更多的与人交流的机会,还能为他们提供办公支持,并且为其带去一些工作资源。WeWork 就是其中受人瞩目的一家提供集中式办公场所的公司,该公司最近融资了 4.3 亿美元,其估值已经达到了 160 亿美元,它在全球 80 个国家与地区建有集中式办公场地。WeWork 称其为自由职业者们提供了充满活力的社区,在办公场地里不仅有精心的建筑设计,还提供新鲜水果与啤酒。

价值数十亿美元的公司不再聘用全职员工

这种说法可能略显夸张,但是有不少公司确实已经不需要像现在一样维持一个庞大的工作团队,为了招人与留人费尽心思。他们可以在特定的项目中雇佣合适的自由职业者兼职完成,而不是让那些领着工资与福利的全职员工去完成这些任务。现在在不少创业企业中有几乎一半的员工都是远程工作,而这也逐渐成为了常态。这对企业如何协同工作,如何找到合适的兼职员工以及如何维持企业文化都提出了挑战。

出现传统教育的替代品

专科学校、技能培训营以及在线课程将会变得越来越有价值。想要成为一个成功的自由职业者,你需要拥有一些符合用户需求且高度专业化的技能,比如说网站后端开发,封面设计以及法律咨询。专门面向自由职业者的网站如 Upwork 将会向你展示有哪些雇主正在招人,他们愿意支付多少酬劳,这些工作机会并不需要你有大学学历才能去争取。

随着工作自由化程度越来越高,自由职业者可能也会在其中失去一些归属感,而企业也会面临着失去员工忠诚度的风险。但是在当今世界中工作形式是不断在进化的,自由职业与远程工作的兴起将会深刻地影响企业的招聘工作,也会改变我们与他人合作的方式。雇佣自由职业者对于企业和工作者本身来说都是双赢的,我们应该积极地去适应并接受这一变化。

文章来源: the HUSTLE,TECH2IPO / 创见 陈铮 编译,首发于创见科技(http://tech2ipo.com/),转载请注明出处

面试感悟:3年工作经验程序员应有的技能

$
0
0

原文地址http://www.cnblogs.com/xrq730/p/5260294.html,转载请注明出处,谢谢!

 

前言

因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章。这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Java程序员的。

简单先说一下,LZ坐标杭州,13届本科毕业,算上年前在阿里巴巴B2B事业部的面试,一共有面试了有6家公司(因为LZ不想请假,因此只是每个晚上去其他公司面试,所以面试的公司比较少),其中成功的有4家,另外两家失败的原因在于:

1、阿里巴巴B2B事业部的面试,两轮技术面试都过了,最后一轮面试是对方的主管,由于听说技术面试过了基本上90%都面试成功了,所以LZ在和主管的交谈中也是毫无顾忌,说得天花乱坠,很多自己介于知道和不知道的东西都直接脱口而出了,结果多次被对方一反问就问得哑口无言。事后想来,模棱两可的答案是面试中最忌讳的,这次的失败也让LZ认真地对待后面的每一次面试

2、另外一家失败的是一家小公司,也就20来个人吧,整个团队是支付宝出来创业的,非常厉害。面试完LZ多方了解了一下,对方认为我基本功什么的都不错,但是实际项目经验还是欠缺一些,因为对方是创业型公司,需要人上手就能干活,因此我在这个时候还不是特别适合他们团队

至于其他成功的四家公司,给LZ的面试评价都挺高的貌似,但LZ也不想记流水账,因此就不一一列举每家公司的面试过程了,下面LZ主要谈谈作为一名工作三年左右的Java程序员应该具备的一些技能以及个人的一些其他感悟。

 

关于程序员的几个阶段

每个程序员、或者说每个工作者都应该有自己的职业规划,如果看到这里的朋友没有自己的职业规划,希望你可以思考一下自己的将来。

LZ常常思考自己的未来,也从自己的思考中总结出了一些东西,作为第一部分来谈谈。LZ认为一名程序员应该有几个阶段(以下时间都算上实习期):

  • 第一阶段----三年
    • 我认为三年对于程序员来说是第一个门槛,这个阶段将会淘汰掉一批不适合写代码的人。这一阶段,我们走出校园,迈入社会,成为一名程序员,正式从书本上的内容迈向真正的企业级开发。我们知道如何团队协作、如何使用项目管理工具、项目版本如何控制、我们写的代码如何测试如何在线上运行等等,积累了一定的开发经验,也对代码有了一定深入的认识,是一个比较纯粹的Coder的阶段
  • 第二阶段----五年
    • 五年又是区分程序员的第二个门槛。有些人在三年里,除了完成工作,在空余时间基本不会研究别的东西,这些人永远就是个Coder,年纪大一些势必被更年轻的人给顶替;有些人在三年里,除了写代码之外,还热衷于研究各种技术实现细节、看了N多好书、写一些博客、在Github上分享技术,这些人在五年后必然具备在技术上独当一面的能力并且清楚自己未来的发展方向,从一个Coder逐步走向系统分析师或是架构师,成为项目组中不可或缺的人物
  • 第三阶段----十年
    • 十年又是另一个门槛了,转行或是继续做一名程序员就在这个节点上。如果在前几年就抱定不转行的思路并且为之努力的话,那么在十年的这个节点上,有些人必然成长为一名对行业有着深入认识、对技术有着深入认识、能从零开始对一个产品进行分析的程序员,这样的人在公司基本担任的都是CTO、技术专家、首席架构师等最关键的职位,这对于自己绝对是一件荣耀的事,当然老板在经济上也绝不会亏待你

第一部分总结一下,我认为,随着你工作年限的增长、对生活对生命认识的深入,应当不断思考三个问题:

1、我到底适不适合当一名程序员?

2、我到底应不应该一辈子以程序员为职业?

3、我对编程到底持有的是一种什么样的态度,是够用就好呢还是不断研究?

最终,明确自己的职业规划,对自己的规划负责并为之努力。

 

关于项目经验

LZ在网上经常看到一些别的朋友有提出项目经验的问题,依照LZ面试的感觉来说,面试主要看几点: 项目经验+基本技术+个人潜力(也就是值不值得培养)。

关于项目经验,我认为并发编程网的创始人方腾飞老师讲的一段话非常好:

介绍产品时面试官会考察应聘者的沟通能力和思考能力,我们大部分情况都是做产品的一个功能或一个模块,但是即使是这样,自己有没有把整个系统架构或产品搞清楚,并能介绍清楚,为什么做这个系统?这个系统的价值是什么?这个系统有哪些功能?优缺点有哪些?如果让你重新设计这个系统你会如何设计?

我觉得这就已经足以概括了。也许你仅仅工作一年,也许你做的是项目中微不足道的模块,当然这些一定是你的劣势且无法改变,但是如何弥补这个劣势,从方老师的话中我总结几点:

1、明确你的项目到底是做什么的,有哪些功能

2、明确你的项目的整体架构,在面试的时候能够清楚地画给面试官看并且清楚地指出从哪里调用到哪里、使用什么方式调用

3、明确你的模块在整个项目中所处的位置及作用

4、明确你的模块用到了哪些技术,更好一些的可以再了解一下整个项目用到了哪些技术

在你无法改变自己的工作年限、自己的不那么有说服力的项目经验的情况下(这一定是扣分项),可以通过这种方式来一定程度上地弥补并且增进面试官对你的好感度。

补充一点,在面试中聊你的项目的时候,有一个问题90%是绕不过的: 谈一下你在项目中解决过的比较复杂的问题。这需要在工作中不断去发现和探索,不需要多,在你自己目前的项目中只要你找到一两个能说的问题就行。一个小技巧是,即使问题不是你解决的而是别人解决的,但是你把这个问题弄懂、搞透了,在面试的时候你一样可以把这个问题当作是你自己解决的来说----毕竟,谁来管这个问题当时到底是不是你解决的呢?

 

关于专业技能

写完项目接着写写一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西----但是如果你掌握得越多,最终能得到的评价、拿到的薪水势必也越高。

1、基本语法

这包括static、final、transient等关键字的作用,foreach循环的原理等等。今天面试我问你static关键字有哪些作用,如果你答出static修饰变量、修饰方法我会认为你合格,答出静态块,我会认为你不错,答出静态内部类我会认为你很好,答出静态导包我会对你很满意,因为能看出你非常热衷研究技术。

最深入的一次,LZ记得面试官直接问到了我volatile关键字的底层实现原理(顺便插一句,面试和被面试本身就是相对的,面试官能问这个问题同时也让面试者感觉到面试官也是一个喜爱研究技术的人,增加了面试者对公司的好感,LZ最终选择的就是问了这个问题的公司),不要觉得这太吹毛求疵了----越简单的问题越能看出一个人的水平,别人对你技术的考量绝大多数都是以 深度优先、广度次之为标准的,切记。

2、集合

非常重要,也是必问的内容。基本上就是List、Map、Set,问的是各种实现类的底层实现原理,实现类的优缺点。

集合要掌握的是ArrayList、LinkedList、Hashtable、HashMap、ConcurrentHashMap、HashSet的实现原理,能流利作答,当然能掌握CopyOnWrite容器和Queue是再好不过的了。另外多说一句,ConcurrentHashMap的问题在面试中问得特别多,大概是因为这个类可以衍生出非常多的问题,关于ConcurrentHashMap,我给网友朋友们提供三点回答或者是研究方向:

(1)ConcurrentHashMap的锁分段技术

(2)ConcurrentHashMap的读是否要加锁,为什么

(3)ConcurrentHashMap的迭代器是强一致性的迭代器还是弱一致性的迭代器

3、设计模式

本来以为蛮重要的一块内容,结果只在阿里巴巴B2B事业部面试的时候被问了一次,当时问的是装饰器模式。

当然咱们不能这么功利,为了面试而学习,设计模式在工作中还是非常重要、非常有用的,23种设计模式中重点研究常用的十来种就可以了,面试中关于设计模式的问答主要是三个方向:

(1)你的项目中用到了哪些设计模式,如何使用

(2)知道常用设计模式的优缺点

(3)能画出常用设计模式的UML图

4、多线程

这也是必问的一块了。因为三年工作经验,所以基本上不会再问你怎么实现多线程了,会问得深入一些比如说Thread和Runnable的区别和联系、多次start一个线程会怎么样、线程有哪些状态。当然这只是最基本的,出乎意料地,几次面试几乎都被同时问到了一个问题,问法不尽相同,总结起来是这么一个意思:

假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

聪明的网友们对这个问题是否有答案呢?不难,java.util.concurrent下就有现成的类可以使用。

另外,线程池也是比较常问的一块,常用的线程池有几种?这几种线程池之间有什么区别和联系?线程池的实现原理是怎么样的?实际一些的,会给你一些具体的场景,让你回答这种场景该使用什么样的线程池比较合适。

最后,虽然这次面试问得不多,但是多线程同步、锁这块也是重点。synchronized和ReentrantLock的区别、synchronized锁普通方法和锁静态方法、死锁的原理及排查方法等等,关于多线程,我在之前有些过文章总结过多线程的40个问题,可以参看 40个Java多线程问题总结

5、IO

再次补充IO的内容,之前忘了写了。

IO分为File IO和Socket IO,File IO基本上是不会问的,问也问不出什么来,平时会用就好了,另外记得File IO都是阻塞IO。

Socket IO是比较重要的一块,要搞懂的是阻塞/非阻塞的区别、同步/异步的区别,借此理解阻塞IO、非阻塞IO、多路复用IO、异步IO这四种IO模型,Socket IO如何和这四种模型相关联。这是基本一些的,深入一些的话,就会问NIO的原理、NIO属于哪种IO模型、NIO的三大组成等等,这有些难,当时我也是研究了很久才搞懂NIO。提一句, NIO并不是严格意义上的非阻塞IO而应该属于多路复用IO,面试回答的时候要注意这个细节,讲到NIO会阻塞在Selector的select方法上会增加面试官对你的好感。

如果用过Netty,可能会问一些Netty的东西,毕竟这个框架基本属于当前最好的NIO框架了(Mina其实也不错,不过总体来说还是比不上Netty的),大多数互联网公司也都在用Netty。

6、JDK源码

要想拿高工资,JDK源码不可不读。上面的内容可能还和具体场景联系起来,JDK源码就是实打实地看你平时是不是爱钻研了。LZ面试过程中被问了不少JDK源码的问题,其中最刁钻的一个问了LZ,String的hashCode()方法是怎么实现的,幸好LZ平时String源代码看得多,答了个大概。JDK源码其实没什么好总结的,纯粹看个人,总结一下比较重要的源码:

(1)List、Map、Set实现类的源代码

(2)ReentrantLock、AQS的源代码

(3)AtomicInteger的实现原理,主要能说清楚CAS机制并且AtomicInteger是如何利用CAS机制实现的

(4)线程池的实现原理

(5)Object类中的方法以及每个方法的作用

这些其实要求蛮高的,LZ去年一整年基本把JDK中重要类的源代码研究了个遍,真的花费时间、花费精力,当然回头看,是值得的----不仅仅是为了应付面试。

7、框架

老生常谈,面试必问的东西。一般来说会问你一下你们项目中使用的框架,然后给你一些场景问你用框架怎么做,比如我想要在Spring初始化bean的时候做一些事情该怎么做、想要在bean销毁的时候做一些事情该怎么做、MyBatis中$和#的区别等等,这些都比较实际了,平时积累得好、有多学习框架的使用细节自然都不成问题。

如果上面你的问题答得好,面试官往往会深入地问一些框架的实现原理。问得最多的就是Spring AOP的实现原理,当然这个很简单啦,两句话就搞定的的事儿,即使你不会准备一下就好了。LZ遇到的最变态的是让LZ画一下Spring的Bean工厂实现的UML图,当然面对这样一个有深度的问题,LZ是绝对答不出来的/(ㄒoㄒ)/~~

8、数据库

数据库十有八九也都会问到。一些基本的像union和union all的区别、left join、几种索引及其区别就不谈了,比较重要的就是数据库性能的优化,如果对于数据库的性能优化一窍不通,那么有时间,还是建议你在面试前花一两天专门把SQL基础和SQL优化的内容准备一下。

不过数据库倒是不用担心,一家公司往往有很多部门,如果你对数据库不熟悉而基本技术又非常好,九成都是会要你的,估计会先把你放到对数据库使用不是要求非常高的部门锻炼一下。

9、数据结构和算法分析

数据结构和算法分析,对于一名程序员来说,会比不会好而且在工作中绝对能派上用场。数组、链表是基础,栈和队列深入一些但也不难,树挺重要的,比较重要的树AVL树、红黑树,可以不了解它们的具体实现,但是要知道什么是二叉查找树、什么是平衡树,AVL树和红黑树的区别。记得某次面试,某个面试官和我聊到了数据库的索引,他问我:

你知道索引使用的是哪种数据结构实现吗?

LZ答到用的Hash表吧,答错。他又问,你知道为什么要使用树吗?LZ答到因为Hash表可能会出现比较多的冲突,在千万甚至是上亿级别的数据面前,会大大增加查找的时间复杂度。而树比较稳定,基本保证最多二三十次就能找到想要的数据,对方说不完全对,最后我们还是交流了一下这个问题,我也明白了为什么要使用树,这里不说,网友朋友们觉得索引为什么要使用树来实现呢?

至于算法分析,不会、不想研究就算了,记得某次面试对方问我,Collections.sort方法使用的是哪种排序方法,额,吐血三升。当然为了显示LZ的博学,对算法分析也有一定的研究(⊙﹏⊙)b,LZ还是硬着头皮说了一句可能是冒泡排序吧。当然答案肯定不是,有兴趣的网友朋友们可以去看一下Collections.sort方法的源代码,用的是一种叫做TimSort的排序法,也就是增强型的归并排序法。

10、Java虚拟机

出乎LZ的意料,Java虚拟机应该是很重要的一块内容,结果在这几家公司中被问到的概率几乎为0。要知道,LZ去年可是花了大量的时间去研究Java虚拟机的,光周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》,LZ就读了不下五遍。

言归正传,虽然Java虚拟机没问到,但我觉得还是有必要研究的,LZ就简单地列一个提纲吧,谈谈Java虚拟机中比较重要的内容:

(1)Java虚拟机的内存布局

(2)GC算法及几种垃圾收集器

(3)类加载机制,也就是双亲委派模型

(4)Java内存模型

(5)happens-before规则

(6)volatile关键字使用规则

也许面试无用,但在走向大牛的路上,不可不会。

11、Web方面的一些问题

Java主要面向Web端,因此Web的一些问题也是必问的。LZ碰到过问得最多的两个问题是:

谈谈分布式Session的几种实现方式

常用的四种能答出来自然是让面试官非常满意的,另外一个常问的问题是:

讲一下Session和Cookie的区别和联系以及Session的实现原理

这两个问题之外,web.xml里面的内容是重点,Filter、Servlet、Listener,不说对它们的实现原理一清二楚吧,至少能对它们的使用知根知底。另外,一些细节的方面比如get/post的区别、forward/重定向的区别、HTTPS的实现原理也都可能会被考察到。

噢,想起来了,一致性Hash算法貌似也被问到了几次,这个LZ以前专门深入研究过并且写了两篇博文,因此问到这个问题LZ自然是答得毫不费力。文章是 MemCache超详细解读和对 一致性Hash算法,Java代码实现的深入研究,特别说明,LZ真的不是在为自已以前写的文章打广告啊啊啊啊啊啊。

最后,如果有兴趣有时间,建议学习、研究一下SOA和RPC,面向服务体系,大型分布式架构必备,救命良方、包治百病、屡试不爽。

 

关于HR面试

如果你过五关斩六将,成功地通过了所有的技术面,那么恭喜你,你离升职加薪、出任CEO、迎娶白富美、走向人生巅峰又进了一步。但是还没有到谈薪资待遇的时候,最后还有一个考验:HR面试。基本所有的大公司都有这一轮的面试,不要小看HR面试,很多公司的HR对于面试者都有一票否决权的----即使前面的面试对你的评价再高。

所以,这轮的面试也必须重视起来,HR面试主要问的是几点:

1、简历中写的过去工作经历的离职原因

2、当前公司薪资待遇

3、期望能到怎样的一家公司

4、个人未来的发展方向

我专门提一下第2点。可能有人比较排斥也不想说这个,我个人倒是持开放状态,问了就说了,当然一些的夸大还是必要的,当前公司薪资待遇多报个一千块钱完全没问题(毕竟是一家互联网公司总多多少少有些补贴啊什么的嘛)。因为这和你在新公司能拿到的薪水关系不大,新公司能拿到的薪水的决定因素是整个公司的薪资情况以及根据你的面试情况在公司的定位,都是有固定的薪资范围的。HR问这个主要也就是心里有个数并且看你是否诚信----有些公司入职时会要求你提供最近一家单位的银行流水号。

HR面试就说到这里了,总结起来其实就是四个字: 滴水不漏。整个面试过程态度积极向上,不要有任何悲观消极的态度(尤其在谈到以前公司情况的时候,即使有再多的不满),就不会有问题。

 

关于面试心态

这个嘛,LZ其实在公司也面试过几个人,一半以上的面试者回答问题的时候都属于那种双腿发抖、声音颤抖的类型。在LZ看来这大可不必并且这还是扣分项,回答问题的时候最最基本的两个要求:

1、不紧不慢,平心静气

2、条理清晰

表达能力绝对是面试的时候重要的考察项目。咱们做的是程序员这一行,讲究的是团队协作,不是写作、画画,一支笔、一个人就行了,一个表达能力不行的程序员,要来又有什么用呢?

除此之外,就是保持良好的心态。古语说得好,只要功夫深,铁杵磨成针,面试的成功与否,在于平时的积累,临时抱抱佛脚,看两道面试题是没有用的,只要平时足够努力,成功是水到渠成的事情,平时不怎么研究技术的,那也就是个听天由命的事情,只要充分地展示平时自己的所学就可以了。

因此在我看来,不要把面试当作面试,当做一次技术交流,把 面试的心态从我要找到一份工作转变为我要通过面试去发现不足、提升自己,这样就会平和多了,即使失败也不会有太多失望的感觉。

另外,如果平时自己热衷于研究技术的朋友,真的要有自信,不要觉得别人面试你别人就比你厉害。面试官未必比你优秀,他问的问题往往都是他平时研究得比较多的问题,你一样有很多自己的研究面试官未必知道。

 

关于Java

网上常看到一种说法:Java比较简单。某种程度上这会打击Java程序员的信心----原来咱们平时用的是这种小儿科的玩意儿啊,在我看来这种想法大可不必,这一部分我来讲讲对于这个话题的看法。

这种说法有些片面,得分开两部分来看,我用四个自总结一下就是: 易学难精

1、易学部分

Java易学我认为有两部分的原因:

(1)很多培训公司包括大四的学生找工作都会学习Java,绝大多数是因为易学。Java从C/C++发展而来,感谢前人的智慧,它消除了C/C++中最复杂和让人困惑的语法、它消除了平台的差异性、它不需要用户手动释放内存空间、它避免了Java程序员和本地语言的交互,让程序员只需要专注于语法层面和应用层面。

(2)Java作为一门面向对象的语言,在企业级开发中体现出了它无与伦比的特性,整个开发流程比较固定化、模块化,需求分析起来也相对容易。我举个自己以前的例子吧,我在大一学习C语言的时候,用C语言写了一个图书管理系统写了2000行+的代码,大四学了C++之后,用面向对象的语言C++取代面向过程的语言C语言重新写了一个功能相似的图书管理系统,只写了1100行的样子,这就是面向对象的优势。

2、难精部分

接着咱们聊聊难精的部分。

Java语言的设计者帮助Java程序员做了这么多事情,这有利也有弊。有利的部分前面已经说过了,让Java易学,不过有弊的部分同样明显。假如在应用运行过程中遇到了语法层面和应用层面之外的错误,应当如何处理?比如线上环境出现内存溢出怎么办?GC时间过长怎么办?IO长时间没反应怎么办?方法抛出莫名其妙的异常怎么办?

凡此种种,绝不是一名只会写几个if...else...的Java程序员就可以解决的,这需要大量的经历、大量的实践、大量对Java底层实现细节的研究,而这往往是最难、最考验Java程序员的部分,一些人根本就不想往深去研究,另外一些人研究了一点点就研究不下去了。

Java为什么难精?就是这个原因。除非你水平特别高,否则五年工作经验以下的Java程序员在简历上写"精通Java"绝对是一件非常愚蠢的事情。

 

结语

文章写到这里,感觉有点像鸡汤文了,那就以最后的鸡汤作为结尾吧。

在以前博客园的一篇文章中,讲到了奔三程序员的困惑,大致说的是三十岁之后程序员要转行之类的云云,LZ在博文中留下了如下的评论:

就以这段话自勉、共勉吧。越努力、越幸运,如果你不是官二代、富二代、红二代,那么请记住: 勤奋才是改变你命运的唯一捷径

 

================================================================================== 

我不能保证写的每个地方都是对的,但是至少能保证不复制、不黏贴,保证每一句话、每一行代码都经过了认真的推敲、仔细的斟酌。每一篇文章的背后,希望都能看到自己对于技术、对于生活的态度。

我相信乔布斯说的,只有那些疯狂到认为自己可以改变世界的人才能真正地改变世界。面对压力,我可以挑灯夜战、不眠不休;面对困难,我愿意迎难而上、永不退缩。

其实我想说的是,我只是一个程序员,这就是我现在纯粹人生的全部。

==================================================================================


已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



[原]技术架构组工作职责

$
0
0
  1. 技术架构组工作目标

    • 落地本部门的技术规划,负责本部门IT整体规划技术部分,指导重要项目的设计实现
    • 规范本部门的所有技术应用和开发内容,保障系统开发的有序、标准、一致性
    • 发展基础技术平台和完善通用组件,实现部门技术积累和IT资源高效复用
    • 解决各项目的技术难点、框架选型,保障项目开发的速度、效率、质量
    • 协助运维、安全和测试组的部分技术性工作,保障各组工作的顺利开展和技术积累
    • 组织技术学习培训,引入代码质量统计工具,提升开发人员技术水平、扩大知识面
  2. 技术架构组工作目标

    • 制定部门技术规划
      – 部门技术规划:技术规划文档、技术发展线路文档
      – 重大技术决策:协助技术委员会的规划和决策落地
    • 制定部门技术规范
      – 整体技术规范:整体技术规范、设计规范、调研规范、部署规范、开发规范、数据库规范
      – 接口技术规范:接口规范、报文规范、通讯规范
    • 发展基础技术平台
      – 技术框架组件整合:框架整合demo、组件代码、组件文档
      – 基础技术平台开发:基础技术平台代码、平台文档
    • 解决项目技术难点
      – 技术框架选型:技术选型报告、技术应用demo
      – 项目设计实现支持:支持重点项目的关键实现,产出设计文档
      – 技术难点攻坚:关键代码、总结报告
    • 提高人员技术水平
      – 协调项目代码质量:度量工具软件、度量标准文档
      – 组织技术学习培训:培训计划、培训课件、培训反馈
    • 协助运维测试人员
      – 性能测试与自动化测试:性能测试脚本和场景评审、分析调优,自动化测试技术支持
      – 持续集成和自动化运维:持续集成、自动化运维技术支持、其他运维相关脚本支持
      – 数据库与部署技术支持:评审数据库方案、部署方案,上线部署的技术支持
      – 版本管理工具统一控制:源码和文档的统一管理、权限统一控制
    • 前端技术统筹管理
      – 前端技术选型和维护:确定网站前端、业管前端、移动前端的
      前端问题解决与积累:培训计划、培训课件、培训反馈
  3. 技术架构组研发资源配置

    • 整体技术框架和规范
    • 支持具体的框架整合、工作流技术调研、MQ技术调研,定时任务和消息中心
    • 技术培训、技术交流、技术岗位入职培训
    • 支持技术规范制定、框架整合、基础技术平台的开发,
    • 整合分布式服务框架,数据中间层等
    • 支持各项目的技术问题和研发过程,完善技术框架、推广新技术
    • 前端与移动技术规范、基础框架和组件维护、各项目技术支持
    • 运维与安全部分工作
    • 自动化测试、前后端性能测试、持续集成相关工作
    • 移动框架的技术平台设计实现工作
    • 数据库规范与配置相关工作
    • 支付网关与接口部分工作
  4. 技术架构组近期工作计划

    • 搭建分布式服务的开发环境:配合三套环境、完善基础设施和培训用法
    • 制定部门各种技术相关规范:整体技术规范、设计规范、调研规范、部署规范、开发规范、数据库规范
    • 完成工作流整合demo代码:工作流整合demo代码、设计文档、整合文档
    • 完善接口规范、评审各接口:评审会议、接口文档
    • 制定整体架构设计V0.1版本:架构设计文档、整体部署文档(方天英配合)
    • 实现基础技术平台V0.2版本:框架整合demo、基础组件demo
    • 完善数据库架构和管理规范:架构设计文档、整体部署文档、管理规范文档(张洋配合)
    • 搭建持续集成以及度量工具:度量工具软件、度量标准文档(协助QA组)
    • 完善整体架构设计V0.2版本:架构设计文档、整体部署文档(方天英配合)
    • 组织部门技术培训课程计划:培训范围、培训方式、确定培训讲师资源
    • 解决各个项目研发技术难点:支撑门户和业管项目的技术选型和疑难问题解决,出选型报告和总结报告
    • 维护发展部门基础技术平台:收集项目对平台的需求文档、完善和重构功能代码,抽象组件代码,完善设计文档
    • 提升部门开发人员技术水平:培训计划表、培训文档(需各组核心研发配合、外部资源)
作者:KimmKing 发表于2016/3/14 0:01:14 原文链接
阅读:1803 评论:0 查看评论

提高ActiveMQ工作性能

$
0
0

(接上文《 架构设计:系统间通信(22)——提高ActiveMQ工作性能(上)》)

6、ActiveMQ处理规则和优化

在ActiveMQ单个服务节点的优化中,除了对ActiveMQ单个服务节点的网络IO模型进行优化外,生产者发送消息的策略和消费者处理消息的策略也关乎整个消息队列系统是否能够高效工作。请看下图所示的消息生产者和消息消费者的简要工作原理图:

这里写图片描述

  1. Producer既是消息生产者,作为一个发送消息的客户端它既可以使用同步消息发送模式,也可以使用异步的消息发送模式。另外, 消息生产者在ActiveMQ服务节点产生消息堆积的情况下,也不能一味的追求发送效率。还好,这种情况下消息生产者端有完整的保证机制——Slow Producer。另外,JMS提供事务功能,所以生产者是否开启事务发送消息,将会影响消息发送性能。

  2. 在整个消息处理规则中,ActiveMQ服务节点最极端的情况就是产生消息堆积(消息的消费速度持续低于消息生成速度,就会出现消息堆积)。那么ActiveMQ服务节点处理网络IO模型的优化外,最大的优化点就是: 如何应对消息堆积。基本原则是: NON_PERSISTENT Message在内存堆积后,转储到Temp Store区域(当然也可以设置为不转储);PERSISTENT Meaage无论怎样都会先使用持久化方案存储到永久存储区域,再视情况决定是否进行发送;在这些区域也产生堆积后,通知消息生产者使用Slow Producer机制

  3. ActiveMQ服务节点在成功完成PERSISTENT Meaage的持久存储操作后,就会向消息生产者发送一个确认信息,表示该条消息已处理完成。 如果ActiveMQ服务节点接受的是NON_PERSISTENT Message,那么生产者默认情况下不会等待服务节点的回执。我们后续会介绍PERSISTENT Meaage的发送也可以设置为不等待回执,这样可以显著提高生产端的消息发送效率。

  4. ActiveMQ服务节点会以一种设置好的策略将消息发送给消费者,这个策略的原则是 ActiveMQ服务节点主动推送消息给某一个消费者(不是消费者主动拉取),这样的方式很好便于ActiveMQ服务节点占据整个策略的领导地位。在这个策略中, 最重要的属性是prefetchSize:单次获得的消息数量。除此以外,消费者端也是可以调整IO网络模型。

  5. 消费者在获得到消息后,就可以根据这条消息进行业务处理了。最后,消费者需要按照处理结果向ActiveMQ服务节点告知这条(或这些)消息是否处理成功——ACK应答。ActiveMQ中有多种ACK应答方式,它们对性能的影响也不相同。通过这些描述可以看出, 消费者的处理性能更能直接影响整个ActiveMQ系统的性能。因为消费者不仅要接受消息、处理消息还要返回消息应答。 所以如果您的业务有一定的复杂性,造成每一条消息的处理都会消耗相当的处理时间,那么最直接的性能改善方式就是采用多个消费者节点

6-1、生产者策略:Send

消息生产者发送的消息主要分为两种类型:发送PERSISTENT Meaage和发送NON_PERSISTENT Message。

6-1-1、发送NON_PERSISTENT Message

默认情况下,ActiveMQ服务端认为生产者端发送的是PERSISTENT Message。 所以如果要发送NON_PERSISTENT Message,那么生产者端就要明确指定。以下语句明确指定消息发送者将要发送NON_PERSISTENT Message:

......
// 设置发送者发送的是NON_PERSISTENT Message
MessageProducer sender = session.createProducer(sendQueue);
sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
......
  • 1
  • 2
  • 3
  • 4
  • 5

发送NON_PERSISTENT Message时,消息发送方默认使用异步方式:即是说消息发送后发送方不会等待NON_PERSISTENT Message在服务端的任何回执。那么问题来了:如果这时服务端已经出现了消息堆积,并且堆积程度已经达到“无法再接收新消息”的极限情况了,那么消息发送方如果知晓并采取相应的策略呢?

实际上所谓的异步发送也并非绝对的异步,消息发送者会在发送一定大小的消息后等待服务端进行回执(这个配置只是针对使用异步方式进行发送消息的情况):

......
// 以下语句设置消息发送者在累计发送102400byte大小的消息后(可能是一条消息也可能是多条消息)
// 等待服务端进行回执,以便确定之前发送的消息是否被正确处理
// 确定服务器端是否产生了过量的消息堆积,需要减慢消息生产端的生产速度
connectionFactory.setProducerWindowSize(102400);
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果您使用的是异步发送方式,那么必须通过这个以上代码指明回执点。例如发送NON_PERSISTENT Message时,这时消息发送者默认使用异步方式。那么如果您想在发送NON_PERSISTENT Message时,每次都等待消息回执,又该如何设置呢?您可以使用connectionFactory提供的“alwaysSyncSend”设置来指 定每次都等待服务端的回执:

......
// 设置成:无论怎样每次都等待服务器端的回执
// 但关键是您确定自己的业务需求真的需要这样使用吗?
connectionFactory.setAlwaysSyncSend(true);
......
  • 1
  • 2
  • 3
  • 4
  • 5

6-1-2、发送PERSISTENT Message

如果您不特意指定消息的发送类型,那么消息生产者默认发送PERSISTENT Meaage。这样的消息发送到ActiveMQ服务端后将被进行持久化存储(持久化存储方案将在后文进行详细介绍),并且消息发送者默认等待 ActiveMQ服务端对这条消息处理情况的回执。

以上这个过程非常耗时,ActiveMQ服务端不但要接受消息,在内存中完成存储,并且按照ActiveMQ服务端设置的持久化存储方案对消息进行 存储(主要的处理时间耗费在这里)。为了提高ActiveMQ在接受PERSISTENT Meaage时的性能,ActiveMQ允许开发人员遵从JMS API中的设置方式,为消息发送端在发送PERSISTENT Meaage时提供异步方式:

......
// 使用异步传输
// 上文已经说过,如果发送的是NON_PERSISTENT Message
// 那么默认就是异步方式
connectionFactory.setUseAsyncSend(true);
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

一旦您进行了这样的设置,就需要设置回执窗口:

......
// 同样设置消息发送者在累计发送102400byte大小的消息后
// 等待服务端进行回执,以便确定之前发送的消息是否被正确处理
// 确定服务器端是否产生了过量的消息堆积,需要减慢消息生产端的生产速度
connectionFactory.setProducerWindowSize(102400);
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6-2、生产者策略:事务

JMS规范中支持带事务的消息,也就是说您可以启动一个事务(并由消息发送者的连接会话设置一个事务号Transaction ID),然后在事务中发送多条消息。这个事务提交前这些消息都不会进入队列(无论是Queue还是Topic)。

不进入队列,并不代表JMS不会在事务提交前将消息发送给ActiveMQ服务端。实际上这些消息都会发送给服务端,服务端发现这是一条带有Transaction ID的消息,就会将先把这条消息放置在“transaction store”区域中(并且带有redo日志,这样保证在收到rollback指令后能进行取消操作),等待这个Transaction ID被rollback或者commit。

一旦这个Transaction ID被commit,ActiveMQ才会依据自身设置的PERSISTENT Meaage处理规则或者NON_PERSISTENT Meaage处理规则,将Transaction ID对应的message进行入队操作(无论是Queue还是Topic)。以下代码示例了如何在生产者端使用事务发送消息:

......
//进行连接
connection = connectionFactory.createQueueConnection();
connection.start();

//建立会话(设置一个带有事务特性的会话)
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//建立queue(当然如果有了就不会重复建立)
Queue sendQueue = session.createQueue("/test");
//建立消息发送者对象
MessageProducer sender = session.createProducer(sendQueue);

//发送(JMS是支持事务的)
for(int index = 0 ; index < 10 ; index++) {
    TextMessage outMessage = session.createTextMessage();
    outMessage.setText("这是发送的消息内容-------------------" + index);
    // 无论是NON_PERSISTENT message还是PERSISTENT message
    // 都要在commit后才能真正的入队
    if(index % 2 == 0) {
        sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    } else {
        sender.setDeliveryMode(DeliveryMode.PERSISTENT);
    }

    // 没有commit的消息,也是要先发送给服务端的
    sender.send(outMessage);
}

session.commit();
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

以上代码中,在“connection.createSession”这个方法中一共有两个参数(这句代码在上文中已经出现过多次)。第一个布尔型 参数很好理解,就是标示这个连接会话是否启动事务;第二个整型参数标示了消息消费者的“应答模型”,我们会在下文中进行详细介绍。

6-3、生产者策略:ProducerFlowControl

生产流控制,是ActiveMQ消息生产者端最为重要的性能策略,它主要设定了在ActiveMQ服务节点在产生消息堆积,并超过限制大小的情况下,如何进行消息生产者端的限流。

具体来说,如果以上情况在ActiveMQ出现,那么当生产者端再次接受ActiveMQ的消息回执时,ActiveMQ就会让消息生产者进入等待 状态或者在发送者端直接抛出JMSException。当然您也可以配置ActiveMQ不进行ProducerFlowControl,如果您对自己 ActiveMQ服务端的底层性能和消费者端的性能足够自信的话。

在ActiveMQ的主配置文件activemq.xml中,关于ProducerFlowControl策略的控制标签是“destinationPolicy”和它的子标签。请看如下配置示例:

......<destinationPolicy><policyMap><policyEntries><policyEntry topic=">" producerFlowControl="false"/></policyEntries></policyMap></destinationPolicy>
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

以上示例配合所有的Topic模式的队列不进行producerFlowControl策略控制。当然还可以为队列配置启用producerFlowControl策略:

......<policyEntry queue=">" producerFlowControl="true" memoryLimit="200mb"></policyEntry>
......
  • 1
  • 2
  • 3
  • 4
  • 5

以上配置项表示为ActiveMQ中的所有Queue模式的队列启用producerFlowControl策略,并且限制每个Queue信息的 最大内存存储限制(memoryLimit)为200MB;这是指的 最多使用200MB的内存区域,而不是说Queue中消息的总大小为200MB。 例如,在ActiveMQ 5.X+ 版本中NON_PERSISTENT Message会被转出到 temp store区域,所以有可能您观察到的现象是,无论怎样堆积NON_PERSISTENT Message消息,Queue的使用内存始终无法达到200MB。

......<policyEntry queue=">" producerFlowControl="true" memoryLimit="200mb"><pendingQueuePolicy><vmQueueCursor/></pendingQueuePolicy></policyEntry>
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

以上配置表示只使用内存存储Queue中的所有消息,特别是NON_PERSISTENT Message只存储在内存中,不使用temp store区域进行转储。在官方文档中,有关于policyEntry标签的所有配置选项都有完整说明: http://activemq.apache.org/per-destination-policies.html

6-4、消费者策略:Dispatch Async

讨论完了消息生产者的关键性能点,我们再将目光转向消息消费者(接收者端);就像本小节开始时描述的那样, 比起消息生产者来说消息消费者的性能更能影响ActiveMQ系统的整体性能,因为要成功完成一条消息的处理,它的工作要远远多于消息生产者。

首先,在 默认情况下ActiveMQ服务端采用异步方式向客户端推送消息。也就是说ActiveMQ服务端在向某个消费者会话推送消息后,不会等待消费者的响应信息,直到消费者处理完消息后,主动向服务端返回处理结果。如果您对自己的消费者性能足够满意,也可以将这个过程设置为“同步”:

......
// 设置为同步
connectionFactory.setDispatchAsync(false);
......
  • 1
  • 2
  • 3
  • 4

6-5、消费者策略:Prefetch

消费者关键策略中,需要重点讨论的是消费者“预取数量”——prefetchSize。可以想象,如果消费者端的工作策略是按照某个周期(例如1秒),主动到服务器端一条一条请求新的消息,那么消费者的工作效率一定是极低的;所以 ActiveMQ系统中,默认的策略是ActiveMQ服务端一旦有消息,就主动按照设置的规则推送给当前活动的消费者。其中每次推送都有一定的数量限制,这个限制值就是prefetchSize。

针对Queue工作模型的队列和Topic工作模型的队列,ActiveMQ有不同的默认“预取数量”;针对NON_PERSISTENT Message和PERSISTENT Message,ActiveMQ也有不同的默认“预取数量”:

  • PERSISTENT Message—Queue:prefetchSize=1000
  • NON_PERSISTENT Message—Queue:prefetchSize=1000
  • PERSISTENT Message—Topic:prefetchSize=100
  • NON_PERSISTENT Message—Topic:prefetchSize=32766

ActiveMQ中设置的各种默认预取数量一般情况下不需要进行改变。如果您使用默认的异步方式从服务器端推送消息到消费者端,且您对消费者端的性能有足够的信心,可以加大预取数量的限制。 但是非必要情况下,请不要设置prefetchSize=1,因为这样就是一条一条的取数据;也不要设置为prefetchSize=0,因为这将导致关闭服务器端的推送机制,改为客户端主动请求

  • 可以通过ActiveMQPrefetchPolicy策略对象更改预取数量
......
// 预取策略对象
ActiveMQPrefetchPolicy prefetchPolicy = connectionFactory.getPrefetchPolicy();
// 设置Queue的预取数量为50
prefetchPolicy.setQueuePrefetch(50);
connectionFactory.setPrefetchPolicy(prefetchPolicy);
//进行连接
connection = connectionFactory.createQueueConnection();
connection.start();
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 也可以通过Properties属性更改(当然还可以加入其他属性)预取数量:
......
Properties props = new Properties();
props.setProperty("prefetchPolicy.queuePrefetch", "1000");
props.setProperty("prefetchPolicy.topicPrefetch", "1000");
//设置属性
connectionFactory.setProperties(props);
//进行连接
connection = connectionFactory.createQueueConnection();
connection.start();
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6-5、消费者策略:事务和死信

6-5-1、消费者端事务

JMS规范除了为消息生产者端提供事务支持以外,还为消费服务端准备了事务的支持。您可以通过在消费者端操作事务的commit和rollback方法,向服务器告知一组消息是否处理完成。 采用事务的意义在于,一组消息要么被全部处理并确认成功,要么全部被回滚并重新处理

......
//建立会话(采用commit方式确认一批消息处理完毕)
session = connection.createSession(true, Session.SESSION_TRANSACTED);
//建立Queue(当然如果有了就不会重复建立)
sendQueue = session.createQueue("/test");
//建立消息发送者对象
MessageConsumer consumer = session.createConsumer(sendQueue);
consumer.setMessageListener(new MyMessageListener(session));

......

class MyMessageListener implements MessageListener {
    private int number = 0;

    /**
     * 会话
     */
    private Session session;

    public MyMessageListener(Session session) {
        this.session = session;
    }

    @Override
    public void onMessage(Message message) {
        // 打印这条消息
        System.out.println("Message = " + message);
        // 如果条件成立,就向服务器确认这批消息处理成功
        // 服务器将从队列中删除这些消息
        if(number++ % 3 == 0) {
            try {
                this.session.commit();
            } catch (JMSException e) {
                e.printStackTrace(System.out);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

以上代码演示的是消费者通过事务commit的方式,向服务器确认一批消息正常处理完成的方式。请注意代码示例中的“session = connection.createSession(true, Session.SESSION_TRANSACTED);”语句。第一个参数表示连接会话启用事务支持;第二个参数表示使用commit或者 rollback的方式进行向服务器应答。

这是调用commit的情况,那么如果调用rollback方法又会发生什么情况呢?调用rollback方法时,在rollback之前已处理过 的消息(注意,并不是所有预取的消息)将重新发送一次到消费者端(发送给同一个连接会话)。并且消息中redeliveryCounter(重发计数器) 属性将会加1。请看如下所示的代码片段和运行结果

@Override
public void onMessage(Message message) {
    // 打印这条消息
    System.out.println("Message = " + message);
    // rollback这条消息
    this.session.rollback();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

以上代码片段中,我们不停的回滚正在处理的这条消息,通过打印出来的信息可以看到,这条消息被不停的重发:

Message = ActiveMQTextMessage {...... redeliveryCounter = 0, text = 这是发送的消息内容-------------------20}
Message = ActiveMQTextMessage {...... redeliveryCounter = 1, text = 这是发送的消息内容-------------------20}
Message = ActiveMQTextMessage {...... redeliveryCounter = 2, text = 这是发送的消息内容-------------------20}
Message = ActiveMQTextMessage {...... redeliveryCounter = 3, text = 这是发送的消息内容-------------------20}
Message = ActiveMQTextMessage {...... redeliveryCounter = 4, text = 这是发送的消息内容-------------------20}
  • 1
  • 2
  • 3
  • 4
  • 5

可以看到同一条记录被重复的处理,并且其中的redeliveryCounter属性不断累加。

6-5-2、重发和死信队列

但是消息处理失败后,不断的重发消息肯定不是一个最好的处理办法: 如果一条消息被不断的处理失败,那么最可能的情况就是这条消息承载的业务内容本身就有问题。那么无论重发多少次,这条消息还是会处理失败。

为了解决这个问题,ActiveMQ中引入了“死信队列”(Dead Letter Queue)的概念。即一条消息再被重发了多次后(默认为重发6次redeliveryCounter==6),将会被ActiveMQ移入“死信队 列”。开发人员可以在这个Queue中查看处理出错的消息,进行人工干预。

这里写图片描述

默认情况下“死信队列”只接受PERSISTENT Message,如果NON_PERSISTENT Message超过了重发上限,将直接被删除。以下配置信息可以让NON_PERSISTENT Message在超过重发上限后,也移入“死信队列”:

<policyEntry queue=">">  <deadLetterStrategy>  <sharedDeadLetterStrategy processNonPersistent="true" />  </deadLetterStrategy>  </policyEntry>
  • 1
  • 2
  • 3
  • 4
  • 5

另外,上文提到的默认重发次数redeliveryCounter的上限也是可以进行设置的,为了保证消息异常情况下尽可能小的影响消费者端的处理效率,实际工作中建议将这个上限值设置为3。原因上文已经说过,如果消息本身的业务内容就存在问题,那么重发多少次也没有用。

RedeliveryPolicy redeliveryPolicy = connectionFactory.getRedeliveryPolicy();
// 设置最大重发次数
redeliveryPolicy.setMaximumRedeliveries(3);
  • 1
  • 2
  • 3

实际上ActiveMQ的重发机制还有包括以上提到的rollback方式在内的多种方式:

  • 在支持事务的消费者连接会话中调用rollback方法。

  • 在支持事务的消费者连接会话中,使用commit方法明确告知服务器端消息已处理成功前,会话连接就终止了(最可能是异常终止)

  • 在需要使用ACK模式的会话中,使用消息的acknowledge方式明确告知服务器端消息已处理成功前,会话连接就终止了(最可能是异常终止)

但是以上几种重发机制有一些小小的差异, 主要体现在redeliveryCounter属性的作用区域。简而言之,第一种方法redeliveryCounter属性的作用区域是本次连接会话,而后两种redeliveryCounter属性的作用区域是在整个ActiveMQ系统范围。

6-6、消费者策略:ACK

消费者端,除了可以使用事务方式来告知ActiveMQ服务端一批消息已经成功处理外,还可以通过JMS规范中定义的acknowledge模式来实现同样功能。 事实上acknowledge模式更为常用

6-6-1、基本使用

如果选择使用acknowledge模式,那么你至少有4种方式使用它,且这四种方式的性能区别很大:

  • AUTO_ACKNOWLEDGE方式:这种方式下,当消费者端通过receive方法或者MessageListener监听方式从服务端得到消息后(无论是pul方式还是push方式),消费者连接会话会自动认为消费者端对消息的处理是成功的。但请注意, 这种方式下消费者端不一定是向服务端一条一条ACK消息

  • CLIENT_ACKNOWLEDGE方式:这种方式下,当消费者端通过receive方法或者MessageListener监听方式从 服务端得到消息后(无论是pul方式还是push方式),必须显示调用消息中的acknowledge方法。如果不这样做,ActiveMQ服务器端将不 会认为这条消息处理成功:

public void onMessage(Message message) {
    //====================
    //这里进行您的业务处理
    //====================
    try {
        // 显示调用ack方法
        message.acknowledge();
    } catch (JMSException e) {
        e.printStackTrace();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • DUPS_OK_ACKNOWLEDGE方式:批量确认方式。消费者端会按照一定的策略向服务器端间隔发送一个ack标示,表示某一批消息 已经处理完成。DUPS_OK_ACKNOWLEDGE方式 和 AUTO_ACKNOWLEDGE方式在某些情况下是一致的,这个在后文会讲到。

  • INDIVIDUAL_ACKNOWLEDGE方式:单条确认方式。这种方式是ActiveMQ单独提供的一种方式,其常量定义的位置都不 在javax.jms.Session规范接口中,而是在org.apache.activemq.ActiveMQSession这个类中。这种方式消 费者端将会逐条向ActiveMQ服务端发送ACK信息。所以 这种ACK方式的性能很差,除非您有特别的业务要求,否则不建议使用

6-6-2、工作方式和性能

笔者建议首先考虑使用AUTO_ACKNOWLEDGE方式确认消息,如果您这样做,那么一定请使用optimizeACK优化选项,并且重新设置prefetchSize数量为一个较小值(因为1000条的默认值在这样的情况下就显得比较大了):

......

//ack优化选项(实际上默认情况下是开启的)
connectionFactory.setOptimizeAcknowledge(true);
//ack信息最大发送周期(毫秒)
connectionFactory.setOptimizeAcknowledgeTimeOut(5000);
connection = connectionFactory.createQueueConnection();
connection.start();
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

AUTO_ACKNOWLEDGE方式的根本意义是“延迟确认”,消费者端在处理消息后暂时不会发送ACK标示,而是把它缓存在连接会话的一个 pending 区域,等到这些消息的条数达到一定的值(或者等待时间超过设置的值),再通过一个ACK指令告知服务端这一批消息已经处理完成; 而optimizeACK选项(指明AUTO_ACKNOWLEDGE采用“延迟确认”方式)只有当消费者端使用AUTO_ACKNOWLEDGE方式时才会起效

“延迟确认”的数量阀值:prefetch * 0.65
“延迟确认”的时间阀值:> optimizeAcknowledgeTimeOut

DUPS_OK_ACKNOWLEDGE方式也是一种“延迟确认”策略,如果目标队列是Queue模式,那么它的工作策略与AUTO_ACKNOWLEDGE方式是一样的。 也就是说,如果这时prefetchSize =1 或者没有开启optimizeACK,也会逐条消息发送ACK标示;如果目标队列是Topic模式,那么无论optimizeACK是否开启,都会在消费的消息个数>=prefetch * 0.5时,批量确认这些消息。

6-7、消费者和生产者性能总结

本小节我们介绍了基于ActiveMQ构建的消息队列系统中,生产者和消费者需要关注的重要性能点。但是整个ActiveMQ中的性能还需要各位读者在实际工作中,一点一点的去挖掘。这里我们根据已经介绍过的性能关注点进行总结:

  • 发送NON_PERSISTENT Message和发送PERSISTENT Message是有性能差异的。引起这种差异的原因是前者不需要进行持久化存储;但是这样的性能差异在某些情况下会缩小,例如发送 NON_PERSISTENT Message时,由于消费者性能不够导致消息堆积,这时NON_PERSISTENT Message会被转储到物理磁盘上的“temp store”区域。

  • 发送带有事务的消息和发送不带有事务的消息,在服务器端的处理性能也是有显著区别的。引起这种差异的原因是带有事务的消息会首先记录在服务 器端的“transaction store”区域,并且服务器端会带有redo日志,这样保证发送者端在发送commit指令或者rollback指令时,服务器会完整相应的处理。

  • ActiveMQ中,为消息生产者所设定的ProducerFlowControl策略非常重要,它确定消息在ActiveMQ服务端产生 大量堆积的情况下,ActiveMQ将减缓接收消息,保证了ActiveMQ能够稳定的工作。您可以通过配置文件设置 ProducerFlowControl策略的生效阀值,甚至可以关闭ProducerFlowControl策略(当然不建议这样做)。

  • 消息生产者端和消息消费者端都可以通过“异步”方式和服务器进行通讯(但是意义不一样)。在生产者端发送异步消息,一定要和 ProducerWindowSize(回执窗口期)的设置共同使用;在消费者异步接受消息时,要记住有Prefetch这个关键的预取数值,并且 PrefetchSize在非必要情况下不要设置为1。很显然适合的PrefetchSize将改善服务端和消费者端的性能。

  • JMS规范中,消息消费者端也是支持事务的。所谓消费者端的事务是指:一组消息要么全部被commit(这时消费者会向服务端发送ACK表 示),要么全部被rollback(这时同一个消费者端会向自己重发这些消息,并且这些消息的redeliveryCounter属性+1);进行消息的 重发是非常消耗消费者端性能的一件事情,这是因为在这个连接会话中,被Prefetch但是还没有被处理的消息将一直等待重发的消息最终被确认。

  • 为了避免带有错误业务信息的消息被无止境的重发,从而影响整个消息系统的性能。在ActiveMQ中为超过MaximumRedeliveries阀值(默认值为6,但是很明显默认值太高了,建议设置为3)的消息准备了“死信队列”。

  • 只有服务器收到了一条或者一组消息的ACK标示,才会认为这条或者这组消息被成功过的处理了。在消费者端有4种ACK工作模式,建议优先选 择AUTO_ACKNOWLEDGE。如果您这样做了,那么请一定重新改小预取数量、设置OptimizeAcknowledge为true、重设 OptimizeAcknowledgeTimeOut时间。这样才能保证AUTO_ACKNOWLEDGE方式工作在“延迟确认”模式下,以便优化 ACK性能。

(接下文:我们将开始介绍ActiveMQ的持久化存储方案和高可用方案)

 

http://m.blog.csdn.net/article/details?id=50991443



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




看看哪些是机器人最不可能取代的工作和不能替代的事

$
0
0

《福布斯》联合市场调查公司麦肯锡和合伙人对美国超过2000种工作进行调查,研究这些工作在当下和未来实施自动化,也就是用机器来取代人的可能性。其中,最有可能被取代的是可控制环境中的体力劳动岗位,而最不可能被取代的是管理岗位。一个比较有意思的发现是,让机器人上岗工作远比科幻小说中要复杂得多,即使技术达到了让机器替代人的水平,机器人制造成本、社会影响、世人接受度也是要考虑的问题。

随着工作自动化正快速地走出小说,成为现实的一部分,我们认为,这一变化将带来的影响将不仅仅是在人和机器间做选择二选一那么简单。

我们调查了美国所有行业内超过2000种工作。以下是我们研究中的8个发现,强调了每一个领域进行自动化的潜力,同时,研究还就哪一种职业最不可能会被机器取代,从技术的角度提出了参考指标。

1468334091-5696-I6E8fDGiaibY64HtibakOIm1PC7A

从上图看来,最不可能机器取代的工作是教育行业。上图中,红色部分越多,红色颜色越深,代表被取代的可能性最低。

能自动化不代表会自动化

虽然技术是自动化的一个必要先决条件,但是,要开展一个具有竞争力的商业实践,其他的要素也是必不可少的。其中包括开发和部署自动化所需要的硬件和软件的成本,以及劳动力的供需关系。从技术上来看,用昂贵的机器人来取代时薪10美元的厨师是可行的,但从商业上来看却是完全没有意义,因为成本高昂,但是却没能提供好的回报。

法规和社会议题也是重要的影响因素,在医院,很多病人完成手术醒来时,会希望由一位人类护士而不是机器人来照料自己。

某些体力劳动被机器取代的可能性最高

在美国的职场,有近五分之一的劳动时间是关于体力劳动或者在可预测的环境中操作机器的。根据目前技术的发展水平,这些工作中,有四分之三都可以被自动化。制造业和餐饮服务业中的数据尤为突出,这些领域的工作受到自动化影响的可能性最大。

在工厂中,机器人已经在从事一些重复性的劳动,比如,产品组装和包装。而在餐饮业中,一些餐馆已经在尝试使用自助订餐甚至机器人服务员。

数据收集和处理也可以被自动化。在美国的所有职业中,从业者有三分之一的时间都花在搜集和处理数据上。不管是搜集数据还是处理数据,这两种工作都有着极高的可能性会被自动化,而这会影响到一些行业:零售、金融服务和保险。从业者并不一定会从岗位上退下,但是,他们的角色可能会发生非常大的改变。比如,抵押经纪人目前有90%的时间都花在了处理申请表上,以后,他们可能会有更多的时间用来为客户提供建议。

即便是一些高薪水的工作也会受到影响。并不是只有那些低门槛或者低薪资的职业需要搜集和处理数据。调查数据显示,年收入超过20万美元的人,会花30%以上的时间来做这些工作,所以,对于一些公司来说,把这一类工作自动化,是非常有吸引力的。总体看来,在薪资水平和自动化程度上来看,影响变量非常多。

在整理床这件事上,机器并不擅长——至少目前是这样

目前为止,在不可预测的环境中,要求移动或者操作的工作对于自动化来说还是非常有挑战性的。一些例子包括在工地上操作吊车,在公共空间收垃圾,或者是在酒店整理床。最后这一项便是不可预测的,因为不同的旅客会把枕头扔到不同的位置,或者把衣服扔在床上,这让其仍人很难完成客房清洁服务。不过,这种情况很快会得到改变,在提升机器人在实际不可预测环境中的表现上,不少研究已经取得了很大的进展。

1468334090-2947-RjmrvR06eRp3UNRe6fEUSpVdZMkA

是时候去做老师或者牙科保健员了?

在今天可实现的技术条件下,最难进行自动化的工作是那些设计管理和培养人才的(自动化潜力为9%),在这些岗位中,专业知识被用于决策、计划和创意(自动化潜力18%),或者是与客户、供应商和其他股东进行沟通的工作(自动化潜力20%)。在这些工作中,经验和年龄通常是一笔无形的资产,具体的工作内容包括,写代码、设计菜单、写促销材料,或者是为消费者提供建议。

在医疗健康中,只有少于30%的注册护士的工作可以被自动化,而对于牙科保健员来说,这一比例降到了13%。在我们所调查的所有行业中,其中最不可能会被自动化的行业就是教育。教师的工作包含了一些深度的专业知识和复杂的人际互动,在这些方面,除了几个特例外,机器的表现还不能跟人相提并论。

机器可能会改变工作,但是不会完全地取代人类。对自动化的技术可行性的最佳分析不是看职位,而是看人类在这一工作上所花费的时间,以及使用现有的技术条件自动化能达到什么程度。

总的来说,我们发现,以现有的技术条件,只有5%的职业可以被完全的自动化。但是,如果从人类工作内容上看,有45% 都是可以被自动化的。此外,在所有的职业中,约60%的岗位中近30%的工作内容是可以被自动化的。

别老想着节流,想想怎么开源

随着人工智能技术的进步,比如机器在自然语言理解的能力上逐渐达到人类的标准,从技术上来说,能够被自动化的工作内容肯定会越来越多。

自动化会从根本上改变公司组织。经理们面临的难题是,找到在组织中自动化可以在哪些地方发生影响,又有哪些地方可以释放价值。他们需要考虑的东西包括:用机器人替代人类劳动力的成本,以及改变工作场所面临的复杂性。最大的收益可能并不是来自人力成本的减少,而是通过更少的错误、更高的产出、更高的质量、更可靠的安全性和更快的速度带来的生产力的提升。

您可能也喜欢的文章:

Forrester:预计2025年美国将有1200万个工作岗位被机器人取代

永远不会被机器人取代的五种科技业工作

VoucherCodesPro:研究称20%的人愿与机器人性爱

2034年英国35%的工作可能被机器人替代——信息图

Travelzoo:机器人进入旅游业工作的深度调研
无觅

Activiti工作流demo

$
0
0

继上篇《 Activiti工作流的环境配置

       前几篇对Activiti工作流进行了介绍,并讲解了其环境配置。本篇将会用一个demo来展示Activiti工作流具体的体现,直接上干货。

一、demo业务分析

       以HelloWorld程序为例。

      首先说一下业务流程,员工张三提交了一个申请,然后由部门经理李四审核,审核通过后再由总经理王五审核,通过则张三申请成功。接下来用Actitivi工作流来实现业务。

二、新建项目

        首先新建一个Activiti项目,目录结构如下。

       

三、画流程图

        在diagrams下新建一个Activiti Diagram:右击diagrams->new->others->Activiti Diagram

        然后画流程图:

         指派各活动节点的分派人:分别为张三,李四,王五。

四、配置环境

        引jar包,建数据库建表,配置日志文件,参考上篇博文《Activiti工作流的环境配置》

五、新建HelloWorld类

        配置好环境后,新建HelloWorld类,代码如下。

<span style="font-size:18px;">package cn.itcast.a_helloworld;


import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class HelloWorld {
	
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	/**部署流程定义*/
	@Test
	public void deploymentProcessDefinition(){
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createDeployment() //创建一个部署对象
			.name("helloworld入门程序")//添加部署的名称
			.addClasspathResource("diagrams/helloword.bpmn")//从classpath的资源中加载,一次只能加载一个文件
			.addClasspathResource("diagrams/helloword.png")//从classpath的资源中加载,一次只能加载一个文件
			.deploy(); //完成部署
		System.out.println("部署ID:"+deployment.getId());  //1
		System.out.println("部署名称"+deployment.getName()); //helloworld入门程序
		
	}
	
	/**启动流程实例**/
	@Test
	public void startProcessInstance(){
		//流程定义的key
		String processDefinitionKey ="helloworld";
		ProcessInstance pi = processEngine.getRuntimeService()//与正在执行	的流程实例和执行对象相关的Service
						.startProcessInstanceByKey(processDefinitionKey);  //使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
		System.out.println("流程实例ID:"+pi.getId());
		System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
	}
	/**查询当前人的个人任务*/
	@Test
	public void findMyPersonalTask(){
		String assignee = "张三";
		 List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
						.createTaskQuery()//创建任务查询
						.taskAssignee(assignee)//指定个人任查询,指定办理人
						.list();
		if(list!=null && list.size()>0){
			for(Task task:list){
				System.out.println("任务ID:"+task.getId());
				System.out.println("任务名称:"+task.getName());
				System.out.println("任务的创建时间:"+task.getCreateTime());
				System.out.println("任务的办理人:"+task.getAssignee());
				System.out.println("流程实例ID:"+task.getProcessInstanceId());
				System.out.println("执行对象ID:"+task.getExecutionId());
				System.out.println("流程定义ID:"+task.getProcessDefinitionId());
				System.out.println("############################################");
			}
		}
	}
	/**完成我的任务*/
	@Test
	public void completeMyPersonalTask(){
		//任务ID
		String taskId = "11402";
		processEngine.getTaskService()//与正在执行的任务管理相关的Service
						.complete(taskId);
		System.out.println("完成任务:任务ID:"+taskId);
	}
}</span>
        分开来讲:

1、部署流程定义

<span style="font-size:18px;">	/**部署流程定义*/
	@Test
	public void deploymentProcessDefinition(){
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
			.createDeployment() //创建一个部署对象
			.name("helloworld入门程序")//添加部署的名称
			.addClasspathResource("diagrams/helloword.bpmn")//从classpath的资源中加载,一次只能加载一个文件
			.addClasspathResource("diagrams/helloword.png")//从classpath的资源中加载,一次只能加载一个文件
			.deploy(); //完成部署
		System.out.println("部署ID:"+deployment.getId()); //1
		System.out.println("部署名称"+deployment.getName()); //helloworld入门程序
		
</span>

       执行完后,4张表中的数据:

      1)act_re_deployment (部署信息表)

      2)act_re_procdef(流程定义数据表)


      3)act_ge_bytearray(二进制数组表)

       4)act_ge_property(属性数据表)


2、启动流程实例

<span style="font-size:18px;">/**启动流程实例**/
	@Test
	public void startProcessInstance(){
		//流程定义的key
		String processDefinitionKey ="helloworld";
		ProcessInstance pi = processEngine.getRuntimeService()//与正在执行	的流程实例和执行对象相关的Service
						.startProcessInstanceByKey(processDefinitionKey);  //使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
		System.out.println("流程实例ID:"+pi.getId());//流程实例ID   101
		System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID
	}</span>
           执行完后四张表中的数据:

         1)act_ru_execution(运行时流程执行实例表)


         2)act_ru_task(运行时任务节点表)

         3)act_identitylink(运行时流程人员表)

         4)act_hi_taskinst(历史任务实例表)


         5)act_hi_procinst(历史流程实例表)


         6)act_hi_identitylink(历史流程人员表)

 

         7)act_hi_actinst(历史节点表)


         8)act_ge_property

         从上图中可以看出变化,next.dbid的VALUE_值由原来的101变为201,REV_由原来的2变为3。

        

3、查询当前人的个人任务

<span style="font-size:18px;">/**查询当前人的个人任务*/
	@Test
	public void findMyPersonalTask(){
		String assignee = "张三";
		 List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
						.createTaskQuery()//创建任务查询
						.taskAssignee(assignee)//指定个人任查询,指定办理人
						.list();
		if(list!=null && list.size()>0){
			for(Task task:list){
				System.out.println("任务ID:"+task.getId());
				System.out.println("任务名称:"+task.getName());
				System.out.println("任务的创建时间:"+task.getCreateTime());
				System.out.println("任务的办理人:"+task.getAssignee());
				System.out.println("流程实例ID:"+task.getProcessInstanceId());
				System.out.println("执行对象ID:"+task.getExecutionId());
				System.out.println("流程定义ID:"+task.getProcessDefinitionId());
				System.out.println("############################################");
			}
		}
	}</span>
        执行完后,能够从运行时任务节点表中查询出相关的信息并显示出来。与上面同理,act_ge_property的两个值分别又变了。

        

4、完成我的任务

<span style="font-size:18px;">    /**完成我的任务*/
    @Test
    public void completeMyPersonalTask(){
        //任务ID
        String taskId = "104";//运行时任务ID
        processEngine.getTaskService()//与正在执行的任务管理相关的Service
                        .complete(taskId);
        System.out.println("完成任务:任务ID:"+taskId);
    }</span>
        执行完后,表的变化。

       1)act_ru_task


       从上表中可以看出完成张三的任务后,张三的任务消失,李四的任务显示在表中。

        2)act_ru_identitylink


      从上表中可以看出多了一条李四的用户数据。

      3)act_hi_actinst


        从上表中可以看出多了一条李四的节点数据。

        同理act_hi_identitylink也会多一条李四的用户数据, ac_hi_taskinst多一条李四的任务数据。

        然后完成李四的任务,到王五同理;完成王五的任务后张三申请成功,同理,但是运行时表的数据会全部清除,act_hi_procinst的结束相关字段会更新。至此,整个申请结束。


        这是Activiti工作流的一个小demo,大家可以参照着实践一下。下面是本demo及更多demo源码下载的地址: http://download.csdn.net/detail/u013037201/9559857

          

作者:u013037201 发表于2016/9/2 23:06:24 原文链接
阅读:65 评论:0 查看评论

Quora在自然语言处理上的所做的工作

$
0
0

问答网站最核心的内容是提供给优质的内容,如何让内容更加优质,处理分析大量的文本数据也是必不可少的工作。Quora有大量的文本数据,分布在Quora的数百万个问题、答案和评论中。不仅如此,还有大量的元数据来补充我问答,包括”赞”和”踩”,用户对话题的兴趣或擅长与否,问题和话题的关系,话题去重合并,用户的社交和关系和影响力幅射,以及用户在Quora的每一个操作历史。如此丰富的数据集让Quora能够从一个非常特殊的视角去看待如何用自然语言处理(Natural Language Processing NLP)技术去解决一些有趣并且有用的问题。这些问题主要集中在以下方面:

  • 随着内容的增长,如何维持并改进我们内容的质量
  • 让内容更加结构化,从而让知识的索引更简单
  • 让社区保持稳定且健康。

让优质答案优先展示

为了让读者优先看到优质的答案,Quora给答案进行了评分,评分主要基于下面几个客观维度,书写风格,可读性,完整性,可靠性。

Quroa早期对于问答的排序是按照赞成和反对票数量的简单排名函数(百分比,或者差值),称其为基准线。虽然效果还不错,但是也存在一些问题:

  • 时间相关:我们在答案收到投票之前无法排名。
  • 马太效应:内容一旦收获投票,则更容易收获更多的投票。
  • 玩笑答案:玩笑答案往往很热门,但是不见得对问题有任何帮助。
  • 可发现性:新加入Quora的专家,可能没有足够多的followers,他们的内容无法被看到,导致她们的回答永远在后面,然后他们就更难获得followers。

Quora的排序方法:

Quora定义一个好的答案要拥有如下5个特性:

  • 不能答非所问。
  • 给任何对这个问题感兴趣的人提供可以复用的知识。
  • 答案必须符合基本原理。
  • 示范必须可信,基础事实必须正确。
  • 清晰,易读。

answer-rank

上面的截图,我们看到了一个好回答的例子。注意框选区域,他们显示了可以用在预测中的结构化信息,例如,作者的可信度,格式,赞同票,等等。Quora还有很多作者和投票者的历史数据,来推断主题专业度以及可信度。

Quora在回答排序方法中使用的是非个性化supervised item-wise regression方法。使用的是监督学习,所以需要训练数据用来抽取特征,建立模型。不管问题如何被建模,都希望可以客观的验证模型。一个方法是使用A/B测试来验证模型,观察相关的指标。这通常被叫做在线验证。另外一种方法,离线验证,指的是模拟排名,然后用它们和一些已知的好的排名比较。离线验证显著优点是可以快速的迭代型。对于答案排序,选择了任何一个模型,都可以有最佳的表现, Quora专注于离线验证,因为Quora需要做的不是短期的优化用户行为表现,而是提供更高质量的产品。

创建一个好的数据集可能成本高昂,但是对在离线情况下验证排名算法极端重要。Quora使用很多不同的方式来了解答案的真实质量。例如,曾经考虑使用一个答案列表,用赞同票和反对票的比例作为标签。这可以作为构建一个基础信任数据的一个不错的起点。这样的数据有很多,因为Quora上有成百万的答案既有赞同票也有反对票。然而,这种标签的问题跟之前反对票标签会遭遇类似的问题。它会把一些非常流行,但是低质量的答案(例如,玩笑答案)排在前面。

另外一种其他人得到训练数据的方法是进行一个用户调查。调查页面可能会问用户是否觉得某个答案有用。结合用户正在看什么答案,以及他们未来参与等级如何,来推测这个信息。所有这些方法都有它们的长处和缺点,在现实世界的设定下,可能想尝试很多种有创意的方法,然后尝试把它们都结合到一个权威的基础信任数据集。

data-set

使用从训练集抽取的一组特征训练我们的模型。特征选取就是用一组函数把我们的例子转换成数值的流程。supervised学习设定下,特征选取是一个模型成功的主要贡献者,也常常是构建一个好的机器学习系统最难的部分。Quroa用对答案质量的直觉测试了大量的特征。尝试过的:基于文本的特征,基于专业度的特征,基于作者投票者历史行为的特征。一开始使用效果明显(高ROI,高投资回报率)的基于文本的特征,但是实验了一阵子,开始尝试更复杂的概念,比如 句法复杂度(syntactic complexity)。很重要的一点,我们期望我们的特征选取做的足够的好,但是文本特征实际上经常产生问题。Quroa最后组合特征,并且如果合理的话重用其他机器学习模型的输出。一个组合模型往往比单一特征更好,常常是提到性能的强大方法。例如,有一个模型尝试去估价一个用户对指定主题的专业度,从这个模型引出的特征结果非常有效。

为了解决通用回归(general regression)问题,Quora实验了几个模型:linear regression、logistic regression、random forests、gradient boosted trees、neural networks。很多都不错,特别是gradient boosted trees以及一些深度学习(deep learning)方法,非常不错。但是,Quroa很在乎的模型可解释性——任何时候,排名看起来不对,都想知道问题出在模型、特征、训练数据、或者还是其他的原因。大家都知道模型越简单,就越好解释。例如,线性回归就是一组特征的权重,但是神经网络可能有很多层,难以解释和可视化。而且从性能考虑,Quroa倾向于简单的模型。

问答作为一个机器学习问题一文中提到,寻找正确的度量是非常重要的。既然选择了point-wise排名方法,就需要关注很多高级度量,有一些是基于排名的,有一些是point-wise的。Quora使用如下的度量方式:

  • 基于排名的:NDCG、Mean Reciprocal Rank、Spearman’s Rho, Kendall’s Tau
  • point-wise:R2、Mean Squared Error

基于排名的度量给Quora关于算法的信息,同时point-wise的确保评分在尺度上接近训练数据,不同问题之间的答案也可以被比较了。

当用户在Quora加上了一个新答案,希望尽快在问题页面给这个答案排名,以提供一个平滑的用户体验。虽然预测的延时非常低,但仍旧需要为新答案计算一些耗时的特征,这种延时会损害加入答案流程的用户体验。所以,创建了一个单独的模型,仅基于那些容易计算的特征,为新加入的答案提供一个还不错的近似评分,来快速排名。一旦答案被添加后,我们会异步的计算一个更准确的评分。

在上百万个答案上实时排名是一个核心的挑战。问题页面可以包含数百个答案。想象一个系统使用数百个特征,需要上百毫秒去计算。问题页面可能需要10秒钟以上去加载。在这种情况下,答案的评分必须更快的产生,所以,把答案评分缓存起来,以便问题页面可以在合理的时间内加载完成。但是,缓存的问题是,如果任何一个特征值变了,我们就可能需要更新答案的分数。为了节约重新计算全部特征的时间,也需要保存全部的特征值。所有这些数据(答案得分、特征值),都保存在可以支撑大量的数据以及写入的HBase中。

缓存每个答案的得分带来的一个问题是,当一些问题或者用户的特征改变时,我们需要更新大量的答案。考虑一个可能有上万个答案的用户。如果依赖于特征,例如用户的答案数,那么每次他增加一个答案,我们就需要更新他全部答案的评分。答案多的用户,往往添加答案也更频繁,这就更恶化了这个问题。为了缓解这个问题的影响,需要把部分用户和问题的数据组织起来。然后,尝试批处理计算这些答案的分数,减少重复的计算。

以上一切,仍旧无法把更新量降低到一个可以控制的范围,所以,在决策树内部做了其他的优化。如果更新一个特征不会影响到答案的评分,我们就不更新它。以上全部的优化,把预测工作量降低了70%,模型在目前的规模下可以高效的运行。

总体上,模型生成的积分,比基准线准确得多。在全部的度量标准下,相比基准线提高了50%的效果,缩短了和完美排名之间的差距,排名质量看起来很不错。同时这些评分对很多基于好答案定义的应用都很有价值:

  • 折叠答案。如果一个答案的积分太低,它可能是坏的内容,应该被折叠。我们现在还会在作者得到反对票之前,就提示他内容质量不够高,可能会被折叠。
  • 高质量的通知。如果用户收到一个低质量答案的通知,那是一个非常坏的用户体验。
  • 提高首页流的排名效果。

在这些改进的基础上,还有很多需要去做。例如,模型还不能个性化。也可以多花些精力放在用更高的技术来给回答文本建模。可以研究Recurrent Neural Networks,它可以处理词序列(早期实验结果很好)。或者,使用一个可以处理更多数据的模型。总体上,会把精力放在更复杂的自然语言处理(Natural Language Processing (NLP))方法上,帮助我们理解问题和回答的语义。

自动纠正语法

因为Quora是在世界范围内进行知识的共享和探索,因此能让不同英语水准的人都能够在Quora进行写作。通过使用NLP,可以自动改进一小段话的语法或者可读性,而不改变它的意思。

关于自动语法纠正,我没有找到更多的资料。 Grammarly:在线语法纠正和校对工具是一个可以帮助用户自动校队语法,纠正英语句子的在线工具,你可以把自己的英文文本发送到该平台上,通过他们的庞大的数据库来帮助你检测和纠正文本中的错误。

问题重复检测

看到一个问题的各种花式问法是让人很心烦的,读者必须看很多页面才能找到答案,作者必须回答一个问题很多次。Quora希望能够有唯一的,规范的提问方式。为了达到这个目标,必须能够判断一个新问题是否已经在Quora有过类似的问题了,从而检测到问题重复。由于Quora有数百万个问题,重复问题检测是一个非常困难的挑战,如果还想在用户敲问题的同时,实时给出提示,则是难上加难。

相关问题提示

在问题有了答案之后,我们经常希望找到相关的问题或者后续问题。Quora的用户也是如此——人们喜欢通过相关的问题来发现新的内容。根据一个问题,寻找在Quora上已经存在的相关问题就是又一大NLP挑战。特别是在区分相关问题和重复问题的时候难度更大,因为这两者的区分特别小。

话题的专业背景质量

许多在Quora上回答问题的人都是某个领域的专家。质量系统需要很好的理解这些作者在这些话题上的专业性和权威性,话题的专业背景就是理解时的一个重要依据。通过话题专业背景,可以使作者在同一个话题内的答案,拥有相同的质量评分。比如说,在”机器学习(Machine Learning)”话题下的专业背景就包括:

  • 应用统计学博士
  • 本科学历
  • Quora的ML工程师
  • Montreal研究院学习算法负责人

这些背景表明了不同的专业性和权威性。不过仅仅通过话题专业背景来推测专业性就是一个困难的NLP问题。不仅仅因为专业背景字数非常少,往往少于100字,而且系统必须支持各种各样差距很大的话题,比如爵士音乐和火箭工程。

User Trust/Expertise Inference 这是Quora另一件非常重要的事情,Quora需要找出某个领域的专家,然后通过产品引导这些专家在这个领域里贡献更多的优质答案。Quora会考虑用户在某个领域里回答问题的多少,接收到的顶、踩、感谢、分享、收藏及浏览等数据。另外还有一个很重要的是专业度的传播效应,比如在推荐系统领域对某个答案顶了一下,那么这个答案作者在推荐系统领域很可能具备较高的专业度。

话题标定器

Topic是对一个主题内容的聚合,Topic在Quora的信息架构里面承载着极其重要的角色,是知识结构的骨架,Quora管这个叫做Topic Network,如何构建Topic Network本身就是一个非常大的挑战,另外还需要解决的问题包括,如何把Topic下(潜在)优质的问题发掘出来,以及如何把水问题降权和过滤/合并重复问题等。

Quora的话题组成非常的复杂,大到”科学”小到”山顶的网球场”应有尽有。为了给用户展示他们想了解的话题的同时也能展示给他们一些他们专业领域内却又没有被回答过的问题。为了能做到这些,需要给问题打标签。每一个新来的问题打上一个话题库里的已有的标签。这是一个非常困难的NLP问题,因为每一个问题只有一小段文字而已。

Quora花了很大力气来正确引导用户给内容打标签,持续不断坚持这项工作的好处开始逐渐显露出来了,他们发现

  • 随着用户群体的扩大,Topic正在呈现出迅速多样化的势头。
  • 很多领域都自组织出了相当不错的层级知识结构。

Quora相信这种依靠社群来组织领域知识的方式是可行的。

topic-network

搜索

Quora的知识库是不断的增长的,因此搜索是很重要的。把NLP技术应用在信息检索领域的目的是为了更好的理解我们用户的问题和搜索词,并给问题,答案,话题以及用户背景排序。与传统的搜索引擎不同,传统的搜索引擎只需要简单的匹配关键字,而Quroa还需要支持用很长询问句作为查询语句。

问答摘要

数百万人都会在Quora上面写篇幅很长又很有深度的答案,这很普遍。但是,有时候读者只想大概的看一下答案,而不去了解所有细节,特别是在移动设备上访问Quora的时候。NLP挑战就是如何自动生成这些答案的摘要。这些摘要必须抓住整个答案的要领。目前Quora还没有问答摘要,但是Quora觉得这会对提升我们的用户体验很有帮助。

自动生成问答维基

尽管有些读者喜欢读一篇文章下的不同答案,更多的人还是希望能快速的找到答案,然后去做别的事情。作为问答摘要的扩展,另一个NLP问题的挑战就是如何为整个问答页创建维基页。比如,能够处理和总结一个问题下面所有的答案所代表的不同视角,并且整理成一个方便阅读的格式。这比仅仅生成问答摘要还要难的多,但是Quora对解决这个问题非常感兴趣。

负面情绪检测

Quora是一个文明互助的社区,并不排斥直白,但是反对侮辱和消极的信息。使用NLP技术快速的检测到那些粗鲁低俗的语言,并且快速的除掉它们。

垃圾信息检测

Quora能帮助用户快速的发布他们的内容,同时这也意味着很多垃圾网站会利用平台发布垃圾信息来给他们的网站导流。因此垃圾信息检测是NLP工作中的一个重要应用: 无论是问题还是答案,我们都会自动识别出他们是不是垃圾信息。尽管支持个人或者公司在Quora上推广产品,但是垃圾信息和自营销是有着微妙却又十分重要的区别的。

问题编辑质量检测

在Quora,允许社区里的任何人改进一个问题的措辞。有时候用户对问题的修改会导致问题的含义发生变化,有时候甚至会有人进行恶意篡改。判断一次修改是否是对一个问题的改善,让问题更清晰或者至少不改变原意也是一个困难的NLP挑战。Quora正在解决这个问题。

将问题推荐给用户

在问题推荐上,Quora主要考虑三个因素:Relevance(关联度)、Quality(质量)和Demand(需求)。Quora核心的数据模型及其之间的关系:

r-q-d

Quora做推荐的一个最核心问题就是Personalized Feed Ranking。Quora是以问题、答案与主题为核心把「知识」串联起来,然后基于用户的顶和踩等动作来划分内容质量,最后再通过人和问题的Follow关系让知识在社区内流动起来。而个人Feed正是这种「流动」的最主要的载体。Quora Feed Ranking的首要目标是确保推送进用户Feed的内容应该是和用户兴趣高度相关的,其次还需要考虑的包括用户之间的Follow关系以及互动,另外还有时间因素,比如一些和热点事件相关的问答,也应该及时地推送进用户Feed。即:Present most interesting stories for a user at a given time

  • Interesting = topical relevance + social relevance + timeliness
  • Stories = questions + answers

Quora主要使用的是个性化的learning-to-rank方法,相比于时间排序(time-ordered),相关度排序大大提升了用户参与度。但也同时面临的挑战:

  • potentially many candidate stories(太多潜在信息)
  • real-time ranking(实时性)
  • optimize for relevance(关联优化)

下图是Quora做Feed Ranking最最基础的数据构成,Quora管这个叫做「impression logs」。

impression-logs

围绕这些基础行为,Quora定义的Relevance函数如下:

relevance

简单讲就是使用一个「行为加权函数」来预测用户对一个story的感兴趣程度。有两种可选的计算方法,一种是把所有行为弄到一个回归模型里面直接预测最终值,另外一种就是先分别预测每个动作的可能性(比如顶、阅读、分享等)然后再综合起来加权求和。第一种简单,但可解释性稍差,第二种可以更好的利用每个动作信号,但需要给每个动作配一个分类器,计算消耗大。Quora主要使用的三类模型如下:

models

Quora最主要的特征包括:

  • user (e.g. age, country, recent activity)
  • story (e.g. popularity, trendiness, quality)
  • interactions between the two(e.g. topic or author affinity)

从整体框架来看,Quora的Feed Ranking也没有什么太特别的地方,基本上也是业界的标准打法。Quora比较特别的是它的数据模型相对其他网站更复杂,之间的关系也更多样化。比如从用户角度看,既可以follow其他用户User,又可以follow问题Question,还可以follow主题Topic。Follow用户接收到的信息范围更广也更多样化,惊喜内容很可能就是来自于自己关注的有趣的用户,但也可能最容易制造不相关的内容噪音,这块的最重要工作是用户专业度的评估。

将用户推荐给问题

Ask2Answers是Quora产品里面非常重要的一个功能,本来Quora是可以直接把相关问题推荐给系统认为的合适的回答者的,Quora最开始也是这么做的,但系统自动做这事儿显然不如发动群众人肉邀请回答来得感觉好,Ask2Answers 操作增强了仪式感,让被邀请者有种被人需要的感觉,心理上很满足,另外这也是一种社交动作,社交的精髓之一就是为用户制造「装逼」的便利,回答问题前很随意的「谢邀/泻药」,一切尽在不言中了。

ask2answer

这个功能看似很简单,Quora也是下了功夫的,Quora把A2A这事model成了一个机器学习问题:Given a question and a viewer rank all other users based on how 「well-suited」 they are。其中

「well-suited」= likelihood of viewer sending a request + likelihood of the candidate adding a good answer

既要考虑浏览用户发送邀请的可能性,又要考虑被邀请者受邀回答的可能性。Quora的blog上也有一篇文章详细讲解了他们的做法。

data-pipeline

识别问题与时间的关系

Quora主要研究成果如下:

  • 识别特定时期内与当时事件紧密相关的单词,其中的主要挑战是处理问题集中的自然语言数据。通过选定恰当的问题集合,并关注特定词性的单词,他们使用标准NLP技术TF-IDF获得了一个令人信服的单词集合。
  • 综合运用专门为自然语言数据而设计的统计检验和基于图的聚簇技术,他们可以发现能够强有力地代表特定Quora历史时期的单词语境。这样,关于一个单词为什么对于特定的历史时期而言非常重要,他们就能够自动提取更多的信息。
  • 他们还能够识别出这些语境如何随时间演进,而这可以让他们从Quora的讨论中看到更广泛的世界中人、企业和事件的关系。

按季度识别最有代表性的单词

由于他们最感兴趣的内容是提问者所提的问题是关于什么主题的,所以他们使用词性标注来过滤问题文本中的关键词,并且只保留名词。此外,考虑到不同国家的人有不同的背景、文化和兴趣,他们根据提问者的国籍划分了问题集合。选取最有代表性的单词有许多方法,最简单的是根据词频排序,但这种方法无法排除常用词。为此,他们选择了TF-IDF方法。在具体实现上,TF为单词在特定国家特定季度的非匿名问题中出现的次数,IDF为单词在特定国家所有问题中出现的次数,减去该单词在特定国家特定季度的非匿名问题中出现的次数,公式如下:

tf-idf

其中,Q表示特定季度,W表示特定单词。该方法可以提供合理的结果,但为了提高所识别出的单词和当时事件的相关性,他们对识别出的单词进行了进一步的过滤。例如,只保留在特定季度里至少被三个提问者使用过的单词。另外,去掉NLTK中定义的停用词以及在NLTK Brown语料库中出现超过10次的单词。下图是进一步过滤排序后生成的一个“单词云(word cloud)”示例:

season-words

在2011年,Quora刚刚在硅谷成立,最具代表性的单词大多数与重大技术和政治事件相关。例如,近场通信(NFC)服务推动了移动支付的广泛应用,人们在预测Groupon、Zynga和Yelp的IPO,等等。

代表性单词的语义语境

对于单词云中的单词的代表性,有的很容易解释,有的并不明显。为此,他们基于单词共现频率设计了一种自动提取单词语境的方法。与生成单词云的过程相比,他们使用了一个更大的单词集合:去掉了停用词,但并没有去掉名词之外的其他单词,也没有限制单个提问者使用某个单词的次数。他们按照如下条件对单词对进行了过滤:

  • 最少共同出现了4次;
  • 共现次数超期望值,即 Nab
  • 随机共现的概率小于5%。

其中,N AB为单词A和B实际的共现次数,N为非匿名问题的数量,N A(N B)为出现单词A(B)的问题的数量。使用这些规则,他们构建了一个图,顶点表示单词,边连接满足上述条件的单词对。对于每条边,他们使用下面的公式赋予一个权值:

fab

通过这种方法,他们识别出图的连通部分,并命名为“语义簇(semantic clusters)”。那些包含最有代表性单词的语义簇是他们重点关注的。下图是一个语义簇示例:

semantic-clusters

美国,2011年第2季度 该语义簇表示,Facebook在2011年6月推出了研究Facebook社交图谱的工具 Graph API Explorer

单词关系随时间演进

在生成单词语义簇之后,他们进一步研究了单词语境随时间的演进。他们从多个季度中选取了最具代表性的单词,他们称为“关注词(focus word)”。对于每个单词A及每个与A关联的单词B,他们使用前文定义的f(A,B)计算两者在2012年到2015年之间不同季度里的共现频率指标。接下来,他们就使用这些值分析单词之间关联关系随时间的变化情况。下图是一个单词语境演进示例:

obama

可以看出,在2012年总统大选之前,Barack Obama经常和Mitt Romney一起被提及,而在2013年8月前后同Syria相关的问题更显著了。总之,他们使用NLP技术分析问题文本,提取最有代表性的单词,并使用单词云的形式将它们可视化。然后,他们使用语义聚簇方法识别出相关度较高的一组组单词,即语义簇。最后,他们分析了一个单词的语境如何随着时间变化。

参考链接:

女性提出离婚诉讼高达70-80%,男人用工作和出轨逃避

$
0
0

文:吴迪(心理咨询师/两性关系专家/恋爱训练营创办人)

 

从2008年开始,来自中国 民政部与法院的统计表明,在所有离婚案件与诉讼中,女性提出离婚的比率高达70%-80%。这个数字,颠覆了我们之前对于传统婚姻中女性逆来顺受的认知。北上广等发达地区的都市女性是城市离婚率推高的“主力军”,这些女性有以下特征:学历高,收入高,离婚率排在前三位职业的分别是专业人士,白领,企事业单位负责人。

 

要去法院诉讼,无非一个想离一个不肯,或者条件谈不拢。婚律师们的反馈是:女性当事人主动提出离婚的越来越多,而男性当事人以消极和被动姿态来面对不和谐婚姻的也越来越多,这样的案件在受案中比例达到60%以上。

 

女人是感情动物,对婚姻的期望值远远高于男性(且不论这种期望是否现实)

女人比较敏感,更容易意识到夫妻间的裂痕。对那些经济收入不错的女性来说,离婚了自己照样可以过得好,更容易提出离婚。

 

我的心理咨询室也来过很多闹离婚的夫妻,女人想离,男人不肯的。男人不肯离婚有以下几个原因:

1.  他不理解妻子为什么要离婚?我们没有原则性问题(通常指家暴、出轨、黄赌毒和欠债),过日子不就是这样吗?对女人提出的离婚理由诸如“没有爱情了、婆媳关系不好、没有共同语言、你没有情趣、价值观不同、性生活没有快感、你不够关心我……”他们表示听不懂。

2.  结婚成家是他个人成功的总要组成部分,离婚是人生的失败。

3.  结婚成家花了他和他父母很多钱,一旦离婚,分割财产,经济损失惨重。

4.  哪怕男人平时陪孩子的时间很少,他也认为妻子获得了监护权会让他彻底失去孩子。

5.  应对不和谐的婚姻,可以拼命地投入工作,尽量晚回家不回家。还可以用出轨和嫖娼找慰藉。所以,就不必离婚了,凑合过呗。

6.  离婚了,以后还要再找,麻烦;还要再结一次,费钱。

 

而我的女性咨客中,更多的还是犹犹豫豫不想或者不敢离婚的,我发现她们来找我,其实就是想让我以心理专家的角度,给她们一个不离婚的理由!那些直接上法院提离婚诉讼的女性,就不需要来跟我要理由了。

 

我做两性关系的心理咨询13年了,很多婚姻不幸福的女人来跟我哭诉,她们喜欢说这么一句话:“我们也没有什么原则性的问题,就是性格不合经常吵架……(或者是性不合,长期的无性婚姻;或者是三观不合;或者是跟对方的父母不合;或者是不能忍受对方失业、收入降低、没有上进心等等。)

 

听了她们的叙述,我很疑惑,婚姻已经千疮百孔,却还要说没有原则性问题,那么到底什么才是原则性的问题才会下决心离婚呢?12年、接待过上千的咨客,我总算明白了,她们所谓的原则性问题是:

1。男人出轨,情节特别严重,比如小三打上门来挺着肚子逼宫(即使这样很多大婆也坚决不离,说是不能便宜了狐狸精)。

2。男人在外欠了大额的债,比如高利贷,还要卖房子。

3。男人虐待老人和孩子。

4。男人动手打老婆(我有个咨客被老公打了想离婚,她妈还劝她忍忍呢)。

反正都是有可能要报警的事情。我常常感慨我们中国人对婚姻的依赖度实在是太强了,一定要发生那么可怕的事情,才觉得可以理直气壮地说出来去离婚。

 

而更多的折磨人的婚姻的问题,是不足以对他人道的,所谓鞋舒不舒服只有脚知道。很多咨客喜欢以这样一句话开头说她们自己的婚姻:“在别人的眼里,我们是很好的一对夫妻……”我每次都打断,不要说在别人眼里,没有意义,说你自己的真实感受。

 

真实感受1:结婚前他就不喜欢我碰他,比如坐飞机磕睡我把头枕到他肩膀上他都觉得不舒服,结婚后平时外出我拉他手会被甩开。怀孕后就停止了性生活,现在孩子都1岁了。我们睡在一个被窝里,可是他不喜欢我碰到他。我只有30岁,这是要我一直守活寡吗?

 

真实感受2:他是农村出身,小时候特别苦,养成了非常节俭的习惯,他认为我乱花钱,在他面前我有一万个错。我们家不可以用微波炉,他说有辐射伤害身体;孩子坚决不可以吃麦当劳肯德基,他说有害身体;毛巾用到烂了还是不可以换,他说浪费;我给他买新衣服他会光火,他说浪费……我在外面好好的一个人,一回家就里外不是人。

 

真实感受3:他原来工作一直都不错,40岁那年在公司里遭遇了政治斗争被排挤出去了,从此一蹶不振。失业后也不再努力去找工作,各种借口,在家炒股票做点理财,可是也没有赚到钱。他才45岁,难道就这样退休了?我不能跟他提找工作的事,提了他就会炸锅。

 

真实感受4:我婆婆非常强势,她有我家的钥匙,想来就来。她不许我们雇阿姨,我要生孩子了,想用月嫂也不行,她要来带。我们的房子是婚前老公的父母全款买的,房产证上没有我的名字。婆婆想住过来,老公不敢反对,因为,这是她的房子。

很多很多这样不足为外人道的婚姻折磨,说给别人听,得到的千篇一律是劝解:“好啦,忍忍就过去啦,这些都不是原则性的问题……”跟别人说不得,说不通,得不到理解和支持,所以要花钱来跟我这个心理咨询师说。

 

我告诉她们,你们说的都是原则性问题! 性不和谐,价值观严重冲突,生活习惯严重不合,无法有情感交流,对方丧失了在社会上谋生立足的能力,父母严重干涉儿女的婚姻生活——这些都是天大的原则问题,分分钟导致离婚。

 

婚姻都糟糕成那样啦,为什么还不打算离婚?理由很多啦:为了孩子,为了父母,为了别人的眼光,为了男人赚钱比自己多,更害怕离婚后也没有更好的选择。她们中大多数收入比老公低,部分是全职太太;但是也有收入比老公高的,依然很依赖婚姻。所以在咨询的时候常常是这样的:前一分钟她痛哭流涕控诉老公的种种不是;后一分钟说到要不要离婚,她马上为老公辩护 “他对家庭还是很负责任的,钱都给我,对孩子也好,对我父母也不错……”

 

我说:好,我支持你不离婚。你就不要在家天天抱怨,天天喊离婚了。你说他不挣钱,那么他做家务吧带孩子吧,就用钟点工男保姆的工资来计算他对家庭的贡献吧。他爱孩子吧?好,父亲的爱也不是你能替代的。这样算下来,你心平了吧?既然不肯离婚,就请放低对丈夫的期待。

 

即使男人触碰到了所谓的原则性问题,出轨(甚至多次出轨),很多妻子也是不敢不肯离婚的。她们来咨询其实是为了让我支持她们不离婚的决定,因为承认自己对丈夫毫无办法对现代女性是一件很丢脸的事情。做心理咨询不是去教育这些女人“你应该自立自强,你应该争取男女平等,你应该……”我支持你的所有决定,只要你能自圆其说。我要提醒你的就是你们夫妻关系以后可能的走向:信任丧失,貌合神离,除了事务性的交谈再也没有知心话可讲,性生活冷淡(因为你不相信他,甚至恨他怨他);小三可能找上门,甚至大着肚子找上门……你老公有多少财产你清楚吗?有多少是你们夫妻共有的?他不想离婚是外遇不够好还是怕分家产?

 

很多妻子都是婚姻中的弱者,因为她们婚前就是找“比我强的男人”,而强者就有了出轨的底气,加之中国现在的大环境男人能挣钱就是王道,外遇被看成男人“本事”的一部分,被男人们广泛认同。这些的大环境,非我一个小小心理咨询师能怎么样,我的工作就是帮助那些不敢离婚的怨妇排遣一下不良情绪,而她们的老公是不会到场的。




 

银联工作总结

$
0
0
DB2版本 v9.5.0.4
weblogic版本 10.3
aix版本 6.1.0.0
jdk版本  1.6.64
mysql:Server version: 5.5.32-enterprise-commercial-advanced MySQL Enterprise Server
 
Linux上jdk版本:sun:jdk1.6.0_37
 
linux上无法使用jps、jstat等工具:
执行这个命令即可使用:
export PATH=/usr/java/jdk1.6.0_37/bin:$PATH
 
 
weblogic启动脚本:
C:\bea\user_projects\domains\mapsDomain\bin\startWebLogic.cmd
 
 
C:\bea\user_projects\domains\mapsDomain\servers\AdminServer
 
flex编辑工具
C:\Program Files\Adobe\Flex Builder 3 Plug-in
D:\MyEclipse 6.0\eclipse
 
 
flex project 
会自动编译生成*.swf
 
生成完swf文件以后,将*.html和*.swf拷贝到
maps_mng\WebContent\com\cup\maps\portal\jpf\flex
 
 
 
 
<2010-6-4 上午10时14分06秒 CST> <Warning> <JDBC> <BEA-001129> <Received exceptio
n while creating connection for pool "mapswebDS": [jcc][t4][2043][11550][3.50.15
2] 异常 java.net.ConnectException:打开端口 60,000 上服务器 /172.17.252.84 的套
接字时出错,消息为:Connection refused: connect。 ERRORCODE=-4499, SQLSTATE=0800
1>
 
 
 
com.cup.common.dao.util.PersistenceException: Unable to resolve 'jdbc.glmondb'. Resolved 'jdbc'; - nested throwable: (javax.naming.NameNotFoundException: Unable to resolve 'jdbc.glmondb'. Resolved 'jdbc'; remaining name 'glmondb')找不到数据源.
 
原因:没配数据源
URL:jdbc:db2://172.17.252.151:60001/glmondb:currentSchema=GL_MONDB;
Driver Class Name:com.ibm.db2.jcc.DB2Driver
user=gl_monap
portNumber=60001
databaseName=glmondb
serverName=172.17.252.151
Password:glmonap
JNDI Name: jdbc/glmondb
 
 
 
log位置:
D:\bea\user_projects\domains\base_domain\appLog\cups_maps.log
 
 
flex项目改好的swf和jsp文件需要copy到如下目录:
maps_mng\WebContent\com\cup\maps\portal\jpf\monitor\
然后必须要ant build项目maps_mng,然后重启weblogic才可以显示改动地方。
 
 
ant build 脚本位置:
maps_mng\script\build.xml
 
那cvs上传的文件应该是swf还是我改的mxml文件
都上传,swf是编译出来的目标文件,mxml是源文件
 
 
 
公共参数管理代码流程:
 
入口:
CommonParaSyncMainOperBean.operEtl(String paraCom,Integer syncBatNo,Map<String, String> jmsMap)
参数:paraCom 当前类型所包含的主题域
syncBatNo 批次号
jmsMap jms传递的map,包含参数类型和是否强制同步信息
 
syncService.syncPara(Integer.toString(syncBatNo), mainPt.getTblId(), userId, mainTableData);(CommonParaSyncServiceBean.syncPara)做了下面几件事:
1、通过同步批次号、表ID、用户ID、参数数据集合同步参数数据 
2、如果没有任务(para_task),则创建;如果任务和正式表存在,进行任务状态校验
3、如果临时表中有可修改的、显示在页面上的字段,则将这些字段值复制到etlData中
4、ETL数据覆盖到TEMP
5、记载审计日志
6、更新Etl表,设置ETL表的sync_st=1
 
 
本主题域从ETL同步后是否可编辑,即可以在多渠道进行维护部分字段,如果不可以在多渠道维护,那么自动生效
CommonParaSyncMainOperBean.activateSubject
做了几件事:
对需要自动生效的任务:
1、将para_task状态改为“复核通过”
2、syncService.activateTask(task);(CommonParaSyncServiceBean.activateTask)将状态改为5(生效中),设置一些ts和userid,做一些检查;forwardOthers()-》sendQueue()发送jms(类型是:ParaConstants.JMS_SUB_SYS_SYNC-JMS子系统同步)
3、ParameterEventBean.process()接受到这个jms消息开始处理:
sucess = syncExecute.activate(requestId);
参数同步生效方法
1.同步临时表数据至正式表
2.同步成功后,执行同步至其他子系统操作
4、if(sucess==true)并且该主题域是可以自动生效自动关闭的(entry_wizd_in=2),
那么设置任务状态是:"S", "同步成功",然后执行关闭任务:syncService.closeTask(task);(CommonParaSyncServiceBean.closeTask(ParaTask task))
 
 
 
备份一张表(ixf为二进制,del为字符型)
db2 "export to ./backup/ETL_MAMGM_TRANS_CHNL_CD.ixf  of ixf select * from ETL_MAMGM_TRANS_CHNL_CD"
覆盖一张表
db2 "import from /maps/usr/ma_mgmdb/backup/ETL/ETL_MAMGM_TRANS_CHNL_CD.ixf of ixf insert into ETL_MAMGM_TRANS_CHNL_CD"
 
查询schema下所有表
list tables for schema "ZHAOWM"
select * from table fetch first 10 rows only;
select * from table where v_time = timestamp('2008-01-01-00.00.01.000000');
 
 
weblogic配置data sources时提示jdbc找不到。
解决:要把d2cc.jar拷贝到domain\lib下。
 
myeclipse有时会报找不到某一类的错误,但是实际上是能找到的。
解决:clean project
 
修改好的swf文件要放在这里:
\maps_mng\WebContent\com\cup\maps\portal\jpf\monitor\maps_monitor.swf
 
 
取路径的最后文件名并排序
sed 's/.*\///;s/.*\\//' 1  | sort >2
 
用室内CVS上的代码与研究院上的代码比较,按时间降序
 
 
PARA_SUB_AREA_INF
ENTRY_WIZD_IN: 该字段在java中使用。
0: 参数维护页面上有“任务创建”按钮;公参任务自动生效。
1: 参数维护页面上有“任务创建”按钮;公参任务执行在“录入中”状态停住。
2: 参数维护页面上没有“任务创建”按钮,只有“查询”;公参任务自动生效。
无论0还是1,在页面上手工创建任务时,都需要手工经历录入中,待复核,复核通过,同步正式表,同步成功等状态。
BAT_EFF_IN: 0:只读    1:可以新增、修改。  该字段在页面上使用
subject.as中存在该字段,如果0的话,“任务创建”按钮还是不存在的。如果是1的话,“任务创建”按钮会在的。
 
是否同步子系统:
para_tbl_attr:
ma_subsys_bmp 10位位图
每位顺序代表:联机(第一位),批量(第二位 ),通讯,管理,健康,NASA(第6位)
PUB_PARA_CD 该字段在公参同步时使用,当子表的该字段值为空时,该子表不做同步处理;当子表的该字段值为01,即有值时,该子表会同步数据。
 
表是否支持插入,更新,删除,查询
para_tbl_attr:
main_tp 4位   0表示可以做,1表示不可以做
para_tbl_attr的ini_exp字段,是页面初始化使用的字段
具体使用在:TableForm.as中(引用了ParaTable.as的initExp值,该值对应着上述字段)
 
 
字段
para_fld_attr:
readonly_bmp  两位,分别对应“新增/修改” 0表示具有这个权限,即具有新增或修改权限,1代表不具有该权限
Form_in:  一位, 1 表示 在创建参数修改任务中,在创建参数新增任务中,会显示这个字段; 0 表示 页面中不显示这个字段
SHOW_TP:  一位: 0 表示使用默认值,在CommonSyncCommand.copyUpdatableFields()中,会将TBL_MAMGM_PARA_FLD_ATTR表中配置的dft_value值,覆盖到etl表中。
LIST_IN:  1 表示在检索结果中,会显示这个字段
INQ_FLD_IN   1 表示在参数维护页面,检索时显示的条件项。   0表示该字段不在检索条件里。
COMP_TP   00 表示一般单行文字输入框, 01 表示下拉框   11 表示可以输入的下拉框  04 日期  07 时间  06 多行文本框
DRDL_VAL_TBL_NM   下拉框里面选择的内容。对应于TBL_MAMGM_DRDL_CFG表。
fld_data_tp:00:string  01:INT   02:timestamp  03:float  04:BIGDECIMAL
DFT_VALUE:    页面上新建参数任务时,该字段的默认值。
 
 
所有表的字段都会在TBL_MAMGM_PARA_FLD_ATTR中,但是并不是所有SHOW_TP为0的字段,都会被覆盖默认值,必须满足下面条件:
1、FORM_IN=1,该字段在页面上显示
2、READONLY_BMP = 10或00 (第二位是0) ,该字段可以修改
3、SHOW_TP为0
4、tmp表在etl表数据覆盖之前是没有值的。
 
 
任务提示
页面:todolist.mxml
页面初始化:ParameterFlexFacade。countTaskBySubject()。另:那个URL是在renderCountTaskList(taskGroup)方法中定义
点每个主题域链接:初始化中的链接,是取缓存access_inf表中的url。
这个表里的url,对技术参数而言是类似于parameter.jsp?subject=X;---》parameter.mxml-----> <taskView:Start> ----> 它指向Start.mxml---> 在parameter.mxml里有一个初始执行函数init()---》 调用执行 main.as里面的init()函数-----》调用startPage.init()---->调用Start.as里面的init()函数
 
 
进入主题域的参数维护页面:
1、“任务批次状态”、“任务生效状态”--->overview.mxml
"录入中"、“待复核”、“复核通过”、“复核不通过”--->ParameterFlexFacade。countTaskByStatus(),保存在response中的batchStatusCountList属性里
2、“同步正式表成功”、“同步正式表失败”。。。。--->保存在response中的effectStatusCountList属性里。
 “同步子系统成功”、“同步子系统失败”、“部分同步共享内存” 三个按钮是否存在,是在ParameterServiceBean。countTaskByStatus(String subjectId)里面做了判断。因为有些表不需要同步子系统,另外一些表不需要同步共享内存。
3、点诸如“录入中”“待复核”等链接。是在overview.as里initQueryButtons()方法中设置了一个监听器,监听函数就是queryTask(),它又调用了ParameterFlexFacade.queryTaskByStatus()方法。
4、至于随之变化的底部的按钮,是在初始化时就保存好的。在点击诸如“录入中”“待复核”等链接并调用了
queryTask(),这个函数会调用initActionButtons()函数,会将初始化保存好的状态信息与各个按钮对应的显示在底部。
5、底部的按钮的action也是在初始化时就设置好的。由ParameterFlexFacade静态调用TaskStatusHelper.init(),这个方法将每个状态对应有多少动作按钮都设置好。会保存在response的statusMap属性里。
6、response中的actionMap属性保存的是涉及流程的操作类型,供之后处理,比如:删除,提交,复核通过,复核不通过等等。
7、switchPage在flex/ParamNew/main.as中定义,函数switchPage(event : MapsEvent)中执行,参数只有三种:OVERVIEW、PARA_QUERY、PARA_EDIT
8、“检索”按钮
9、“创建参数修改任务”和“创建参数删除任务”调用ParameterFlexFacade.queryProdPara(),查询主表和子表相关内容。
10、“创建参数新增任务”不需要查询记录。
11、任务状态“录入中”、“待复核”、“复核通过”等链接下面的按钮如“任务提交”、“任务查看”、“任务信息”、“任务修改”等是保存在response的statusMap里面,
且在ParameterFlexFacade.getGrantedActionMap()函数里面设置。
查询按钮是所有任务状态链接下都有的按钮。
 
 
"创建参数新增任务"\"创建参数修改任务"\"创建参数删除任务"按钮在Query.mxml页面中,点击按钮的触发的函数分别是gotoCreateInsert()、gotoCreateUpdate()、gotoCreateDelete()。
对于修改任务gotoCreateUpdate(在Query.as中):
1、校验是否选中一条记录:getSelectedRecId
2、执行checkOper("U"),调用checkParaOperatable(mainTable.tblId, getSelectedRecId())
3、执行回调函数checkParaOperatableHandler -》 getSwitchEvent("U",recid,eventid)-> ParamNew/main.as中定义的事件switchPage,traget=ParaConstants.PAGE_PARA_FORM
4、mainFrame.selectedIndex = 2;paraEdit.initParaPage(event.data);意思是页面展示Edit.mxml,并且执行Edit.as的initParaPage函数,函数参数是ParaUtil种定义的switchEvent的data
参数中包括target=“PARA_EDIT” type=“U”  recId eventId这四个参数,
5、该initParaPage函数首先执行ParameterFlexFacade.queryProdPara()
6、执行回调函数queryParaHandler() -> shown() 多表的要加上多表 -》 showForm();表数据引入 -> reloadButtons()置入按钮
 
 
 
 
 
 
获取一开始的处理操作,即参数管理中每个表的初始进入页面中“查询”、“任务创建”。
这两个按钮是否存在的判断在:
ParameterFlexFacade.blankGrantedActionList()
1、该用户是否有这两个按钮的权限
2、该主题域是否具有可以查询,可以任务创建的功能。(TBL_MAMGM_PARA_SUB_AREA_INF.ENTRY_WIZD_IN)
3、点“任务创建”后,“创建参数新增任务”“创建参数修改任务”“创建参数删除任务”“查看参数”是由TBL_MAMGM_PARA_TBL_ATTR.MAIN_TP字段控制。位图1111表示上述四个按钮全都存在,0000表示上述四个按钮全不存在。
 
 
 
tmp表数据怎么来的?
1、从etl表读数据到一个rowset中
2、增加一些时间和人的信息
3、给特殊情况的字段赋默认值
 
 
 
商户路由表为什么单拿出来?
商户路由的etl表与tmp表表名不一致。tmp表和tbl表的表名一致。公参同步是将ETL_MAMGM_SETTLE_TRE_MCHNT_INF表(财税库银商户表,该表从商户平台来,且由商户平台发起同步命令)
的一部分内容同步到tbl_mamgm_mchnt_rout_det,另一部分内容同步到tbl_mamgm_mchnt_rout_inf(该表是主表)。
这两个表公参时特殊处理,不走优化后的公参代码。
 
 
卡号转换表没有etl表?
不是所有tmp,tbl表都有对应的etl表,etl是给公参同步时,外系统用的
 
 
公参同步的web services接口在: 
BatchSynchResultNotifyImpl。notify()
这个方法调用EJB,EJB的名字是CommonParaJmsService,它又对应了CommonParaJmsServiceBean。sendJmsRequester()来处理
 
 
查看目录下文件或文件夹得大小,并按照从大到小排序
du -sg * |sort -nr
 
 
在VI中,将字符串str1替换成str2
:g/str1/s//str2/g
 
aix中vi一文件,删除^M符号,执行如下命令:
:%s/^V^M//
:%s/^M//
^V和^M指的是Ctrl+V和Ctrl+M
 
 
公参同步任务是如何执行的?
商户平台使用web services访问接口BatchSynchResultNotifyService,而这个类BatchSynchResultNotifyImpl又用ejb的形式调用了local接口CommonParaJmsService。并由CommonParaJmsServiceBean.sendJmsRequester()
通过CommonParaSyncRequester给JMS服务队列发送消息,MsgProperty是"common_para_sync"。
 
CommonParaSyncMDB 通过JMS消息队列 接收到这个消息后,把ObjectMessage转发给CommonParaSyncEventBean,由ObjectMessage中的MsgProperty决定,把ObjectMessage中包含的两个参数,一是参数类型,一是批次号。
发给CommonParaSyncMainOperBean。operEtl来处理
 
1、正在同步的公参批次,如果由另外一页面发起强制同步的话,很容易报911,表锁问题;原因在改ETL表的状态为1时与MERGE语句使用了相同的表。
2、公参成功后,查看的是紧接着的同参数类型的一个批次是否成功,如果是待同步,则执行,如果是成功的就不会往下做了。隔着的那些待同步批次不会执行的。
 
公共参数管理页面对应的jsp:
/com/cup/maps/portal/jpf/flex/CommonParaQuery.jsp
“重新同步”命令调用ParameterFlexFacade.reSyncCommonPara(String batNo,String paraTp,boolean force)函数。
该函数调用 CommonParaJmsService.sendJmsRequesterForce()  发送jms消息,(跟商户平台的公参同步类似,不过它走了另外一个函数sendJmsRequester)
 
 
“重新同步”与“强制同步”均要走同步正式表和生效接口,它们的不同在于:
1、“强制同步”无视 还小的批次号,可以绕过之前失败的批次做同步。
2、如果该批次同步成功,公参任务表的最终状态会改成“3-强制同步成功”
 
 
研究院-电话支付-CVS
:pserver:leishen@172.17.238.150:2401/cvsout
Module:tams
 
checkout某一标签tag的cvs文件:
cvs co -r branch_tipsp_codemerge_20120530 isvr_mgm
查看标签语句
cvs status -v
 
 
 
ant在编译指定文件夹中的java类时,会将该java类引用到的所有java类同时编译。
在打war时就可以把引用到的java生成的class文件一起打入war包中。
 
 
db2在某一列创建索引时会让你选择该列是否设置成unique。
 
 
 
对于显示的查询结果,如果要有水平的滚动条,需要修改这个dataGrid的属性,
增加一个:horizontalScrollPolicy="auto" 
 
 
商户同步的参数中,也就下面表需要编辑。其它的都是自动生效的
卡bin 01010601  TBL_MAMGM_BIN+TBL_MAMGM_BIN_REGION 0000000000
机构信息(成员机构静态信息表)  01010101 TBL_MAMGM_INS_STATIC_INF 0000000000
商户类型表 01071101 TBL_MAMGM_MCHNT_TP 0000000000
交易代码表 01071401 TBL_MAMGM_TRANS_ID 0100000000
 
 
行业机构静态信息表:服务提供机构、渠道接入机构、行业商户
industry_ins_static_inf 
成员机构信息表:多渠道平台、银联总分公司、转接机构、发卡机构、收单机构
ins_static_inf
商户静态信息表:直连终端商户、渠道接入机构商户、服务提供机构商户、行业商户、虚拟商户
mchnt_static_inf
终端静态信息表:直连POS、ATM、电话终端、各种虚拟终端
term_static_inf
 
 
对于“参数同步”这个交易,tbl_mamgm_para_tbl_attr中配置了两条记录如下:
TBL_CDTBL_NMTBL_NM_CNMA_SUBSYS_BMPSUB_CDENTRY_WIZD_SEQ
0803010208030102参数同步到数据库(返回)00010000000803011
0803010108030101参数同步到数据库(发送)11000000000803010
OnlCommon.getSTMGBySubCd(subjectId,subsysId);
该函数取ENTRY_WIZD_SEQ=0的记录,由subsysId(是BAT、ONL)来得到联机或者批量的默认节点
OnlCommon.getRTMG(subjectId);
该函数取管理的默认节点(节点的意思是tbl_maps_gfs_deploy_inf这张表的一条记录,包括ip,port,openid等信息)
 
 
 
批量应用重启:
taskcom stop all
 停应用
 MPubTask &
 启动
 
 
管理数据库停止后,再开启,不影响管理应用继续使用,管理应用无需重启即可。
jdbc:db2://172.17.252.84:60032/mamgmdb
是ma_onldb/ma_onl用户建的。端口60032是这个用户在/etc/services文件设置好的。
ma_onldb@/etc>cat /etc/services |grep 60032 
DB2_ma_onldb    60032/tcp
 
 
 
 
多渠道管理有5个web service 接口,页面上可以测试。CommonParaJmsServiceBean类是第一层处理接口:
1、公参管理
http://172.17.252.85:4866/maps_service/BatchSynchResultNotifyService?wsdl
http://172.17.252.63:7001/csb/shcenter/BillDomain/MultiAcquiringSystem/ParamSyncNotiry/ParamSyncNotiryProxy?wsdl
 
http://172.17.248.158:40423/maps_service/BatchSynchResultNotifyService?wsdl
http://172.17.248.40:4867/maps_service/BatchSynchResultNotifyService?wsdl
 
 
2、改变交易规则状态交易(changeFilterAppInf)
改变指定商户的交易状态(changeMchntTransSt)
改变指定终端的交易状态(changeTermTransSt)
根据任务事件号查询的事件状态(queryTransSt)
http://172.17.252.85:4866/maps_service/TransStateAndRuleSwtService
 
3、行业机构状态查询
http://172.17.248.74:8888/MapsServicePortal/IndustryInsStateActionService?wsdl
 
4、bps接口
http://172.17.248.74:8888/MapsServicePortal/BpsServiceImplService?wsdl
对应csb地址:
http://172.17.252.63:7001/csb/shcenter/BillDomain/MultiAcquiringSystem/BpsServiceImplService/BpsServiceImplServiceProxy?wsdl
 
5、多渠道交易状态查询接口(过滤应用信息表状态、商户状态、终端状态查询) 未上线
http://172.17.248.74:8888/MapsServicePortal/TransStateActionService?wsdl
 
 
6、供mtqj调用接口
http://172.17.248.74:11000/MapsServicePortal/MjcCallActionService?wsdl
 
7、手工交易
http://172.17.248.74:11000/MapsServicePortal/MjcCallActionService?wsdl
 
 
MTQJ的webservice地址
http://172.17.252.88:10000/mjc/MtqWebService?wsdl
 
 
 
行综平台管理系统目前有1个web service 接口
csb地址:http://172.17.252.63:7001/csb/shcenter/BillDomain/IntegratedServicePlatformForIndustry/IsvrBatchParaSynchNotifyService/IsvrBatchParaSynchNotifyServiceProxy
对应的行综环境:http://172.17.248.188:7004/IsvrServicePortal/BatchParaSynchNotifyService?wsdl
 
 
csb地址:
http://172.17.252.63:7001/sbconsole
用户名/密码:weblogic/weblogic
多渠道在Projects->csb->shcenter->MultiAcquiringSystem
行综在Projects->csb->shcenter->IntegratedServicePlatformForIndustry
 
 
 
通讯重启:
1、hgcom1/nasa/bin/reload_cfg 100 300 0 shutdown
2、mtqshutdown
3、mtqstartup
4、hgcom1/nasa/bin/nasad
5、shmadmin
   5.1--- h
   5.2--- create COMALL
   5.3--- q
6、reload_cfg 100 300 0 start
7、ml
8、ps -ef |grep $USER
 
 
 
用户管理平台(权限相关):
系统权限导入:只会更新已有数据+插入新增数据。不会删除系统已有数据。
 
 
EJB3里面
@TransactionAttribute(TransactionAttributeType.NEVER)的函数中,调用了
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)的函数,子函数的事务不起作用,无法回滚
 
 
bytes[]类型的参数同步后的数据与etl表原始数据不一致,最后部分的00 00 00内容被截断了,需要修复。
修改:SqlUtil.java下面这行
fieldValue = StringUtils.defaultString(new String(rowset.getBytes(fieldCount))); //byte[]的类型特殊处理
 
 
管理系统使用DBPM
自己开发一应用程序,用modifyPasswd.sh执行,读取config.properties配置的DBPM服务器地址,通过socket的方式获得数据库密码。
然后调用调用WLST工具类,修改Domain中的JDBC数据源中设置的密码。
然后启动domain。
 
下面5个交易由之前的同步交易,改成异步交易,发送流程是:首先管理发MTQ消息给联机1,联机1通过通讯发给CUPS,cups做完后会返回结果给联机,但是由于通讯是负载均衡的,所以有可能发给了联机2,联机2通过异步邮箱134, 发送给管理,管理得到134邮箱的内容后,会更新联机交易日志表(manage_trans_log),此时管理端仍然在轮询联机日志表,找到状态是1(收到事件请求报文),2(已经事件处理完毕),99(出错)的对应event_id记录后,返回前台成功或出错信息,如果超过60秒,仍然没有找到,那么返回前台超时标志。
签到:多渠道向cups签到,激活状态。
签退:多渠道向cups签退。
申请重置密钥:通知cups,让cups给成员机构发送密钥。
重置密钥下发:通知行业机构重置密钥
线路测试:通知cups,让cups给成员/行业机构发送测试交易。
 
终端签到:
先去查联机的终端静态表,如果状态为1-冻结,直接报错,如果状态为0,接着校验交易位图等,最后更新联机终端动态表状态为0-开启。
终端状态启用冻结
只更新联机的终端静态表
 
 
 
查找主题域/表对应的下拉框的内容:
select t5.sub_cd,t5.SUB_NM_CN,t4.TBL_CD,t4.TBL_NM_CN,t1.* 
from TBL_MAMGM_DRDL_ITEM_DEF t1,TBL_MAMGM_DRDL_CFG t2,
tbl_mamgm_para_fld_attr t3,tbl_mamgm_para_tbl_attr t4,TBL_MAMGM_PARA_SUB_AREA_INF t5
where t1.DRDL_ID = t2.DRDL_ID and t2.DRDL_NM = t3.DRDL_VAL_TBL_NM
and t3.tbl_cd = t4.TBL_Cd and t4.SUB_CD = t5.SUB_CD
and t4.TBL_CD = '07010301'
and t5.SUB_CD = '070103';
 
公参同步用到的一系列表:
select * from TBL_MAMGM_PARA_SYNC_TASK;
select * from TBL_MAMGM_PARA_TASK;
select * from TBL_MAMGM_ACCESS_INF;
select * from TBL_MAMGM_PARA_SUB_AREA_INF;
select * from TBL_MAMGM_PARA_TBL_ATTR;
select * from TBL_MAMGM_PARA_FLD_ATTR;
 
 
 
取得当前时间:
select current timestamp from (values 1);
取得sequence的下一取值:(两种方法)
select nextval for sqn_mamgm_ei from (values 1);
select nextval for sqn_mamgm_ei from sysibm.dual;
values nextval for sqn_mamgm_ei;
设置管理数据库的REC_ID对应的sequence下一取值为108000003
alter sequence ma_mgmdb.sqn_mamgm_ri restart with 8000003
 
CHAR型转INTEGER
select CAST(INS_ID_CD AS INTEGER) max from etl_mamgm_ins_static_inf;
 
 
TBL_MAMGM_PARA_FLD_ATTR表中配置的字段如果少于TBL表中的字段,在创建新增参数任务、创建修改参数任务时都会报错。
具体表现为:
1、关闭记录时tmp记录删不掉。
2、修改参数任务时也没显示的字段值不对应。
 
 
下拉框配置表TBL_MAMGM_DRDL_CFG:
DRDL_TP: 2 表示用sql执行的结果,进入页面时,读数据库一次下拉框的代码
DRDL_REMARK:sql语句
SHOW_KEY_IN: 0 表示格式像“代码中文名称”    1 表示格式像“代码-代码中文名称”
DRDL_SORT_TP: 1 
 
 
 
JMS server参数配置:
Messages Maximum: -1。 JMS消息队列最大值。设为-1表示没有限制,容易引起内存不足。
Maximum Message Size:2147483647  The maximum number of bytes allowed in individual messages on this JMS server
 
 
虚拟终端确定信息表TBL_MAMGM_VIRTUAL_TERM_DET的ETL表比TBL表多一个字段CUP_BRANCH_INS_ID_CD,此时无论公参优化前后,该表都可以同步成功。
但是如果公参同步失败,需要页面上人工操作,走参数维护流程,那么将出错,
出错情况和上面所讲的TBL_MAMGM_PARA_FLD_ATTR表中配置的字段如果少于TBL表中的字段情况相同。
 
 
目前多渠道代码的问题缺陷错误:
1、TBL_MAMGM_DRDL_ITEM_DEF.drdl_id=9254名称写错:“本平手工台录入”
2、商户黑名单etl_MAMGM_MCHNT_BLKBILL没有sync_bat_no字段,无法做公参同步,报错。好在这个表联机批量都不用。
3、中奖奖项限制配置表TBL_MAMGM_PRIZE_LIMIT_CFG该表没有ETL表,但是该表是子表且pub_para_cd值为空,该表不做同步处理,公参同步时不报错。
4、子表被删除了,在页面中通过主表查询子表内容还是能看到。
5、下拉框表TBL_MAMGM_DRDL_CFG中,WINUSEFLG有2个。
 
 
java的substring问题
String ss = "1234567890123456";
System.out.println(ss.substring(1,2));//2
System.out.println(ss.substring(2,4));//34
System.out.println(ss.substring(5,8));//678
 
 
 
在参数删除时,不对字段进行校验
ParameterFlexFacade.checkParaByValidators()根据Validator进行校验
 
 
新建“链路信息表”记录时,输入“链路编号”字段,只有两位,保存到TMP表以后,该字段变成13位,原因:
TBL_MAMGM_PARA_TBL_ATTR配置表时,BEFORE_INSERT_EXP字段配置了处理代码,如下:
import com.cup.maps.parameter.util.*;
 String s=map.get("LINE_NO"); if (s.length()==2) 
{ map.put("LINE_NO",map.get("ACCESS_INS_ID_CD")+s); 
ParaExpressions.checkExistRecordForTask("01100701", map);  }
此外该表在TBL_MAMGM_PARA_VFY中有很多校验信息,具体有15条,列出如下:
无效的接入系统标识!
链路编号C开头本方监听端口应为0
链路编号A开头本方监听端口不为0
链路编号C开头对方监听端口不为0
链路编号A开头对方监听端口应为0
本方监听端口输入错误!
对方监听端口输入错误!
登录用户不能为空
登录密码不能为空
短信窗口大小不能为空
短信源发序列号不能为空
短信接入角色不能为空
检测时间间隔不能为空
单条链路超时时间不能为空
接入模式 0001 /0006,才能选支持
 
 
在管理应用上部mtq时,除了常规参数配置外,还要保证/glb/mtq/etc/mtq.ini文件中
SHMKEY_MB和MSGKEY这两个参数,在应用主机上与其他用户的mtq配置的不重复。
 
 
用winrar软件更新jar文件中的一个class,压缩进去,生成的新的jar文件,仍然可以像之前一样引用,且更新的地方也会生效。
 
假如程序A.java引用了XX.JAR包中的B.java,且B.java又引用了XXX.JAR中的内容。那么:
1、把B.java打成XX.jar包的操作,不应该将XXX.JAR打入XX.JAR中
2、在javac A.java时,classpath应该只包括XX.jar和.
3、在执行java A.java时,应该将XX.JAR和XXX.jar均包进classpath中。
例子Testjar.java中引用了tools.jar的XmlRead类,而XmlRead类又引用了dom4j-1.5-rc1.jar包的内容,下面是正确编译和执行的语句:
D:\>javac -classpath "d:/tools.jar" Testjar.java
D:\>java -classpath ".;d:/tools.jar;D:/workspace/TOOLS/lib/dom4j-1.5-rc1.jar" Testjar
 
 
 
下面两个sql,第一个取全部字段,走全表扫描,第二个sql由于取主键,走索引。两边取出的值不一定一样。
select * from ETL_MAMGM_TERM_STATIC_INF where sync_bat_no = 999 fetch first 1000 rows only with ur;
select term_id,mchnt_cd,sync_bat_no from ETL_MAMGM_TERM_STATIC_INF where sync_bat_no = 999 fetch first 1000 rows only with ur;
 
 
 
商户折扣信息表,中奖等级表,中奖基本表等按照规划是营销平台通过公参平台公参同步到多渠道,但是营销平台没有这些接口,
多渠道本身也没有用这些表。
 
 
商户黑名单和卡号黑名单这两张表是在商户维护的吗?
答:是风险平台维护。但现在他们还没有作
 
mtq.ini中有:
BEGIN GROUP
31  172.17.252.87  8113  20  S
END   GROUP
 
mtq重启以后,端口8113会被监听
netstat -an|grep 8113
查看当前用户的进程
ps -ef |grep mtq|grep $USER
BEGIN GROUP里面的配置的S要大写。
0   172.17.248.57  8100  20  S这个0的行是什么含义?
异步邮箱组连接数及发送报文个数:
mtqmng list或者ml(需要创建别名alias ml="mtqmng list")
 
 
su - iisp1onl
iisp1onl@/iisp/usr/iisp1onl>db2 connect to ISMGMDB user iisp1db using iisp1db
db2 reorg table ma_mgmdb.TBL_MAMGM_MSG_FMT_CONV_MTO
 
 
多渠道管理回归数据库82
telnet 172.17.252.82
su - ma_mgmdb
db2 list db directory
/maps/usr/ma_mgmdb>db2 connect to GMAMGMDB user ma_mgmdb using ma_mgmdb
db2 reorg table ma_mgmdb.etl_mamgm_mchnt_static_inf
db2 reorg table ma_mgmdb.tmp_mamgm_mchnt_static_inf
db2 reorg table ma_mgmdb.tbl_mamgm_mchnt_static_inf
 
 
查询db2错误代码
db2 ? sql-30082|more
 
 
 
82联机回归数据库,发生668错误
maps/usr/ma_mgmdb>db2 connect to GMAONLDB user ma_onldb using ma_onldb
db2 runstats on table ma_mgmdb.TBL_MAMGM_AUDIT_LOG2
/maps/usr/ma_mgmdb>db2 reorg table TBL_MAONL_MCHNT_STATIC_INF
 
 
 
获取前台flex发送到后台的值
OnlCommon.getSentFlied(String subjectId, Map<String, String> map) 
根据主题域ID取到参数表对象列表
OnlCommon.java     List<ParaTable> getParaTable(String subjectId)
 
 
过滤应用信息的下拉内容来源于业务参数(fml域转换配置信息表),
 
 
成员机构静态信息表在页面上做“创建参数修改任务”后,复核通过,会在同步正式表成功那里卡住,
然后在“参数刷新-参数同步到共享内存”页面做了参数刷新以后,回到参数管理页面,该参数已在同步成功栏内。
刷新共享内存及更新para_task状态的地方在:SyncExecuteBean.refreshSchemeStatus(Map<String, String> map)
这里面maps的内容是子系统subsysCd和内存编号zoneId
这个函数做了两件事:
1、更新TBL_MAMGM_PARA_TASK_SYNCSHM_STATUS状态为4-成功
2、更新TBL_MAMGM_PARA_TASK为S-同步成功或者A-部分同步到共享内存成功
 
 
同步子系统的地方:
ParaSyncServiceBean。sendMsg(ParaTask batch, Map<String, String> map)
需要的内容包括:batch里面的eventid,map里面的子系统名称、多个表名
 
 
db2取当前时间
SELECT current date FROM SYSIBM.DUAL;--取得当前年月日
SELECT current time FROM SYSIBM.DUAL;--取得当前时分秒
SELECT current timestamp FROM SYSIBM.DUAL;--取得当前年月日时分秒
select current timestamp,microsecond(current timestamp) from SYSIBM.DUAL;
select 1,to_char(current timestamp,'yyyymmdd') from sysibm.dual;--日期格式
 
axis,unix取当前时间
dateWed Mar  9 11:22:07 GMT+08:00 2011
date +%Y2011
date +%y11
date +%m03
date +%M22
date +%d09
date +%D03/09/11
date +%S07
date +%s1299669809
 
 
错误:
DB2 SQL error: SQLCODE: -20154, SQLSTATE: 23513, SQLERRMC: MA_MGMDB.VIW_MAMGM_AUDIT_LOG;2
sqlcode-20154原因:指定的视图包含一个UNION ALL查询
1、不符合任何基础基表的检查约束。
2、满足所有多个基础基表检查约束。
解释:视图VIW_MAMGM_AUDIT_LOG是由TBL_MAMGM_AUDIT_LOG1和TBL_MAMGM_AUDIT_LOG2这两个表组成的。在这两张表的create时,
没有增加CHECK (SUBMIT_MON BETWEEN 1 and 6)和 CHECK (SUBMIT_MON BETWEEN 7 and 12)语句,导致在insert viw时,db2不知道要插入哪张表。
 
 
 
db2 修改字段属性
alter table tmp_maps_gfs_fmt_grp alter trantype set data type char(6);
select current schema from sysibm.dual
db2 values current schema
 
菜单的顺序是跟access_inf表的event_id相关的。只有event_id相同的情况下,才看access_cd.
 
unix vi命令
01 G   移至最后一行行首
02 nG   移至第n行行首
03 n+   下移n行,行首
04 n-   上移n行,行首
05 n$   下移n行(1表示本行),行尾
06 0   所在行行首
07 $   所在行行尾
08 ^   所在行首字母
09 h,j,k,l 左移,下移,上移,右移
10 H    当前屏幕首行行首
11 M   屏幕显示文件的中间行行首
12 L   当前屏幕最底行行首 
 
 
 
管理系统里面不常用的两个sequence:
TBL_MAMGM_FLOW_CD的主键Sequence
public static final String TBL_MAMGM_FLOW_CD_KEY="sqn_mamgm_fck";
审计日志sequence
public static final String AUDITLOG_SEQUENCE = "sqn_mamgm_aui";
 
 
 
db2中select语句最多可以选择1012个字段,超过以后就会报sqlcode=840的错误。说选择的列太多。
ultraedit每行最多显示4096个字符
感觉db2的sql长度没啥限制一个18k的select语句也是可以被执行的。
如果select出来一个字段没有值,那么rs.getString()取出来的值是空:"",并不是null
 
我们的页面根本没有对用户的权限做限制,比如:
在url上输入:https://172.17.252.85:8889/maps/com/cup/maps/portal/jpf/flex/cacheRefresh.jsp
然后再登录的地方输入分公司的用户名和密码
页面仍然可以显示,并且刷新的功能也能完成。
 
查看aix的版本
oslevel
 
 
将System.out.println输出到文件中。
OutputStream os = new FileOutputStream("d:/output.txt");
PrintStream p = new PrintStream(os);
System.setOut(p);
System.out.println("ee");
 
从jar文件中读取资源文件
//方法一,直接读取该文件的每行内容
BufferedReader br1 = new BufferedReader(new InputStreamReader(
    ((ReadXmlFileFromJar.this.getClass().getResourceAsStream("1.txt")))));
String s1;
while((s1=br1.readLine())!=null)
System.out.println(s1);
 
 
//方法二,读取xml文件内容后组装成document对象
BufferedReader br = new BufferedReader(
new InputStreamReader(((ReadXmlFileFromJar.this.getClass()
.getResourceAsStream("1.xml")))));
String s;
while ((s = br.readLine()) != null)
System.out.println(s);
 
SAXReader saxReader = new SAXReader();
Document document;
try {
document = saxReader.read(ReadXmlFileFromJar.this.getClass()
.getResourceAsStream("1.txt"));
Element incomingForm = document.getRootElement();
String ss = document.asXML().toString();
System.out.println("ss=" + ss);
} catch (DocumentException e) {
e.printStackTrace();
}
 
 
从jar中读取资源文件
1、方法一
URL fileURL=this.getClass().getResource("/resource/res.txt");   
System.out.println(fileURL.getFile());  //file:/C:/ResourceJar.jar!/resource/res.txt
 
2、方法二
InputStream is=this.getClass().getResourceAsStream("/resource/res.txt");   
        BufferedReader br=new BufferedReader(new InputStreamReader(is));  
        String s="";  
        while((s=br.readLine())!=null)  
            System.out.println(s);  
 
 
参数查询角色功能代码 :1001999014
是指参数维护页面上那个查询按钮
 
 
下面这条sql的执行计划是:
1、首先执行4)中的子查询,IXSCAN
2、然后执行3)查询表TBL_MAPS_GFS_TASK,TBSCAN
3、对1、2的查询结果进行HSJOIN,从而获得了行号ROWNO_以及t.*
4、对查询的结果进行排序bmqid
5、选取前40行记录
 
1)SELECT ROW_NUMBER() OVER() AS ROWNO_, t.*                                             
2)FROM TBL_MAPS_GFS_TASK t                                                              
3)WHERE OPER_IN != 'd'                                                                  
4)AND (node_id in  (select NODE_ID from TBL_MAPS_GFS_DEPLOY_INF where SUBSYS_CD='BAT')) 
5)order by bmqid                                                                        
6)FETCH FIRST 40 ROWS ONLY
 
下面这条sql不同的地方就是第4)行,但是db2的执行计划就变成了:
因为node_id是索引查询,3)、4)、5)条件一起执行,IXSCAN,
然后再获得排完序的行号ROWNO_
 
1)SELECT ROW_NUMBER() OVER() AS ROWNO_, t.* 
2)FROM TBL_MAPS_GFS_TASK t 
3)WHERE OPER_IN != 'd'
4)AND (node_id in  ('21','22')) 
5)order by bmqid 
6)FETCH FIRST 40 ROWS ONLY
 
 
DB2存储主键的地方
select * from SYSIBM.SYSKEYCOLUSE;
select * fROM sysibm.SYSINDEXES;--存储索引
select * from sysibm.syscolumns;--存储字段
select * from sysibm.systables;
select * from SYSIBM.SYSTABLESPACES;
select * from sysibm.sysschemata;
 
 
 
java中读取下拉框内容:
TransMonitorFacade.getDrdp(String name, false)
 
 
数据库中DECIMAL (8,2)
表示的意思是:
小数点前的位数最多是6位,小数点后的位数一定是2位,不够的话补0
 
 
appCfg/config.properties文件中的provider_url是给管理系统自己的webservice用的EJB接口
 
 
 
 
 
ajax发送到后台的字符编码与form提交使用的字符编码不同
正确的代码:
 
javascript:GET方式
var phone = document.getElementById("phone").value;
var url = "<%=request.getContextPath()%>/upload?phone=" + (phone);
url = encodeURI(url);
req.open("GET", url, true);
req.onreadystatechange = updatePage;
req.send(null);
 
java:
String phone = request.getParameter("phone");
phone = new String(phone.getBytes( "ISO-8859-1"), "UTF-8");
//设置响应内容类别  
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
//传回浏览器
response.getWriter().println("i know your phonedddd d的上少时诵诗书 : "+phone);
//不需再forward
 
 
javascript:POST方式
var xmlString = document.getElementById("phone").value;
xmlString = encodeURI(xmlString);
var url = "<%=request.getContextPath()%>/uploadxml";
req.open("POST", url, true);
// Tell the server you're sending it XML
req.setRequestHeader("Content-Type", "text/xml");
// Set up a function for the server to run when it's done
req.onreadystatechange = confirmUpdate;
// Send the request
req.send(xmlString);
 
java端后台,接受XML格式 + POST方式,乱码解决:
StringBuffer xml = new StringBuffer();
String line = null;
BufferedReader  reader = request.getReader();
while((line=reader.readLine())!=null)
xml.append(line);
String temp = xml.toString();
temp =  java.net.URLDecoder.decode(temp, "UTF-8");
//设置响应内容类别  
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
//传回浏览器
response.getWriter().println("i know your phonedddd d的上少时诵诗书 : "+temp);
 
 
 
浏览器访问链接上有中文时,如http://localhost/import/dbpatch?ss=aaa东东东东dd,浏览器会转成如下链接:
http://localhost/import/dbpatch?ss=aaa%B6%AB%B6%AB%B6%AB%B6%ABdd
doGet方法中有两种方式获取:
1、String query = request.getQueryString();
System.out.println("query="+query);//ss=aaa%B6%AB%B6%AB%B6%AB%B6%ABdd
query = java.net.URLDecoder.decode(query, "gbk");//直接访问的servlet
System.out.println("query2="+query);//ss=aaa东东东东dd
2、String ss = new String(request.getParameter("ss").getBytes("iso8859-1"),"gbk");//说明requst.getParameter方法做了转码decode
System.out.println("@@@@@@@ss="+ss);
 
 
DB2
如果一个字段设置为NOT NULL 但是没有默认值。比如如下语句:
CREATE 
    TABLE a 
    ( 
        MSG_SPEC_TP CHARACTER(4) DEFAULT ' ' NOT NULL, 
        INS_ID_CD_CAPTURE_MD CHARACTER(1) NOT NULL, 
        INS_ID_CD_CAPTURE_EXPRESS VARCHAR(152) NOT NULL,
        RID CHARACTER(10) DEFAULT ' ' NOT NULL,
        CONSTRAINT TIX_MAMGM_MIT_PK PRIMARY KEY (MSG_SPEC_TP) 
    );
那么在INSERT记录的时候,就必须带上该列,
甚至可以在该列的VALUES里面填'',当然不能不填或者填个NULL
 
正确:INSERT INTO a(MSG_SPEC_TP,INS_ID_CD_CAPTURE_MD,INS_ID_CD_CAPTURE_EXPRESS)VALUES('5555','','');
(注:执行上述语句后,VARCHAR类型的字段值是'',而CHAR类型的字段值是' ',多一个空格,是DB2数据库自动添加的值。)
错误:INSERT INTO a(MSG_SPEC_TP,INS_ID_CD_CAPTURE_MD,INS_ID_CD_CAPTURE_EXPRESS)VALUES('5555',,'');
错误:INSERT INTO a(MSG_SPEC_TP,INS_ID_CD_CAPTURE_MD,INS_ID_CD_CAPTURE_EXPRESS)VALUES('5555',null,'');
错误:INSERT INTO a(MSG_SPEC_TP,INS_ID_CD_CAPTURE_MD)VALUES('5555','');
错误:INSERT INTO a(MSG_SPEC_TP,INS_ID_CD_CAPTURE_EXPRESS)VALUES('5555','');
 
如果这个列有默认值,那么INSERT语句就可以不出现该字段,比如上述的正确语句中就没有RID字段。
 
 
 
在FLD_ATTR中字段名配置为小写,不影响其在页面上进行录入,但是查询的时候字段值会显示不出来。
 
从cache中读取下拉框的值
List<Map<String, String>> ParameterFlexFacade.getDropdownListByFld(String fldCd)
 
 
TBL表中重复的EVENT_ID也没有关系
同步正式表的操作:ParaSyncServiceBean.activate。从batch取出的event_id是从TMP表中取得记录,然后根据记录的主键值
更新TBL中的记录。
 
 
appCfg/securityClient.properties文件详解:
defaultSSOUrl=http://172.17.249.56:6008
##maps ip
172.17.252.85=http://172.17.248.56:6008
##F5 ip
172.17.248.31=https://172.17.248.31:1215
Remote_NewSecurityEJB_Url=t3://172.17.248.56:6008
##maps system str assigned by sso
SysIdStr=6018724E9A708E13CB0156465E8E8384
isPortalLogin=false
loginClassName=com.cup.portal.security.utils.CupPortalSecurityUtil
 
 
如果Remote_NewSecurityEJB_Url这个配错了的话,重启后登陆会报如下错误:
Caused by: java.net.UnknownHostException: 172.17.258.56
        at java.net.InetAddress.getAllByName0(InetAddress.java:1275)
        at java.net.InetAddress.getAllByName(InetAddress.java:1197)
        at java.net.InetAddress.getAllByName(InetAddress.java:1119)
        at weblogic.rjvm.RJVMFinder.getDnsEntries(RJVMFinder.java:409)
        at weblogic.rjvm.RJVMFinder.findOrCreate(RJVMFinder.java:180)
        at weblogic.rjvm.ServerURL.findOrCreateRJVM(ServerURL.java:153)
        at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:352)
        ... 24 more
com.cup.newSecurity.exception.LdapBaseException: 
        at com.cup.securityClient.client.service.UserService.getLoginUserAndPrivileges(UserService.java:95)
        at com.cup.maps.portal.common.filter.SessionFilter.doFilter(SessionFilter.java:66)
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
        at com.cup.maps.portal.common.filter.SetCharacterEncoding.doFilter(SetCharacterEncoding.java:64)
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
        at edu.yale.its.tp.cas.client.filter.CASFilter.doFilter(CASFilter.java:221)
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3496)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(Unknown Source)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
 
 
 
 
java文件中:
String s = "工作就";
使用各种编码进行javac,语句如:javac -encoding GBK TestString.java
然后class文件中这三个汉字如何显示。
 
iso8859-1
String s = "\271\244\327\367\276\315";
默认编码
String s = "\u5DE5\u4F5C\u5C31";
GBK
String s = "\u5DE5\u4F5C\u5C31";
UTF-8
String s = "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD";
 
编成class文件以后,这个字符串的长度,就是用length()函数得到的长度就比较好理解了。
用iso8859-1编码进行编译后执行length()函数得到的长度是6,gbk编码进行编译的长度是3,utf-8编码进行编译的长度也是6。
 
注:
java中byte使用1个字节(8 bit)表示,char使用2个字节(16bit位)来表示。
 
 
还可以按某种编码来执行,如下:
java -Dfile.encoding=ISO8859-1 TestString
 
 
查看哪个进程绑定哪个邮箱
mtqmng pid
 
 
管理应用上的mtq是为了异步邮箱而安装的,生产上面两台管理应用就有两台MTQ,其中mtq2没有作用。
因为第二台管理上getmsgservice这个线程在启动时,读取deploy_inf表中的管理MGM默认节点,所以会与mtq1的134邮箱绑定。
同步模块在往管理发的时候也仅仅发送31号管理应用,也即第一台管理。
 
 
在Unix下获取多个IP的方法
ifconfig -au |grep inet |grep -v inet6 |grep -v 127.0.0.1 |awk '{print $2}'
 
 
 
EVENT_ST:事件状态
0-交易已发送
1- 交易被接受
2 - 交易已处理
99-交易出错
RESP_CD:请求应答码
00 - 成功
01 - 失败
99 - 确认收到请求/应答报文
response.code:返回报文中的应答码
00 -交易成功
XX-交易已接受
其它  - 交易失败
 
记联机交易日志MANAGE_TRANS_LOG时,首先根据逻辑一得出EVENT_ST:
if response.code == 00
EVENT_ST = 2
else if response.code == XX
EVENT_ST = 1
else
EVENT_ST = 99
 
然后根据逻辑二得出RespCode:
if ("99".equals(EVENT_ST)) {
tmmtl.setRespCode("01");
} else if ("2".equals(EVENT_ST)) {
tmmtl.setRespCode("00");
} else if ("1".equals(EVENT_ST)) {
tmmtl.setRespCode("99");
}
但是,在读取异步邮箱的代码GemMsgService中,却忘记了逻辑二,
直接将response.code中的代码更新到联机交易日志MANAGE_TRANS_LOG的RESP_CD字段。
 
 
 
删除子表记录:应该在创建修改任务中,再选择新增、修改、删除子表记录。
 
 
172.17.252.85上ma_mgm用户/mgmtest目录有最大50m的限制。
 
 
可以在console中的Security Realms->myrealm->users and groups ->点用户->passwords->save,
然后修改/mapsDomain/servers/MapsServer/security/boot.properties,这样该用户的登录weblogic的密码就改好了。
但是,改完之后执行stopWL.sh的时候报错,说密码错误。要改动bin/stopWebLogic.sh把其中的password改成正确的。就可以关掉weblogic了(或者删除也可以)
 
 
反编译资源文件
native2ascii -reverse -encoding gbk MessageResources.properties MessageResources_cn.properties
 
 
查看AIX系统资源
cpu: 
vmstat(lcpu=8逻辑cpu有8个) 
prtconf( Number Of Processors: 4         ==》物理cpu有4个)
查看系统使用情况  topas
 
查看aix内存svmon -G
例:
              size       inuse        free         pin     virtual   mmode
memory      2621440     2612781        8659      640841     3284826     Ded
pg space    1048576      898467
单位是4k,memory是实际物理内存:2621440*4/1024/1024=10g,
pg space是换页空间大小:1048576*4/1024/1024=4g
 
 
aix上查看java进程所占内存
svmon -P pid
例:
svmon -P 52363278
-------------------------------------------------------------------------------
     Pid Command          Inuse      Pin     Pgsp  Virtual 64-bit Mthrd  16MB
52363278 java            132076     7764     5865   158615      Y     Y     N
进程实际使用内存Inuse:132076*4/1024 = 516M
 
 
查看AIX系统资源
prtconf
 
 
逻辑cpu
topas
bindprocessor -q
vmstat
 
物理cpu
prtconf
 
查看cpu的详细信息,如主频,是否支持SMT,是否开启了SMT等等
lsattr -El proc0
 
查看网卡相信信息,网卡ent0
netstat -v ent0
 
 
Eclipse @override报错
在JAVA 1.5和1.6中@override的用法是有些区别的,虽然改变了JRE但eclipse还是会报错。
解决办法:Windows->Preferences-->java->Compiler-->compiler compliance level设置成6.0就OK了
 
 
weblogic.xml中 weblogic-web-app 标签的 xsi:schemaLocation 属性,在myecplise下面报错如下:
Referenced file contains errors (http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd).  For more information, right click on the message and select "Show Details..."tips/tamcx/WEB-INFweblogic.xmlline 1131191929944315159
解决办法,在xsi:schemaLocation属性增加一段内容,如下:
http://java.sun.com/xml/ns/javaee
 
 
myeclipse6.0.1注册码生成:
TOOLS/MyEclipseGen.java执行后,输入名字就可以生成序列号。比如:
用户名shenlei
序列号Serial:fLR8ZC-855575-69527357679415182
 
 
myeclipse中js乱码问题,我导入项目后,发现js里的中文全部变成乱码
解决办法:
window->Preferences->Myeclipse->Files and Editors->JSP(以及javascript等)把encoding改成UTF-8。
 
 
 
workshop的webservice项目无法generate wsdl文件解决:
右键项目 Targeted Runtimes,勾上:Runtimes  Oracle weblogic server v10.3
 
workshop中创建webservice工程,它的web.xml文件与weblogic.xml文件
与它export出的war包中的两个文件有所不同,需注意。
因为export出的war包中必须包括一些application启动类的配置。
 
 
行业机构静态信息表TBL_MAMGM_INDUSTRY_INS_STATIC_INF内的
INDUSTRY_INS_ST机构状态字段,0表示打开,1表示关闭
而对应联机库 TBL_MAONL_INDUSTRY_INS_DYN_INF表中的INDUSTRY_INS_ST字段 0表示关闭,1表示打开
 
 
workshop appxray编译时间过长解决:
右键工程——》properties->builders——》去掉勾选 workshop AppXRay
 
 
List<Map<String, String>> list = ms.findAllBySql(sql.toString(),
values);
这个方法竟然把我sql里面的列全变成大写字母放入MAP中
 
 
db2 创建远程节点连接
http://www.ibm.com/developerworks/cn/data/library/techarticles/0301chong/0301chong2.html 
db2 catalog tcpip node mpwrnode remote mpower.ca.ibm.com server 50000
注: “mpwrnode”是为该节点所选择的任意名称。
mpower.ca.ibm.com = 数据库服务器 的主机名。 可以使用 IP 地址来代替主机名。
50000 = 数据库服务器实例 所使用的端口。 
db2 catalog db a42ds1 at node mpwrnode
db2 connect to a42ds1 user <userid> using <password>
这样就可以再本地使用远程数据库。
例子如下:
1、db2 catalog tcpip node isvrfffffffff remote 172.17.248.188 server 60020
2、db2 catalog db ismgmdb at node isvrfffffffff
3、db2 terminate
4、db2 connect to ismgmdb user isvrdb3 using isvrdb3
 
 
 
删除catalog
db2 uncatalog node isvrfffffffff 
 
 
在91ma_mgm上建的catelog,指向联机性能库
db2 catalog tcpip node maonldb remote 172.17.252.133 server 60000
db2 catalog db maonldb at node maonldb
db2 terminate
db2 connect to maonldb user ma_onldb using ma_onldb
 
 
 
当前用户的当前实例
db2 get instance
The current database manager instance is:  ma_mgmdb
 
 
查看当前实例是否在
db2pd - -alldbpartitionnum
Database Partition 0 -- Active -- Up 129 days 07:30:50 -- Date 05/18/2012 17:02:26
 
 
 
查看活动日志使用如下命令:
db2pd -db arc -logs
 
 
 
当前实例的配置
db2 get dbm cfg
 
数据库的配置 
db2 get db cfg for DBNAME
 
修改日志文件大小:db2 update db cfg for mamgmdb using LOGFILSIZ 40960
修改主日志文件个数:db2 update db cfg for mamgmdb using LOGPRIMARY  15
修改辅助日志文件个数:db2 update db cfg for mamgmdb using LOGSECOND 0
 
DB2 数据库一旦创建就无法再修改字符集的编码方式了。
可以在创建的时候指定字符集,如下指定为GBK:
create db SRCDB using codeset GBK territory CN
 
设置在锁上等待的时间
db2 "update db cfg for DBNAME using LOCKTIMEOUT 15"
 
主机上所有实例(其实就是用户)
db2ilist
 
显示的是当前实例下catalog的DB信息
db2 list db directory
 
查看catalog中远程节点node的信息(实际就是远程数据库的信息)
db2 list node directory
 
查看表空间信息
db2 list tablespaces show detail
 
 
查看DB2 instance是启动还是停止的
 1、db2_ps
 2、db2pd -inst
 3、ps -ef | grep -i "db2sysc" | grep -i "<instance name>"
 4、db2gcf -s
 
 
通过端口来查看哪个用户建了这个数据库
vi /etc/services
该文件里面有用户以及对应的端口,如:
DB2_ma_onldb    60032/tcp
DB2_ma_onldb_1  60033/tcp
DB2_ma_onldb_2  60034/tcp
 
 
财税库银实现类查询
select a.*,b.tran_name,b.tran_type,b.tran_class from t_sub_tran a ,t_tran b where a.tran_code=b.tran_code;
 
 
预置刷新共享内存表tbl_mamgm_para_task_syncshm_status和预置同步子系统表tbl_mamgm_para_task_syncsys_status
在公参同步中,一个1000条的批次,会插入2条(联机+批量)记录。
 
 
 
 
创建参数新增任务、创建参数修改任务,创建参数删除任务
这些动作之前要校验是否可以操作:
ParameterFlexFacade.checkParaOperatable()
其中checkParaRecordSyncIn函数调用了para_tbl_attr表的sync_in_exp字段,该字段是一个表达式,其中替换以后可以验证,如果验证失败将会抛exception,比如:
throw new BizException("主表正式表记录不存在,不允许操作!");
throw new BizException("此记录是只读的,不允许修改和删除操作!");
 
 
过滤条件组信息表,修改时报:“此记录是只读的,不允许修改和删除操作!”
原因是:tbl_mamgm_para_tbl_attr中该记录的字段SYNC_IN_EXP配置了下面语句:只有6开头的过滤条件组id才可以修改。
boolean result = !"#{RULE_GRP_ID}".startsWith("6");
01030201TBL_MAMGM_FILTER_RULE_GRP_INF过滤条件组信息表
报错的地方在:ParameterFlexFacade。checkParaRecordSyncIn函数
 
 
maps_sys是表示该记录是技术参数,不能操作
这个限制是指:para_tbl_attr表中sync_in_exp字段配置的:
boolean result = "maps_sys".equalsIgnoreCase("#{REC_UPD_USR_ID}");
目前多渠道包括两张表有此限制:
TBL_MAPS_GFS_MSG_SPEC_INF报文规范类型信息表,TBL_MAMGM_ACCESS_SYS接入系统标识表
 
sync_in_exp字段配置的其它包括:
TBL_MAMGM_FILTER_RULE_GRP_INF过滤条件组信息表boolean result = !"#{RULE_GRP_ID}".startsWith("6");  不以6开头的的,就
TBL_MAMGM_FILTER_APP_INF过滤应用信息表boolean result = !"#{APP_ID}".startsWith("9");
 
 
 
批量的两张表任务表:
TBL_MABAT_BAT_TASK_CTRL
TBL_MABAT_RECNCL_TASK_INF
 
 
订单页面宽度变小后,多出一条横杆,解决办法:
1、main.css
.table_head 中去掉 
background:url(../images/table_top_back.jpg) left top repeat-x;
这样换行就不会有一条杠了
2、WebContent/com/cup/isvr/portal/jpf/orderview/index.jsp中<th>与汉字之间加上
<div nowrap="nowrap">
</div>
3、把.datashow th行的line-height:27px;删除
 
 
HTTP GET和POST的区别
1、都是明文传输,都是不安全的
2、GET是在url上追加参数,POST在浏览器的地址栏中看不见参数,它是将表单内各个字段与其内容放置在HTML HEADER内
3、POST不会被浏览器缓存
4、GET是获取指定URL上的资源,是读操作,不论对某个资源GET多少次,它的状态是不会改变的
POST的语意是对指定资源“追加/添加”数据
5、长度限制,GET不能大于2k,POST一般认为不受大小限制。
 
浏览器中get方式:request.getContentLength()=-1,http规范中没有限制get方式不可以设置cotent-length,
GET /mjc/webtrans/PBRG HTTP/1.1
HOST: 172.17.248.74:11000
Accept: */*
Content-Length: 3
 
q=a
 
webservice的war包中wsdl和xsd文件既可以放在\WEB-INF\src\com\cup目录下,
也可以放在\WEB-INF\classes\com\cup在,用ant脚本编译workshop建的webservice工程时要修改web.xml文件
 
 
<2011-12-2 下午02时21分49秒 CST> <Warning> <Socket> <BEA-000402> 
<There are: 5 active sockets, but the maximum number of socket reader threads allowed by the configuration is: 4. 
You may want to alter your configuration.> 
解决:左边菜单servers -> configuration -> tuning下,将Socket Readers:由33改成99
注:上面一行勾上Enable Native IO可显著提供weblogic性能
 
 
使用ant打包时,如果仅仅是import一个类,不在程序中使用该类的任何方法,或者new该类
就算这个类不在classpath中,也不会报错,且生成的class文件中没有import那句话。
 
 
W.java文件内容:
class W{
static{
System.out.println(org.apache.commons.net.ntp.TimeStamp.getCurrentTime());
}public static void main(String[] args){
}}
在cmd中执行情况是:成功、成功、成功、失败。
javac -cp "d:\bea\modules\com.bea.core.apache.commons.net_1.0.0.0_1-4-1.jar" W.java
java -cp ".;d:\bea\modules\com.bea.core.apache.commons.net_1.0.0.0_1-4-1.jar" W
javac -cp "D:\bea\wlserver_10.3\server\lib\weblogic.jar" W.java
java -cp "D:\bea\wlserver_10.3\server\lib\weblogic.jar" W
1、很明显weblogic.jar中没有org.apache.commons.net.ntp.TimeStamp类,为什么能编译通过
2、把weblogic.jar拷贝到比如D:\bea\wlserver_10.3\server目录下,就编译不过了。为什么?
 
 
对于db2中字段是char型的后面补了空格的情况,在java中用sql查出来时也是带空格的。
要在sql中或者resultset结果中使用trim()去掉空格。
 
 
启动多渠道管理应用时,执行分别会执行下面脚本
mapsDomain/startWL.sh
mapsDomain/startWebLogic.sh
mapsDomain/bin/startWebLogic.sh  配置DOMAIN_HOME、JAVA_OPTIONS
${DOMAIN_HOME}/bin/setDomainEnv.sh  配置WL_HOME、JAVA_VM、JAVA_HOME、USER_MEM_ARGS、PRODUCTION_MODE、DOMAIN_PRODUCTION_MODE、SERVER_NAME、JAVA_OPTIONS
${WL_HOME}/common/bin/commEnv.sh   配置BEA_HOME、WL_HOME、JAVA_HOME、JAVA_VENDOR、WEBLOGIC_CLASSPATH、PATCH_CLASSPATH、CLASSPATHSEP
 
 
现在想要做一个java的socket客户端,C的socket服务端。客户端向服务端发送的报文中头四个字节是整型,表示报文总长度,
之后才是报文内容。在C里很好做,先把长度转成网络字节序,再拷贝到四个字节的缓冲区里。但是JAVA中要怎么做呢?
答:使用DataOutputStream,用其中的writeInt方法
此方法是如下操作:>>>表示无符号右移,左移没有无符号一说,即没有<<<
out.write((v >>> 24) & 0xFF);
        out.write((v >>> 16) & 0xFF);
        out.write((v >>>  8) & 0xFF);
        out.write((v >>>  0) & 0xFF);
int v =-2;
int s = v >> 1;
System.out.println(s);//-1
s = v >>> 1;
System.out.println(s);//2147483647
//00000000 00000000 00000000 00000000表示0
//01111111 11111111 11111111 11111111表示2147483647
//10000000 00000000 00000000 00000000表示-2147483648
//10000000 00000000 00000000 00000001表示-2147483647
//11111111 11111111 11111111 11111111表示-1    //通过System.out.println(Integer.toBinaryString(-1));方法可以看到二进制码
 
 
* Java 和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换  
* 高、低字节之间的转换  
* windows的字节序为低字节开头  
* linux,unix的字节序为高字节开头  
* java则无论平台变化,都是高字节开头  
 
 
使用weblogic的jta全局事务
ctx = getInitialContext();//创建一个上下文环境
javax.transaction.UserTransaction ut = (javax.transaction.UserTransaction)ctx.lookup("javax.transaction.UserTransaction");
ut.begin();
...
ut.commit();
 
 
 
 
transient
java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。   
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,
我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
 
 
如果不implements   Cloneable的话,那么调用super.clone()函数将抛出CloneNotSupportedException异常
 
 
shell脚本中获得日期
CURTIME=`date +%Y%m%d%H%M%S`
echo $CURTIME
 
 
JAVA四个方位修饰符
private--类内部 
 
default--类内部,同包无继承关系类,同包子类 
 
protected--类内部,同包无继承关系类,同包子类,不同包子类 
 
public-类内部,同包无继承关系类,同包子类,不同包子类,不同包无继承关系类
 
 
@SuppressWarnings("serial")在Java中有什么作用?
@SuppressWarnings可以抑制一些能通过编译但是存在有可能运行异常的代码会发出警告,你确定代码运行时不会出现警告提示的情况下,可以使用这个注释。
("serial") 是序列化警告,当实现了序列化接口的类上缺少serialVersionUID属性的定义时,会出现黄色警告。可以使用@SuppressWarnings将警告关闭
 
 
表清理问题
TBL_MAMGM_TABLE_CLEAN_CFG
clean_md:0-多表清理;1-清理无效数据;2-清理指定表
ma_batdb.tbl_mabat_trans_log_chk_fail勾兑差错流水表,属于2-清理指定表;共7张,清理星期几的那张表的数据
ma_onldb.tbl_maonl_trans_refund退货表,也属于2-清理指定表,共3张,每月3号清理 第(month % 3 + 1)张表。
像众多的“0-多表清理”方式的表,表号取自ma_gfsdb.TBL_MAPS_GFS_DYN_SYS_PARA
ma_batdb.tbl_mabat_elct_prod_infBAT电子产品表,属于1-清理无效数据
ma_batdb.tbl_mabat_trust_data_infBAT托管数据表,属于1-清理无效数据
 
 
批量应用绑管理库
执行/maps/usr/hg_bat1/glb/gfs/sbin/mgmbind.sh
 
 
联机批量报818错,bind管理库有问题,需要将glb/gfs/bin/MDatasync_bat进程和glb/gfs/bnd/MDatasync_mgmdb.bnd文件一同拷贝
,注意进程的可执行chmod
 
taskcom list
进程扫描管理库的TBL_MAPS_GFS_TASK表,共享内存里面去
 
HttpServlet为什么要实现serializable?
我认为主要的原因是servlet容器可能会钝化servlet,把不活跃的servlet暂时持久化到IO设备
The servlet engine is not required to keep a servlet loaded for any period of time or  
for the life of the server. Servlet engines are free to use servlets or retire them at any  
time. Therefore, you should not rely on class or instance members to store state  
information.  
When the servlet engine determines that a servlet should be destroyed (for example,  
if the engine is shut down or needs to conserve resources), the engine must allow the  
servlet to release any resources it is using and save persistent state. To do this, the  
engine calls the servlet’s destroy method.  
The servlet engine must allow any calls to the service method either to complete  
or to end with a time out (as the engine defines a time out) before the engine can  
destroy the servlet. Once the engine destroys a servlet, the engine cannot route any  
more requests to the servlet. The engine must release the servlet and make it eligible  
for garbage collection.
容器不要求每个servlet都一直维持在内存,可以钝化,servlet也支持多种类加载方式,包括反序列化。
 
 
 
 
下拉框的两表DRDL_CFG和DRDL_ITEM_DEF都不支持oper_in in ('d','D')的过滤
DRDL_CFG表:DropDownCache.queryAll()
 
DRDL_ITEM_DEF表:
DataDropDown.java的构造函数调用了DropDownBaseImpl的构造函数,再调用了DataDropDown的init(),sql=SQL_LBLCD+...
SQL_LBLCD是在DropDownBaseImpl中定义:
static final String SQL_LBLCD="SELECT A.drdl_item_key,A.drdl_item_val FROM TBL_MAMGM_DRDL_ITEM_DEF A,"
+"TBL_MAMGM_DRDL_CFG B WHERE A.drdl_id=B.drdl_id AND B.drdl_nm=";
 
 
 
查看系统使用表空间的方法:
1、连接到目标数据库
命令:db2 connect to mamgmdb user username using password(username和password需要替换为正确的值)
2、查看数据库表空间使用情况
命令:db2 list tablespaces show detail
 
查看表空间所属容器信息
db2 list tablespace containers for 1 show detail
 
3、判断数据库表空间使用率是否正常的方法:
首先判断表空间类型(Type),如果Type= System managed space,说明表空间是操作系统管理的表空间,表空间自增长,只需关注表空间所在的文件系统的利用率。
如果Type= Database managed space,说明表空间是数据库管理的表空间,表空间非自增长,需要关注Used pages与Useable pages的比值,当(Used pages/Useable pages)>80%,需要及时向系统室值班岗报告。
 
 
查看数据库是否使用了归档日志,OFF为循环日志
db2 get db cfg for gmabatdb|grep LOGRETAIN
Log retain for recovery enabled             (LOGRETAIN) = OFF
Log retain for recovery enabled             (LOGRETAIN) = RECOVERY (为归档日志)
 
 
AIX主机名:
hostname
 
主机名对应的IP
vi /etc/hosts
 
aix查看某进程打开的文件数量
procfiles -n pid
 
对某进程强制垃圾收集
procfiles -F pid
 
UdpServlet的启动日志在cup_maps_alarm.log里面
 
 
多渠道和行综也会被xss跨站脚本攻击,原因就是这次新加的titleNm值
https://172.17.248.188:7002/isvr/com/cup/isvr/portal/jpf/flex/parameter.jsp?subjectId=010911&titleNm=ddd");}alert('xss');>
https://172.17.248.188:7002/isvr/com/cup/isvr/portal/jpf/flex/parameter.jsp?subjectId=010911&titleNm=ddd");}alert(request.getParameter('subjectId'));>
 
 
 
Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试
 
 
 
SQL
对于查不出结果的sql语句的ResultSet一点不同:
select * from tbl_mamgm_para_task where EVENT_ID =2rs.next() == false
select 1 from tbl_mamgm_para_task where EVENT_ID =2rs.next() == false
select sum(1) from tbl_mamgm_para_task where EVENT_ID =2rs.next() == true,且rs.getInt(1)==0
 
 
 
flex的DateField日期组件,默认是不可修改。如果需要修改增加属性:
editable="true"
 
 
weblogic热部署必须要把启动模式改成开发模式,方法是config.xml中标签<production-mode-enabled>改成false。
热部署的build.xml关键语句
 <target name="redeploy" description="redeploy ear to WebLogic on ${wls.ip}:${wls.port};">
                <wldeploy user="${user}" password="${password}" adminurl="t3://${wls.ip}:${wls.port}" debug="true" remote="true" upl
oad="true" action="redeploy" name="${map.earApp.name}" source="${dest.home}/dest/${map.earApp.name}.ear" verbose="true" />
 
        </target>
        
 
在TimerTaskStartThread类中增加了catch NoSuchEJBException{break;}的原因是:
答:在redeploy管理应用ear包的时候,增加了一个TimerTaskStartThread线程,但是原先的TimerTaskStartThread线程仍在,
只是原先线程缓存了之前的ejb对象,导致了一直报错,虽然新的TimerTaskStartThread线程使得功能无影响,
但是break出去以后就不会在nohup.out里面报错了。
 
 
 
当db2中某表被锁,当使用weblogic数据源select该表,或者java应用通过jdbc select该表,均在10秒钟后报错,一个的errorcode=-4470,
另一个的SQLCODE=-911,这个超时时间10秒设置在:
1、db2 "update db cfg for DBNAME using LOCKTIMEOUT 15"  此处15是指设置锁上等待15秒
2、重启db2实例,才能生效
 
 
 
 
AIX查看某个端口被哪个进程占用
1. netstat -Aan|grep <portnumber>
2. 如果是 tcp 连接,则 rmsock <PCB/ADDR> tcpcb,如果是 udp 连接,则 rmsock <PCB/ADDR> inpcb 
下面我们以 telnet 服务所使用的 23 号端口为例,说明该方法: 
#netstat -Aan|grep 23
f1000200019ce398 tcp 0 0 *.23 *.* LISTEN
可以看到 PCB/ADDR 为 f1000200019ce398 ,且协议类型为 tcp
#rmsock f1000200019ce398 tcpcb
The socket 0x19ce008 is being held by proccess 185006 (inetd).
命令报告该端口正在被 inetd 进程使用, PID 为 185006 。 
3. ps -ef |grep PID
 
 
windows查看端口占用命令
1、netstat -aon|findstr "80"
2、tasklist|findstr "2448" 
 
windows杀死进程命令
tskill PID或者
 
 
 
 
HttpServletResponse的getBufferSize()方法获取Web容器的以kb为单位的目前缓冲区大小
 
 
cvs上被remove和commit的文件,恢复的办法:
答:根据版本号或者标签号checkout下来,例如historyFrame.html文件已经被彻底删除:
cvs co -r maps-7760-20120724 maps_mgm/flex/comm/html-template/history/historyFrame.html
 
 
 
日切日期:
同步模块会校验:管理发给的日期 = TBL_MAPS_GFS_DYN_SYS_PARA.MAPS_SETT_DATE + 1     校验不过直接报错
 
这个字段表示当前使用哪张表:
TBL_MAPS_GFS_DYN_SYS_PARA.multi_tab_act
第一位:0表示不在日切窗口期,1表示在日切窗口
第二位:2套表使用第几张
第三位:3套表使用第几张
第四位:7套表使用第几张
 
 
 
应用启动时数据源连接池的驱动用的是mapsDomain/lib/db2jcc.jar,
启动时,weblogic会自动去mapsDomain/lib下加载所有jar包。
 
 
FAQ
Some solutions to common problems:
Exception
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
Solution
Include a listener in your web.xml:
<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
 
 
问题:jsf的javax.faces.application.ViewExpiredException异常
答:去掉richfaces4的jar包
 
 
 
数据库字段,前面加上函数就不走索引了
select * from TBL_MAMGM_POS_PARA_INF WHERE LOWER(mchnt_cd) LIKE '11%';
RETURN0.0 %13993.33593751.350166272E913474.07.85886144638061513993.32128906251.35012864E913474.00.00.013474.00.00.0
MA_MGMDB.TBL_MAMGM_POS_PARA_INF  TBSCAN100.0 %13993.33593751.350166272E913474.07.85886144638061513993.32128906251.35012864E913474.00.00.013474.00.00.044675.437512
 
 
 
weblogic上ssl的端口默认是7002,所以有可能7002不出现在config.xml文件中
 
 
eclipse默认启动内存在eclipse.ini文件中配置:
诸如:
-Xms128m
-Xmx512m
-Duser.language=en 
-XX:PermSize=128M 
-XX:MaxPermSize=256M
 
 
 
boolean offer(E e) 
Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions. When using a capacity-restricted queue, this method is generally preferable to add(E), which can fail to insert an element only by throwing an exception.
 
它们的区别就是add 方法在插入失败的时候会抛出 IllegalStateException 异常
而offer可以通过返回值来判断成功与否 
 
 
Server监听
Socket clientSocket = serverSocket.accept();
tcp        0      0  *.8886                 *.*                    LISTEN
 
已建立的链接
cp4       0      0  172.17.248.74.8886     172.17.236.133.3966    ESTABLISHED
 
 
 
 
java做webservice时获得客户端的信息
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
 
@Resource
WebServiceContext messageContext;
 
MessageContext mc = messageContext.getMessageContext();
HttpServletRequest request = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST);
String remortAddress = request.getRemoteAddr();
 
/*request.getLocale()=zh_CN
request.getLocalAddr()=172.17.248.74
request.getLocalName()=host01
request.getLocalPort()=8888
remortAddress=172.17.236.133
request.getRemoteHost()=172.17.236.133
request.getRemotePort()=3823
request.getRemoteUser()=null*/
System.out.println("request.getLocale()="+request.getLocale());
System.out.println("request.getLocalAddr()="+request.getLocalAddr());
System.out.println("request.getLocalName()="+request.getLocalName());
System.out.println("request.getLocalPort()="+request.getLocalPort());
System.out.println("remortAddress="+remortAddress);
System.out.println("request.getRemoteHost()="+request.getRemoteHost());
System.out.println("request.getRemotePort()="+request.getRemotePort());
System.out.println("request.getRemoteUser()="+request.getRemoteUser());
 
 
 
j2se开启webservice服务:
String wsUrl= "http://172.17.236.133:8888/MtqWebService?wsdl";
Endpoint.publish(wsUrl, new MtqWebService());
MtqWebService是一个类,需要标注@WebService、@WebMethod。
如果想让webservice服务的方法抛出异常必须要把异常包装成SOAPException,如:
 
@WebMethod
public String callByXml(String xmlData) throws Exception{
throw new SOAPException("dqqqqq");
}
 
 
 
Exception in thread "main" javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:331)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:234)
at org.apache.cxf.jaxws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:112)
at javax.xml.ws.Endpoint.publish(Endpoint.java:170)
at com.sl.ws.threadpool.MtqWebAction.main(MtqWebAction.java:22)
解决:去掉jbosslib的user library
 
 
Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "msg"
this problem is related to the following location:
at public java.lang.String com.sl.ws.model.Request.getMsg()
at com.sl.ws.model.Request
this problem is related to the following location:
at public java.lang.String com.sl.ws.model.Request.msg
at com.sl.ws.model.Request
Class has two properties of the same name "msgRes"
this problem is related to the following location:
at public java.lang.String com.sl.ws.model.Response.getMsgRes()
at com.sl.ws.model.Response
this problem is related to the following location:
at public java.lang.String com.sl.ws.model.Response.msgRes
at com.sl.ws.model.Response
解决:将com.sl.ws.model.Request和 com.sl.ws.model.Response类中的属性从public改成private
 
 
weblogic在console中做update、stop、delete应用时,会调用Servlet的destroy()方法。
对于某些类的静态static实例变量,要在destroy方法中做clear,否则执行update、stop、delete后,static实例变量被认为是null值。
原先的static实例变量所指的对象将永远存在,直到domain被stoped
 
 
 
java socket的连接超时时间:
Socket socket = new Socket();
socket.connect( new InetSocketAddress( "172.17.236.133", 4700 ),5000);  //比如此处设置成5s
如果端口4700在server上没有监听:
1、如果该client与server的ip在同一网关内,java较容易找到该server机器,则直接抛错:java.net.ConnectException: 远程主机拒绝 connect 操作尝试。
2、如果该client与server的ip不在同一网关内,java将会去DNS上找路由,时间较长,那么超时抛错会出现:java.net.SocketTimeoutException: connect timed out
 
 
 
由于AIX(或UNIX)系统和Windows系统对于文本文件的行末结束符(或回车换行符)的处理方式不同,
当我们将Windows格式的一个文本文件以BIN格式(而不是ASCII方式)上传至AIX上时,用vi查看该文件会发现每行的行末出现一个^M的符号。
这会导致AIX系统下对该文本文件的处理出现异常,并且在该文件是脚本的情况下,也会导致脚本执行异常。
 
 
杀死本用户下的weblogic进程
ps -fu $USER |grep weblogic|grep -v grep|awk '{print $2}'|xargs kill -9 $1
 
 
乱码
public static String getEncodedString(Object p) {
boolean isDefaultChinese = Locale.getDefault().getLanguage()
.toLowerCase().indexOf("zh") != -1;
String tmpStr = p.toString();
if (!isDefaultChinese)
try {
tmpStr = new String(tmpStr.getBytes("GBK"), "ISO8859_1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return tmpStr;
}
 
 
网络传输中有个二进制0的概念,一个字节8位全是二进制0,在java里面表示byte b = '\0',
对于new String(byte[])以后,二进制0还会存在,只要做了trim()就去掉了。
如果把二进制0赋予整型会变化成ascii的0.
int i = '\0';
System.out.println("i="+i);//i=0
 
 
 
weblogic的web应用:
提交了重新编译的class文件,哪怕是其中一个文件,或者不相干的class文件,
原先class中static变量的值都被赋null了。
 
 
JDK5.0 java.util.concurrent包中引入对Map线程安全的实现ConcurrentHashMap
java.util.concurrent包也提供了一个线程安全的ArrayList替代者CopyOnWriteArrayList
 
 
如何讲二进制流 加入XML报文中发送?
// 将 s 进行 BASE64 编码
public static String getBASE64(String s) {
if (s == null) return null;
return (new sun.misc.BASE64Encoder()).encode( s.getBytes() );
}
 
// 将 BASE64 编码的字符串 s 进行解码
public static String getFromBASE64(String s) {
if (s == null) return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
只要在xsd中,将某个字段类型设置成base64Binary,jaxb能自动讲xml中的BASE64 编码的字符串解析成正确的byte[]数组。
 
 
 
 
Socketsocket = new Socket();
//socket.setSoTimeout(5000);
InetSocketAddress local = new InetSocketAddress("172.17.246.1",0);
socket.bind(local);
socket.connect( new InetSocketAddress( "145.17.236.133", 4700 ),1000);  
 
    socket.setSendBufferSize(100);
 
 
 
mian2 aix测试结论:
1、新增一个new NioSocketConnector(1),增加4个句柄的使用。只开一个NioProcessor,即只用一个cpu,只开一个select.open()
2、新增一个new NioSocketConnector(),增加了4*(4+1)个句柄。第2个4:是248.74上有4核的cpu       4+1是默认值
3、做一次connector.connector()操作,即新增一条链路的话,增加1个句柄
4、new NioSocketConnector()和new NioSocketConnector(Runtime.getRuntime().availableProcessors() + 1)是一样的。
 
 
 
 
log4j.properties、CommPacket.ini、FilePacket.ini、mtq.properties       先找mtqCfg/ ,再找appCfg/,再找当前路径下
mtqNetwork.xml、mtqService.xml   必须在mtqCfg目录下,或者mtqCfg/sysname/目录下
 
 
 
 
如何使用JDK自带的JConsole监控Weblogic
http://172.17.249.10/NewSys/OA/KnowledgeBase/ShowKb.aspx?Id=6440&Key=
 
在java启动时添加:
-Dcom.sun.management.jmxremote.port=41125 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
在windows path中:
Jconsole
 
myeclipse6.0
今天安装完eclipse和myeclipse以后,发现启动后窗口的标题栏显示:wtp java ee(myeclipse incompatible)?
选其它的perspective(视图): MyEclipse Java Enterprise
 
 
 
官方文档指出,WebLogic 9 / WebLogic 10 的线程池是自调优的,并且在WebLogic 9的时候,
通过修改config.xml可以修改默认线程池的最小值、最大值,但是很麻烦。
到了WebLogic 10gR3,连修改config.xml的办法都给取消了。
 
但是,可以通过在启动脚本增加如下参数,可以指定默认线程池的最小值、最大值:(http连接数)
 
-Dweblogic.threadpool.MinPoolSize=100 -Dweblogic.threadpool.MaxPoolSize=500
 
 
 
 
HashMap map.get(null)   返回null
ConcurrentHashMap concurmap.get(null)   报错java.lang.NullPointerException
ConcurrentHashMap concurmap.put(Integer.valueOf(2),null);报错java.lang.NullPointerException
 
Map遍历方式
for(Map.Entry<String, String> map : formFldValues.entrySet()){
queryString += map.getKey()+" like ? and";
values.add(map.getValue());
}
 
 
xml 转 javabean方式
 
//方式一 jaxb ,无需额外lib包
/*InputStream is = null;   效率最差
try {*/
// System.out.println(REQ.class.getPackage().getName());
/*JAXBContext jc = JAXBContext.newInstance(REQ.class.getPackage()
.getName());// 包名
Unmarshaller u = jc.createUnmarshaller();
is = new ByteArrayInputStream(xmlStr.getBytes("GBK"));
REQ req = (REQ) u.unmarshal(is);*/
 
//方式二 xsream ,需xstream-1.3.1.jar    10w次 78390ms
/*XStream xs1 = new XStream(new DomDriver());
xs1.alias("REQ", REQ.class);
REQ req = (REQ) xs1.fromXML(xmlStr);*/
 
 
//方式三 dom4j,需dom4j-1.6.1.jar  10W次 54203ms
Document doc=null;
try {
doc = DocumentHelper.parseText(xmlStr);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 将字符串转为XML
     Element rootElt = doc.getRootElement(); // 获取根节点
      System.out.println("根节点:" + rootElt.getName()); // 拿到根节点的名称
System.out.println(rootElt.elementTextTrim("SYSTEMNAME"));
 
//方式四 stax  10w次  6125ms
static XMLInputFactory inputFactory = XMLInputFactory.newInstance();
byte[] byteArray = xml.getBytes("GBK");
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray);
XMLStreamReader reader = inputFactory.createXMLStreamReader(inputStream);
int event = reader.getEventType();//获取节点类型,结果是以整形的方式返回的。
while (reader.hasNext()) {
switch (event) {
case XMLStreamConstants.START_DOCUMENT://表示的是文档的开通节点。
break;
case XMLStreamConstants.START_ELEMENT://开始解析开始节点   
if (reader.getLocalName().equals("SYSTEMNAME")) {//判断节点的名字
 
mr.setSystemName(reader.getElementText());
break;
}
event = reader.next();
}
 
//方式五  自解 10w次  1437ms
mr.setSystemName(sb.substring(sb.indexOf("<SYSTEMNAME>")+12,sb.indexOf("</SYSTEMNAME>")));
 
 
 
使用cxf测试了csb上webservice,证明可行:
但是csb似乎不支持使用一个url获取wsdl,原因是解析后的wsdl文件倒数第四行address location是主机名,而不是ip
如:
http://P570_F_3:7001/csb/shcenter/BillDomain/MultiAcquiringSystem/BpsServiceImplService/BpsServiceImplServiceProxy
所以需要把wsdl保存在d:/BpsServiceImplServiceProxy.wsdl,然后将上述address location替换如下:
http://172.17.252.63:7001/csb/shcenter/BillDomain/MultiAcquiringSystem/BpsServiceImplService/BpsServiceImplServiceProxy
其效果与使用应用自己的webservice一样。
http://172.17.252.85:4866/MapsServicePortal/BpsServiceImplService?wsdl
 
此外还可以把解析好的变量设置成final类型:
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
final Client client = dcf.createClient("d:/BpsServiceImplServiceProxy.wsdl");
Object[] res = client.invoke("excuteBpsService","<CUPBPS></CUPBPS>","BPS", "MAPSQUERY");
System.out.println("Echo response: " + res[0]);
 
 
 
 
 
如果xml请求报文中无<FILECONTENT>标签,则进不去这个if中
} else if (reader.getLocalName().equals("FILECONTENT")) {//判断节点的名字
如果xml请求报文中有,且值为空,如<FILECONTENT></FILECONTENT>,则
String s = reader.getElementText();
System.out.println((s==null));//false
System.out.println((s.equals("")));      //true
 
byte[] b = s.getBytes();
System.out.println((b==null));//false
System.out.println((b.length));//0
 
 
 
log4j级别依次下降
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level OFF;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level FATAL;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level ERROR;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level WARN;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level INFO;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level DEBUG;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level TRACE;
  
  // Field descriptor #56 Lorg/apache/log4j/Level;
  public static final org.apache.log4j.Level ALL;
 
 
 
 
持卡人管理upjas配置文件
$HOME/upjas/upjas-minimal/server/default/cup-deploy/mtqCfg
 
domain启动时脚本,以及nohup.out文件位置
$HOME/upjas/upjas-minimal/bin
 
 
 
java使用udp
客户端:
DatagramPacket packet = new DatagramPacket(msg.getBytes(), Integer
.valueOf(msg.length()), address, Integer.valueOf(port));
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
 
//发送以后socket记下了本机使用的临时端口:socket.getLocalPort()
//所以之后可以监听端口等待了
byte[] message = new byte[256];
DatagramPacket recpacket = new DatagramPacket(message, message.length);
socket.setSoTimeout(10 * 1000);
socket.receive(recpacket);
 
//从udp包中获取数据是这样的:
String recmsg = new String(recpacket.getData(),0,recpacket.getLength());
System.out.println("client:"+recmsg);
 
 
服务端:
DatagramSocket socket = new DatagramSocket(Integer.valueOf(port));  //监听一端口
byte rb[] = new byte[1024];//申请一块内存
DatagramPacket pac = new DatagramPacket(rb, rb.length);//装成udp包
socket.receive(pac);//阻塞读,一旦收到内容,往udp包里面写信息,如:客户端ip、port;真实数据写入内存rb中
 
//使用接收时用的udp包中的客户端ip和port,将信息返回到客户端
String message = "toclient";
DatagramPacket recpacket = new DatagramPacket(message.getBytes(),message.length(), pac.getAddress(), pac.getPort());
socket.send(recpacket);// 发送回去
 
//另一种方式,原路返回客户端
pac.setData(message.getBytes());
socket.send(pac);// 发送回去
 
 
实践证明如果主机网卡上有两个ip(逻辑ip),那么下面代码,未绑定一个ip时,udp服务将在两个ip的端口上监听,udp客户端可以往两个ip的这个端口发消息
DatagramSocket socket = new DatagramSocket(Integer.valueOf(port));
 
且可以绑定两个ip的一个端口2次,下面的两个ip在一块网卡上。
String ip = "172.17.236.134";
InetAddress serveraddress = InetAddress.getByName(ip);
DatagramSocket socket = new DatagramSocket(Integer.valueOf(port),serveraddress);
String ip = "172.17.236.133";
InetAddress serveraddress = InetAddress.getByName(ip);
DatagramSocket socket = new DatagramSocket(Integer.valueOf(port),serveraddress);
 
 
如果ip是null或者“”,那么返回值是127.0.0.1的地址,
InetAddress serveraddress = InetAddress.getByName(ip);
---->  impl.loopbackAddress();
 
 
AIX5.3上如何查IP配置及子网掩码!
smitty tcpip选中你要看的网卡,回车.看完后按ESC+0退出就可以了.
 
查看网卡信息
lsdev -Cc adapter|grep ent
 
ifconfig -a 查出有几个网络接口,因为可能装有多个网卡。假设有ent0、ent1
lscfg -v -l ent0,就可以查到这块网卡的包括子网掩码、所在插槽位置等多个信息。
 
 
count(*)和order by一起会报错?
select count(*) from TBL_MAMGM_DRDL_CFG order by drdl_id;
 
 
 
从javaEE5开始,jpa规范脱离了EJB规范,好处是J2SE环境也可以使用jpa持久化层了。
 
 
eclipse生成javadoc
Project -> Genetate JavaDoc
如果项目编码不是GBK而是UTF-8,那么在Extra javadoc options写上:
-encoding UTF-8
-charset UTF-8
 
 
 
ApplicationInfoUtil的属性是无法通过管理页面刷新获得更新的,要改?
 
 
为什么API里FileReference有load()方法和data属性却不能使用?
FileReference的load()方法和data属性需要使用flashplayer 10的版本,
要添加playerglobal.swc,在你所用的sdk包下面,我这里的路径是sdk3.5.0.12683/frameworks/libs/player/10/playglobal.swc
 
 
flex builder3 默认要求flash player 最低要9,需要改成10.0,修改方法如下: 
右键点击项目,在项目属性中找 flex compile, 修改 html wrapper,把9.0.24改为10.0.0
 
 
flex工程ParaCommon报如下错误:'isNaN' is marked as extern, but '__AS3__.vec:Vector$int' is not?
右键工程-》Flex Library Compiler -》 Additional compiler arguments ->-target-player=10
so I went back to my application project to see if I had any special compiler settings, and remembered I had :
-target-player=10
 
 
 
Facade类的方法抛出BizExcpetion前台也获取不了。
 
 
@Column放在setPageImport上竟然获取不了数据库的值,只有放在getPageImport才正确。
 
 
 
flash10开始,FileReference增加了一个save方法,参数为(data:Object, defaultFileName:String = null),在调用save方法时,只需将文件内容传给data,
浏览器会自动打开一个保存对话框,让用户选择保存目录。有两个要注意的地方,1、save方法flash10及以上才有,客户端flash版本需跟上,
且代码编译环境也要在10以上,eclipse环境下,选中项目,右键properties,flex compiler选项,将required flash player version 设为10.0.0或以上,
否则将找不到save方法。2、save方法只能通过用户交互来调用。怎么理解用户交互,例如,点击一个下载按钮这算是用户交互,
而一般的回调方法则不是用户交互。如下载一张图片,如果图片还没加载进来,我们经常是先要进行加载,然后监听事件,然后在回调函数里进行处理,
如果将save方法写在回调函数里面,将会报错:Error #2176: 某些动作(如显示弹出窗口的动作)只能通过用户交互来调用。
所以很多时候我们必须采用双按钮,一个用来加载数据,一个用来下载数据。
 
 
点“模版文件下载”按钮没反应:
解决:eclipse环境下,选中项目,右键properties,flex compiler选项,将required flash player version 设为10.0.0或以上,
 
 
treemap是自然顺序(默认自然顺序,是指如果key是int型就是按数字大小,如果key是string则按照字母顺序排列,如果实现了Comparator接口即可按照想要的顺序了),
linkedmap是插入顺序,ListOrderedMap,LRUMap等都是有一定规则的顺序的map...
 
 
 
PrepardStatement语句中占位符?不能在select的字段中,只能在where条件后?
 
 
 
 
持续insert时候,db2报如下错误:ERRORCODE=-805,SQLSTATE=51002
 
问题的根本是因为程序里有很多游标没有关闭
问题解决了,谢谢你的提醒!!
pstmt.executeUpdate(); 
pstmt.close();//加上这一行
就可以了。
 
 
 
新增菜单无法通过刷新管理缓存立刻可见?
原因:tbl_mamgm_access_inf表中的access_cd字段值最后多了一个空格
 
 
 
 
同步子系统失败了以后竟然到了同步成功这一状态???
 
 
 
 
flex3中datagrid组件中某个单元格可编辑时,如何在键盘输入值之后触发事件函数获得值?
有两个事件可以itemEditEnd、itemFocusOut。
<mx:DataGrid id="defindInfoGrid" editable="true" itemEditEnd="valueVaildate(event)"/>
 
public function valueVaildate(event : DataGridEvent) : void
{
//第几列
Logger.info("event.columnIndex1 :"+event.columnIndex);
 
//dataField值
 var dataField:String = event.currentTarget.columns[event.columnIndex].dataField;;
 Logger.info("dataField :"+dataField);
 
//编辑前值
var oldValue:String=event.itemRenderer.data[dataField];//对已知的dataField:event.itemRenderer.data.FIELD_DESC
Logger.info("oldValue :"+oldValue);
 
 var cols:DataGridColumn=defindInfoGrid.columns[event.columnIndex];
//编辑后新的值
  var newValue:String=defindInfoGrid.itemEditorInstance[cols.editorDataField];
  Logger.info("newValue :"+newValue);
}
 
 
 
 
db2查询sql时报如下错
 09:06:16  [SELECT - 0 row(s), 0.000 secs]  
 [Error Code: -968, SQL State: 57011]  DB2 SQL error: SQLCODE: -968, SQLSTATE: 57011, SQLERRMC: null
增加你的system temp tablespace所在文件系统大小,或者database temp tablespace空间利用率
 
 
 
在weblogic中,如果有多个war、war包应用,默认的部署顺序都是100,改变方法是修改config.xml中的<deployment-order>98</deployment-order>项
  <app-deployment>
    <name>mjc</name>
    <target>MapsServer</target>
    <module-type>war</module-type>
    <source-path>/GGZF/usr/mapsweb/shenlei/dest/mjc.war</source-path>
    <deployment-order>98</deployment-order>
    <security-dd-model>DDOnly</security-dd-model>
  </app-deployment>
或者在console中,点deployment中的某一项应用。
 
 
 
 
页面新增参数,点保存时报“当前用户没有此操作权限!”
原因:TBL_MAMGM_PARA_SUB_AREA_INF表中的ACCESS_CD没写对
 
 
参数维护时,创建新增任务,点保存,报“用户没有权限”错误
原因:subject表上access_url填写错误。
 
 
使用ThreadLocal以空间换时间解决SimpleDateFormat线程安全问题,同时提高了每次new SimpleDateFormat的效率
class DateUtil2 {
 
private static final String DATE_FORMAT = "yyyy-MM-dd";
 
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
protected synchronized DateFormat initialValue() {
System.out.println("initial");
return new SimpleDateFormat(DATE_FORMAT);
}
};
 
public static DateFormat getDateFormat() {
return threadLocal.get();
}
 
public static String format(Date date) throws ParseException {
return getDateFormat().format(date);
}
 
public static Date parse(String textDate) throws ParseException {
return getDateFormat().parse(textDate);
}
}
 
 
 
PreparedStatement中进行模糊查询:
String = "select * from tbl_mamgm_comm_line_cfg where line_no like ?"
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, "%000HCSN0001A1%");
ResultSet rs = ps.executeQuery();
 
 
java.util.zip
GZIPOutputStream类用于压缩 
GZIPInputStream类用于解压缩 
 
 
 
2012 年餐饮业收入23,283 亿元,同比增长13.6%。其中限额以上餐饮业收入7,799 亿元,同比增长12.9%
限额以上餐饮业是指年主营业务收入200 万元及以上的餐饮业企业 (单位)
 
 
sleep三秒
TimeUnit.SECONDS.sleep(3);
 
 
poi中设置单元格为文本格式:
HSSFCellStyle cellStyle2 = demoWorkBook.createCellStyle();
            HSSFDataFormat format = demoWorkBook.createDataFormat();
            cellStyle2.setDataFormat(format.getFormat("@"));
            cell.setCellStyle(cellStyle2);
            
 
excel 2003  工作表最大有2^16=65536行,2^8=256列
 
excel 2007 和excel 2010最大有2^20=1048576行,2^14=16384列
 
 
ibm jdk gc(xml格式) 查看工具ga441.jar
Used Tenured(After)   gc过后老年代使用的内存大小
Free Tenured(After)   gc过后年老代未使用内存大小
Total Tenured(After)  gc过后老年代总大小
Free Tenured(Before)  gc之前年老代未使用内存大小
Total Tenured(Before) gc之前老年代总大小
Free Nursery(After)    gc之后年轻代未使用内存大小
Total Nursery(After)   gc之后年轻代总大小
Free Nursery(Before)   gc之前年轻代未使用内存大小
Total Nursery(Before)  gc之前年轻代总大小
 
分配失败(AF)导致的垃圾收集的verbosegc输出
 
compact压缩
如果未设置虚拟机参数-Xnocompactgc并且以下几个条件任何一个为true,那么就会发生堆压缩动作: 
· 设置了虚拟机参数-Xcompactgc 
· 清理阶段结束之后,还是无法满足分配需求 
· 调用System.gc()并且在最后一次分配失败发生或者并发标识收集之前发生了压缩动作 
· TLH消耗了至少一半的存储,并且TLH的平均大小低于1000字节 
· 堆的空闲空间小于5% 
· 堆的空闲空间小于128KB 
 
其实IBM的gc的停止比我们想象中要短的多。STW(stop total world)只有在下面这些条件才执行:
1.到达heap limited或者allocation fail
2.System.gc方法被调用
3.Concurrent mark 完成所有的工作
 
调大nursery尺寸会导致垃圾回收的停顿时间加长。
 
对于1GB的堆,如果进行了压缩动作,垃圾收集的暂停时间可能增加到40秒。
增量压缩技术就是将压缩动作分散到多次垃圾收集周期中,以减少暂停时间。 
-Xpartialcompactgc,表示每次垃圾收集都使用增量压缩,除非必须进行完整的压缩动作 
 
 
使用ibm的HeapAnalyzer查看aix的dump文件(jdk有个工具:jmap -dump:live,format=b,file=d:\java.dump pid),内存映射--------ha445.jar
heapdump.20130605.160859.24969368.0004.phd
 
使用ibm的Thread and Monitor Dump Analyzer for java查看aix的core文件(通过kill -3 pid获得),查看线程、内存等完整信息--------jca432.jar
javacore.20130604.171533.10027244.0011.txt
 
java -Xmx1000m -jar jca432.jar
 
jmap 的用途是为了展示java进程的内存映射信息,或者堆内存详情
使用命令:
jmap pid 打印内存使用的摘要信息
jmap -histo:live pid     展示class的内存情况,展示的信息为编号,实例数,字节,类名
jmap -heap pid           展示pid的整体堆信息
jmap -dump:live,format=b,file=d:\java.dump pid导出的文件可以供分析用,比如jhat或者mat、ha445.jar,以便查找内存溢出原因
 
 
Jstat是Sun JDK中自带的监控工具,利用了JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控等等
jstat -gcutil 7432 5000 10每隔5000ms采样一次,一共采样10次
C:\Documents and Settings\沈雷>jstat -gcutil 7432 5000 10
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
  0.00   0.00   0.00   1.41   3.13      0    0.000     3    0.887    0.887
 
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
 
如果FGC 过多,有必要调整下jvm参数。
 
 
 
 
F5负载均衡器简单的理解就是咱们通常称之四层交换机或七层交换机。同时也叫IP应用交换机
 
 
下载文件的按钮连点两次,页面上只会提示一个文件下载框,是第二次点击生成的文件
 
下载文件的文件保存框是resposne全部write完,还是开始写的时候就弹出来? 开始写
 
weblogic支持的最大http请求设置?
无法修改,可以通过在启动脚本增加如下参数,可以指定默认线程池的最小值、最大值:(http连接数)
-Dweblogic.threadpool.MinPoolSize=100 -Dweblogic.threadpool.MaxPoolSize=500
 
 
weblogic的http连接超时时间?
ueue: ‘billproxyqueue’ has been busy for “727″ seconds working on the request “Http Request: /bill/y
nQueryPublic.go”, which is more than the configured time (StuckThreadMaxTime) of “600″ seconds.>
一看明显是连接超时, 导致的错误.
1、程序问题,是不是程序中没有关闭连接
2、Configuration -》 Tuning  -》 Stuck Thread Max Time: 600
如果程序没问题,则是weblogic的StuckThreadMaxTime设置过小而引起的,
一般weblogic server 的StuckThreadMaxTime默认参数是600s,即10分钟,如果并发量过大,
而导致等待处理过多,导致系统不停的增加线程,造成线程阻塞,
你可以把该参数设置大点这个是稍微调大StuckThreadMaxTime的参数即可.
3、看线程数设置,可适当增加线程数,这个在WLS控制台中可以调整
 
 
java程序模拟发起http请求到多渠道时,需要设置cookie值:
bke_isvr=dLpbR0XCzYryDZtPBhBLZwpQLn51sQ234hC1rlpqv6ThVJMJTK8W!1476132340
否则管理会将链接到sso时返回一个登陆页面给java模拟程序。
 
 
jsp文件,weblogic编译的servlet结果。
路径:项目/com/maps/index.jsp
编译好的路径:isvrDomain/servers/IsvrServer/tmp/_WL_user/isvr_mngApp/dioh2x/jsp_servlet/_com/_map
该servlet class的类名:out.println("========"+this.getClass().getName());
结果:========jsp_servlet._com._maps.__index 
 
 
 
javac -verbose
java -verbose
 
 
DBPM服务端部在172.17.248.74   $HOME/shenlei/dbpm_j下
 
 
360在提交时会访问servlet两次:
https://172.17.248.181:7002/isvr/FileDownLoad?subjectId=080701&STAT_DT_STAT=20130617&STAT_DT_END=20130617
 
 
设置下载文件的大小:
response.setHeader("content-length", String.valueOf(filelen));
 
 
HTTP头的一些信息:
System.out.println("*******************************begin****************************************");
System.out.println("Protocol: " + request.getProtocol() );
System.out.println("Scheme: " + request.getScheme() );
System.out.println("Server Name: " + request.getServerName()  );
System.out.println("Server Port: " + request.getServerPort() );
System.out.println("Protocol: " + request.getProtocol() );
System.out.println("Server Info: " + getServletConfig().getServletContext().getServerInfo()); 
System.out.println("Remote Addr: " + request.getRemoteAddr() );
System.out.println("Remote Host: " + request.getRemoteHost() );
System.out.println("Character Encoding: " + request.getCharacterEncoding() );
System.out.println("Content Length: " + request.getContentLength() );
System.out.println("Content Type: "+ request.getContentType() );
System.out.println("Auth Type: " + request.getAuthType() );
System.out.println("HTTP Method: " + request.getMethod() );
System.out.println("Path Info: " + request.getPathInfo() );
System.out.println("Path Trans: " + request.getPathTranslated() );
System.out.println("Query String: " + request.getQueryString() );
System.out.println("Remote User: " + request.getRemoteUser() );
System.out.println("Session Id: " + request.getRequestedSessionId() );
System.out.println("Request URI: " + request.getRequestURI() );
System.out.println("Servlet Path: " + request.getServletPath() );
System.out.println("Accept: " + request.getHeader("Accept"));
System.out.println("Host: " + request.getHeader("Host") );
System.out.println("Referer : " + request.getHeader("Referer") );
System.out.println("Accept-Language : " + request.getHeader("Accept-Language"));
System.out.println("Accept-Encoding : " + request.getHeader("Accept-Encoding") );
System.out.println("User-Agent : " + request.getHeader("User-Agent") );
System.out.println("Connection : " + request.getHeader("Connection") );
System.out.println("Cookie : " + request.getHeader("Cookie") );
System.out.println("Created : " + request.getSession().getCreationTime() );
System.out.println("LastAccessed : " + request.getSession().getLastAccessedTime() );
System.out.println("*******************************end****************************************");
 
 
jsp中文乱码三句话:
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>  
<%@page contentType="text/html;charset=gb2312"%>  
<%request.setCharacterEncoding("gb2312");%>  
 
在filter中设置request.setCharacterEncoding("gb2312");只支持post提交的信息,对于GET方式的提交在jsp中显示的方法是:
1、new String(request.getParameter("titleNm").getBytes("ISO8859-1"),"UTF-8"));
2、或者在/upjas/upjas-minimal/server/default/deploy/jbossweb.sar/server.xml中设置:
< Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK" />
 
upjas页面乱码修改了:
SetCharacterEncoding
web.xml
 
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (ignore || request.getCharacterEncoding() == null) {
String encoding = selectEncoding(request);
if (encoding != null) {
request.setCharacterEncoding(encoding);
}
}
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String tmpUrl = req.getRequestURI();
String queryString = req.getQueryString();
if (!StringUtil.isEmpty(queryString)&&queryString.contains("titleNm")) {
queryString = new String(queryString.getBytes("ISO8859-1"), "UTF-8");
tmpUrl = tmpUrl.substring(5)+"?"+queryString;
req.getRequestDispatcher(tmpUrl).forward(req, resp);
return;
}
chain.doFilter(request, response);
}
 
 
jboss上查看ejb和数据源是否部署成功:
http://localhost:端口/jmx-console/ 
左边菜单的jboss链接,然后选 service=JNDIView, 点击 list 下面的 invoke 看一看现在 jboss 的 jndi 里面都有哪些对象
直接看最下面的 global 部分就可以了,看看有没 有定义的Namespace
如果有,那就说明部署成功了,调用应该就没有问题了
 
 
http头增加了Content-Type:application/x-www-form-urlencoded;charset=UTF-8,而不是Content-Typeapplication/x-www-form-urlencoded时,
jboss能自动转换字符,而在filter中设置request.setCharacterEncoding(encoding);不起作用。
 
 
 
 
spring加载配置文件 
1、把applicationContext.xml直接放在WEB-INF/classes下,spring会采用默认的加载方式
2、采用在web.xml中配置ContextLoaderListenera或ContextLoaderServlet指定加载路径方式。
3 通过ClassPathXmlApplicationContext或XmlWebApplicationContext代码动态加载!
 
 
 
对 HTTP 304 的理解:
304 的标准解释是:Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。
服务器告诉客户,原来缓冲的文档还可以继续使用。看下面的http请求,里面的If-Modified-Since
GET /test/bar.emf HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Accept-Encoding: gzip, deflate
If-Modified-Since: Fri, 28 Jun 2013 08:24:04 GMT
If-None-Match: W/"3952-1372407844254"
Connection: Keep-Alive
Host: 172.17.236.121:8080
 
 
apache反向代理:
修改Apache2.2\conf\httpd.conf配置
1.先去掉下面两行的注释
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
2.然后在最后增加
<VirtualHost localhost:80>#此处localhost:80为当前apache服务的 ip:port
ProxyPass / http://www.baidu.com
ProxyPassReverse / http://www.baidu.com
</VirtualHost>
 
那么浏览器访问http://localhost/img/bdlogo.gif , apache会将请求转发到:http://www.baidu.com/img/bdlogo.gif
 
 
例如使用apache作为域名www.test.com代理服务器,让其暴露在公网上,即DNS解析到本机器上,真正提供web服务器的是另一台位于同一内网的机器上,假设起IP是192.168.100.22,那么只需要如下配置就可以了。
ProxyPass / http://192.168.100.22/
ProxyPassReverse / http://192.168.100.22/
ProxyPass 很好理解,就是把所有来自客户端对http://www.test.com的请求转发给http://192.168.100.22上进行处 理,ProxyPassReverse 的配置总是和ProxyPass 一致,但用途很让人费解。似乎去掉它很能很好的工作,事实真的是这样么,其实不然,如果响应中有302重定向,ProxyPassReverse就派上用 场。举例说明,假设用户访问http://www.test.com/exam.php,通过转发交给http://192.168.100.22 /exam.php处理,假定exam.php处理的结果是实现redirect到login.php(使用相对路径,即省略了域名信息),如果没有配置 反向代理,客户端收到的请求响应是重定向操作,并且重定向目的url为http://192.168.100.22/login.php ,而这个地址只是代理服务器能访问到的,可想而知,客户端肯定是打不开的,反之如果配置了反向代理,则会在转交HTTP重定向应答到客户端之前调整它为 http://www.test.com/login.php,即是在原请求之后追加上了redirect的路径。当客户端再次请求http: //www.test.com/login.php,代理服务器再次工作把其转发到http://192.168.100.22/login.php。
客户端到服务器称之为正向代理,那服务器到客户端就叫反向代理。
 
 
apache利用mod_cache缓存图片:
在httpd.conf中打开mod_cache,然后:
1、内存:
<IfModule mod_cache.c>  
LoadModule mem_cache_module modules/mod_mem_cache.so  
<IfModule mod_mem_cache.c>  
CacheEnable mem /images  
MCacheSize 4096  
MCacheRemovalAlgorithm LRU  
MCacheMaxObjectCount 100  
MCacheMinObjectSize 1  
MCacheMaxObjectSize 2048  
CacheMaxExpire 864000  
CacheDefaultExpire 86400  
CacheDisable /php  
</IfModule>  
</IfModule>  
2、硬盘:
<IfModule mod_cache.c>
LoadModule disk_cache_module modules/mod_disk_cache.so
CacheDefaultExpire: 3600                     #指定快取的预设过期秒数;默认值是一小时 (3600)。
CacheMaxExpire: 86400                        #指定快取最大的过期秒数;默认值是一天 (86400)。
<IfModule mod_disk_cache.c>
CacheRoot d:/cachetest
#CacheSize 256
CacheEnable disk /
CacheDirLevels 4
#CacheMaxFileSize 64000
#CacheMinFileSize 1
#CacheGcDaily 23:59
CacheDirLength 3
</IfModule>
 
 
如何知道已经安装上的unix系统是否有cc编译器?
cc -v
 
cc 1.c 
没有指定可执行文件的名字,系统会自动生成可执行文件a.out。这个可执行文件的名字是系统自动生成的。默认情况下就是a.out
 
可执行文件的名字管理?
cc -o 1 1.c
 
编译多个c语言源程序文件
cc -o 2 1.c 2.c
cc -o 2 1.o 2.c
 
系统会编译源程序代码文件,并生成对应的目标文件.o。但是不会把目标文件链接成可执行文件,即使存在main函数的情况下
cc -c 1.c
会生成1.o
 
 
SERVER系统(例如WINDOWS 2003或者2008)安装邮件服务器
XP系统不支持安装微软的Exchange邮件服务器(Exchange要求开启IIS+ASP+SMTP+NNTP服务,关键是还要求局域网内有电脑安装域控,XP只能装IIS服务),
某些第三方邮件服务器软件(Web方式的)可以支持
 
 
 
在向eclipse的jar包中导入了javadoc后,编写程序的过程中使用jar包中的方法时Eclipse会自动显示其注释说明,可以大大提高开发人员的效率。
在向eclipse的jar包中导入了source后,Eclipse将可以显示类的源代码,并且同时具有了导入javadoc的显示功能。
 
 
 
使用eclipse的时候,突然发现eclipse中按Alt+/ 后,代码智能感应不能出现?
解决:
从eclipse进入Window-Preferences-General-Keys。找到Content Assist,会发现快捷键是“ctrl+space”,这与windows系统的默认中英输入法切换快捷键冲突了,
需要修改,先Remove Binding,然后改为“alt+.”就可以了。它可以帮你联想到所有的类供你选择。
另:“word completion”的快捷键使用“alt+/”,它可以自动帮你补全类名。
 
 
在eclipse中打开jsp文件时出现An error has occurred.see error log for more details错误?
解决:进入打开cmd(命令提示符)Eclipes目录下,输入eclipse.exe -clean           待Eclipse启动后,即可打开编辑jsp页面
 
 
ejb以jar形式在jboss中发布后,jar包中的类可以直接被同时发布的war包中new出。
 
 
JBOSS5中ejb Stateless bean的开发:
Stateless的属性:mappedName不能与实现的类名相同,否则会报下面的错。name属性随便。
Caused by: org.jboss.aop.DispatcherConnectException: EJB container is not completely started, or is stopped.
 
如果不设置mappedName的话,客户端调用使用lookup("CompanySessionBean/remote"),
本地(ejb中调用ejb)使用remote和local都可以,不过使用remote费时:
lookup("CompanySessionBean/local")或者lookup("CompanySessionBean/remote")
 
 
在客户端中访问stateless bean时需要Properties,且使用Company/remote标志,如:
Properties prop = new Properties();
prop.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
prop.setProperty(Context.PROVIDER_URL, url);
prop.setProperty(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
InitialContext ctx = new InitialContext(prop);
DepartmentRemote dr = (DepartmentRemote)ctx.lookup("DepartmentRemote");
System.out.println(dr.getDepName("Company"));
 
在ejb中访问ejb不需要如此麻烦,不需要Properties和/remote:
InitialContext ctx = new InitialContext();
CompanyRemote companyRemote = (CompanyRemote) ctx.lookup("CompanyRemote");
System.out.println(companyRemote.getName());
 
 
--原子服务(函数),用于组装用于组装原子交易的基本单位,本表定义了原子服务的函数名、所属动态链接库等参数供联机处理时定位实际的业务处理函数
select * from TBL_MAPS_GFS_ATOM_SVR_INF;
select * from TBL_MAPS_GFS_ATOM_TRANS_SVC_RELATED;--配置每个流程服务处理的原子交易列表
select * from TBL_MAPS_GFS_FLOW_SVC_ATOM_TRANS_RELATED;--记录需要属于指定的原子交易
select * from TBL_MAPS_GFS_FLOW_SVC_INF;--邮箱号
 
 
--多渠道平台向外部系统的原发请求交易,根据交易信息源代码、采用的报文规范类型、商户代码等参数查找外部交易码及其对应的报文格式转换相关信息
select * from TBL_MAMGM_MSG_FMT_CONV_MTO;
select * from TBL_MAPS_GFS_FMT_GRP;--平台打解包格式转换组编号
 
 
jboss热部署,在deploy中web部署的context.xml中修改如下:
<Context cookies="true" crossContext="true" antiResourceLocking="false " antiJARLocking="false ">
 
 
操作系统通过文件系统管理文件及数据,磁盘或分区需要创建文件系统后才能为操作系统使用,创建文件系统的过程又称为格式化。
 
cpu 4.2g的意思是:每秒能处理4.2*1000*1000*1000次指令。
DDRIII1333的速度读取大概在8到9G左右,写的速度大概在7到8G左右。
普通硬盘的读取速度大概是100M/S左右,而固态硬盘的读取速度则是250M/S
 
 
关闭employee表的约束性检查
db2 set integrity for employee off
 
oracle中建立延迟约束,提交时才做约束检查
ALTER TABLE MV_T ADD CONSTRAINT UN_MV_T_NAME UNIQUE (NAME) DEFERRABLE;
 
db2 import数据时出错:
SQL3120W  The field value in row "22370" and column "1" cannot be converted to 
an INTEGER value, but the target column is not nullable.  The row was not 
loaded.
解决:如果字段值里面含回车换行的,如果以del形式export之后,import导入时都会出现这个问题。换成ixf二进制格式就没有问题了。导入速度还快。
 
 
有没有在vi 编辑文件过程中刷新命令(请高手赐教)?
解决:使用“:e”可以刷新
 
 
函数原型
void *memcpy(void *dest, const void *src, size_t n);
 
 
 
pcap抓包文件使用Wireshark打开
 
 
SimpleDateFormat的毫秒级表示S:yyyy-MM-dd hh:mm:ss SSS
 
 
jdk自带工具jvisualvm来查看线程
 
new ExecutorFilter()中调用了init(executor, MANAGEABLE_EXECUTOR),然后调用initEventTypes(IoEventType... eventTypes),由于eventTypes为null,因此eventTypes = DEFAULT_EVENT_SET默认所有的IoEventType。
 
 
list.remove()会影响list中后面的取值。
 
jboss服务器上临时tmp目录:
/maps/usr/ma_mgm/shenlei/upjas/upjas-minimal/server/default/tmp/4sh702j-fmwloa-hkaiefdh-1-hkaigw6d-al/maps.war/com/cup/maps/portal/jpf/flex
 
 
aix上解压zip文件
/usr/java6_64/bin/jar -xvf upjas.zip
 
 
export CVSROOT=:pserver:leishen@172.17.249.63/cvsnew2
cvs login
cvs update -r V[1][0][1] UPJAS
 
 
 
F5负载均衡获取客户端真实ip?
首先需要在F5上配置X-Forwarded-For,然后可以通过获取"x-forwarded-for";来获取客户端的IP地址。
具体步骤:
1:Local Traffic-Profiles-Http-改“Insert XForwarded For”为Enable
2:Local Traffic-Virtual servers-点击需要改动的VS-将Type选项更改为Standard-将HTTP Profile 选项更改为Http
 
 
final_str = new String(final_str.getBytes("iso8859-1"), "gbk");
getbytes:表示编码,是指将内存中utf-16(unicode)编码的char,通过计算得到以iso8859-1表示的字节数组,
就是把一个字符char(2位)转换成若干位的过程(比如utf-8,有可能是1或者2或者3位)
newString中的gbk表示解码,是指将字节数组按照gbk的编码方式,如2个字节为一位,按照固定算法,转换成utf-16表示的char
 
 
 
 
e.printStace()没有打到server.log中的原因是不能存在两个log4j.properties。
 
 
[org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Msg'.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:505)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:206)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:184)
at jaxb.Testunmarshallerxml.unmarshallerXml(Testunmarshallerxml.java:82)
at jaxb.Testunmarshallerxml.main(Testunmarshallerxml.java:45)
解决:
 
 
[org.xml.sax.SAXParseException: Premature end of file.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:505)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:206)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:184)
at jaxb.Testunmarshallerxml.unmarshallerXml(Testunmarshallerxml.java:82)
at jaxb.Testunmarshallerxml.main(Testunmarshallerxml.java:45)
解决:u.unmarshal(fisNetwork);传入的输入流InputStream已至流的末尾。
 
 
 
在dbvisualize里面直接修改db2的某个字段,如果字符串中含有||那么dbvisualize在保存时会自动计算值,但是写sql执行则不会。
 
 
 
用32位还是64位JDK编译出来的Class文件没区别
 
linux上中文显示乱码?
执行 locale -a 查看系统是否已安装utf-8字符集
执行 export LANG=zh_CNexport LC_ALL=zh_CN.utf8设置本地语言环境为utf-8
如果终端(如SecureCRT)编辑脚本时出现乱码,请设置 Menu | Options | Session Options... | Appearence | Character 为utf-8
 
2、LC_CTYPE
用于字符分类和字符串处理,控制所有字符的处理方式,包括字符编码,字符是单字节还是多字节,如何打印等。是最重要的一个环境变量。
 
项目中log4j在英文版linux下输出中文日志为乱码?
由于log4j配置文件中没有设置编码格式(encoding),所以log4j就使用系统默认编码。导致乱码。
解决方法是设置编码格式UTF-8,方法为:
log4j.appender.syslog.encoding=UTF-8
(syslog为你的logger名称)这样就可以了
 
 
没有泛型数组一说
Pair<String>[] stringPairs=new Pair<String>[10];
这种写法编译器会指定一个Cannot create a generic array of Pair<String>的错误
 
 
org.apache.commons.codec.binary.Hex
.encodeHexString()
.decodeHex()
 
 
使用AES加密时,当密钥大于128时,代码会抛出java.security.InvalidKeyException: Illegal key size or default parameters
Illegal key size or default parameters是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件。文件位于${java_home}/jre/lib/security
这种限制是因为美国对软件出口的控制。
解决办法:
去掉这种限制需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.网址如下。
下载包的readme.txt 有安装说明。就是替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar
jdk 5: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR
jdk6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
 
 
数字签名算法是非对称加密算法和消息摘要算法的结合体。要求能够验证数据完整性、认证数据来源、抗否认。
 
 
S6209: [函数/调用]EventGetIntTransIdInf获取内部交易码信息失败,ilRc = [100]!
TBL_MAMGM_EVENT_SVC_CFG少参数
 
 
252.86有的浏览器无法访问,原因是86上不支持TLS1.0协议,把server.xml改掉之后就正常了
<Connector protocol="HTTP/1.1" SSLEnabled="true" ^M
           port="11009" address="${jboss.bind.address}"^M
           scheme="https" secure="true" clientAuth="false" ^M
           keystoreFile="${jboss.server.home.dir}/conf/server.keystore" keystorePass="123456" keystoreType="jks" ^M
           sslProtocol = "SSL" />
     
     
upjas,jms的MDB默认有15个线程在处理,该池不会增大
解决:在default\deploy\hornetq\jms-ds.xml文件中<max-pool-size>20</max-pool-size>
指定了jms的线程池大小
 
 
代码表两个:
TBL_MAMGM_FILTER_APP_CATA
TBL_MAMGM_FILTER_RULE_GRP_CATA
 
TBL_MAMGM_FILTER_APP_INF 过滤应用信息表
TBL_MAMGM_FILTER_APP_DET 过滤应用确定表,定义了包含多个过滤条件组
 
TBL_MAMGM_FILTER_RULE_GRP_INF  RULE_TP 'S'-唯一过滤条件 'R'-范围过滤条件; BLKBILL_IN ‘W’-白名单 'B'-黑名单
TBL_MAMGM_FILTER_RULE_DET 定义了每个过滤条件组的具体取值
 
根据内部交易类型获取控制规则 控制规则检查 
 
 
银行卡共有三个磁道:
一磁道 只读 信息量79位
二磁道 只读 信息量40位
三磁道 读写 信息量107位
国内银联卡的磁道格式说明:
磁道1. “%” + “99(2N)” + “16位卡号(19A)” + “^” + “凸字姓名(26A)” + “^” + “expiry_date YYMM(4N)” + “101或者501(PRMCD.SERV-CODE)” + “CARD.PVV
(5N)” + “0000000000(10N)” + “CVV(3A)” + “00(2N)”+”?”&#61664;共78位数
 
磁道2. “;” + “16位卡号(19A)” + “=” + “expiry_date YYMM(4N)” + “106(3N,服务代码)” + “PVV(5N)” + “00(2N)” + “CVV(3A)” + “?”&#61664;共39位数
 
磁道3. “;” + “99(2N)” + “16位卡号(19A)” + “=” + “156(国家代码3N) ” 
+ “156(货币代码3N) ” + “000000000(金额指数1N&周期授权量4N&本周期余额4N) ” 
+ “000000(周期开始日期4N&周期长度2N) ” + “30000000(密码重输次数1N&个人授权控
制参数6N&交换控制符1N) ” + “000000(PAN的TA和SR& SAN-1的TA和SR& SAN-2的TA和SR
,各2N) ” + “expiry_date YYMM(4N) ” + “0(卡序列号1N) ” + “=” + “0000000
00000(SAN-1,12A) ” + “=” + “000000000000(SAN-2,12A) ” + “=” + “1(传递标
志1N) ” + “000000(加密校验数6N) ” + “00000000(附加数据8N) ” + “?”&#61664;共106位数
 
 
 
委托关系-》
TBL_MAONL_PMT_ENTRUST_INFXX表,共10张
USR_NO
USR_NO_TP
USR_NO_REGION_CD
USR_NO_REGION_ADDN_CD
上面四个字段去找TBL_MAMGM_USR_NO_BIN表,找到后端商户PARENT_MCHNT_CD,然后去商户表找到行业机构代码INDUSTRY_INS_ID_CD,再去找TBL_MAMGM_COMM_LINE_CFG获得链路,发送出去
PMT_NOTV30100101
PMT_NO_TPGD
PMT_ACCT_NO955800000000000001
PMT_ACCT_TPCD-银行卡
支付号码、支付号码类型、账户号码、账户类型
ENTRUST_ACQ_INS_ID_CD00280000   
ENTRUST_TERM_IDTERN0LYC
ENTRUST_MCHNT_CD898320154110210
ENTRUST_ACPT_INS_CD_ID00280000   
委托的渠道接入机构、终端、商户、受理机构代码
 
 
 
配置完成后读者可以通过访问: http://localhost:8088/jmx-console/ ,
输入jmx-console-roles.properties文件中定义的用户名和密码,访问jmx-console的页面。
 
 
 
 
response.sendRedirect向浏览器发送一个特殊的Header,然后由浏览器来做转向,转到指定的页面,所以用sendRedirect时,浏览器的地址栏上可以看到地址的变化
1、response.sendRedirect之后,应该紧跟一句return;
2、在使用response.sendRedirect时,前面不能有HTML输出
用<jsp:forward page=""/>则不同,它是直接在server做的,浏览器并不知道,也不和浏览器打交道,这从浏览器的地址并不变化可以看
 
 
 
会计里面借记什么贷记什么?
这个要根据科目的性质来判断:资产类借方记增加贷方记减少,负债类借方记减少贷方记增加,权益类借方记减少贷方记增加,收入和费用类借减贷加
 
 
JSP中包含swf文件,给swf传的参数中不能包括下划线 _
 
<param name="FlashVars" value="titleNm=<%=request.getParameter("titleNm")%>&syncBatNo=<%=request.getParameter("sync_bat_no")%>&paraTp=<%=request.getParameter("para_tp")%>" />
比如syncBatNo不能写成sync_Bat_No
这样在swf中就可以用如下方法取得值:
private var paratype : String;
paratype =  Application.application.parameters["paraTp"];
 
 
 Flex代码:在Flex中这样取其中obj 即是Java返回的Map
//输出格式为key:value  
for (var itemName:Object in obj){  
       trace(itemName+":"+obj[itemName])  
}  
//输出的只是value             
for each(var itemValue:Object in obj){  
      trace(itemValue.toString())  
}
 
 
 
打印cookie的值:
Cookie[] cs = request.getCookies();
if(cs!=null)
for(Cookie c: cs){
logger.info("c.getComment()="+c.getComment());
logger.info("c.getDomain()="+c.getDomain());
logger.info("c.getMaxAge()="+c.getMaxAge());
logger.info("c.getName()="+c.getName());
logger.info("c.getPath()="+c.getPath());
logger.info("c.getSecure()="+c.getSecure());
logger.info("c.getValue()="+c.getValue());
logger.info("c.getVersion()="+c.getVersion());
logger.info("########################################");
}
新增cookie
Cookie newCook = new Cookie("HOMEPAGESTYLE","1");
newCook.setPath("/isvr");
newCook.setMaxAge(3600*24*365);
response.addCookie(newCook);
没有修改cookie的方法,只可以再addCookie一次
删除cookie就是:newCook.setMaxAge(0);
 
 
 
 
weblogic10默认连接池个数是在config/jdbc/中配置的,最小1,最大100
   <initial-capacity>1</initial-capacity>
    <max-capacity>100</max-capacity>
 
upjas的数据库连接池个数是在vi upjas_tunning_setEnv.sh中配置
MIN_POOL_SIZE=100                    # initial count of db connections
MAX_POOL_SIZE=100                    # max count of db connections
 
db2数据的最大连接个数如下查看
1、db2实例
db2 get dbm cfg
--MAX_CONNECTIONS=AUTOMATIC(MAX_COORDAGENTS)
--MAX_COORDAGENTS=AUTOMATIC(200)
 
两值被设置成 AUTOMATIC,认为db2系统可以承受所有的连接:
db2 update dbm cfg using MAX_COORDAGENTS AUTOMATIC;
db2 update dbm cfg using MAX_CONNECTIONS AUTOMATIC;
 
2、db2数据库
db2 connect to dbname user username  using  passwd
db2 get db cfg
--Max number of active applications            (MAXAPPLS) = AUTOMATIC(323)
 
通过如下命令修改:
db2 update db cfg using MAXAPPLS  number
 
通过这个命令db2 get snapshot for dbm可以看到目前db2连接池的最高个数
High water mark for agents registered          = 12
Agents registered                              = 5
Idle agents                                    = 4
 
 
 
 
db2 "export to ETL_MAMGM_POS_PARA_INF.ixf of ixf select * from MA_MGMDB.ETL_MAMGM_POS_PARA_INF"
 
db2 "import from ETL_MAMGM_POS_PARA_INF.ixf of ixf REPLACE into MA_MGMDB.ETL_MAMGM_POS_PARA_INF"
INSERT | INSERT_UPDATE | REPLACE | REPLACE_CREATE
db2 connect to mamgmdb user maps_db using glbpoc0
 
 
 
248.188 回导多渠道商户终端参数ismgmdb
db2 connect to ISMGMDB user isvrdb3 using isvrdb3
db2 list tablespaces show detail
 
db2 import from MA_ONLDB.TBL_MAONL_TERM_STATIC_INF.ixf of ixf replace into IS_MGMDB.TBL_MAONL_TERM_STATIC_INF
db2 import from MA_ONLDB.TBL_MAONL_MCHNT_STATIC_INF.ixf of ixf replace into IS_MGMDB.TBL_MAONL_MCHNT_STATIC_INF
db2 runstats on table IS_MGMDB.TBL_MAONL_MCHNT_STATIC_INF
db2 runstats on table IS_MGMDB.TBL_MAONL_TERM_STATIC_INF
 
db2 import from MA_MGMDB.TBL_MAMGM_MCHNT_STATIC_INF.ixf of ixf commitcount 10000 replace into IS_MGMDB.TBL_MAMGM_MCHNT_STATIC_INF
db2 import from MA_MGMDB.TBL_MAMGM_TERM_STATIC_INF.ixf of ixf commitcount 10000 replace into IS_MGMDB.TBL_MAMGM_TERM_STATIC_INF
db2 runstats on table IS_MGMDB.TBL_MAMGM_MCHNT_STATIC_INF
db2 runstats on table IS_MGMDB.TBL_MAMGM_TERM_STATIC_INF
 
 
 
让datagrid可以文本选择:
http://stackoverflow.com/questions/1431574/flex-selectable-text-in-datagridcolumn
 
文件SelectableDataGridItemRenderer.as
package com.cup.isvr.view.grid
{
    import mx.controls.dataGridClasses.DataGridItemRenderer;
 
    public class SelectableDataGridItemRenderer extends DataGridItemRenderer
    {
        public function SelectableDataGridItemRenderer()
        {
            super();
            this.selectable = true;
        }
    }
}
用法:
<chkGrid:CheckboxDataGrid itemRenderer="com.cup.isvr.view.grid.SelectableDataGridItemRenderer" id = "dataGrid" width = "100%"  height = "100%" itemClick="ControlUtil.toggleSelected(event)"  doubleClickEnabled="true" itemDoubleClick="dbClicked(event)"/>
 
 
 
Eclipse 3.1 版本代号 IO 【木卫1,伊奥】  
Eclipse 3.2 版本代号 Callisto 【木卫四,卡里斯托】  
Eclipse 3.3 版本代号 Eruopa 【木卫二,欧罗巴】 2007  
Eclipse 3.4 版本代号 Ganymede 【木卫三,盖尼米德】 2008 
Eclipse 3.5 版本代号 Galileo 【伽利略】 2009
Eclipse 3.6 版本代号 Helios 【太阳神】(太阳之神and泰坦海泼里恩之子;阿波罗的后任.) 2010
Eclipse 3.7 版本代号 Indigo 【靛青】 2011
Eclipse 4.2 版本代号 Juno (朱诺(主神朱庇特的妻子), 鸿运当头) 2012
Eclipse 4.3 版本代号 Kepler 2013.6
 
 
 
如何使用JBPM5.4
1、下载Eclipse3.6 Helios,注意启动前修改eclipse.ini最后一行-Xmx256m改成-Xmx128m。
2、下载jbpm-5.4.0.Final-installer-full.zip(http://sourceforge.net/projects/jbpm/files/jBPM%205/jbpm-5.4.0.Final/)
3、解压jbpm-5.4.0.Final-installer-full\jbpm-installer\lib\org.drools.updatesite-5.5.0.Final-assembly.zip,将org.drools.updatesite-5.5.0.Final-assembly目录
拷贝到D:\eclipse3.6\dropins下
4、解压jbpm-5.4.0.Final-installer-full\jbpm-installer\lib\jbpm-5.4.0.Final-bin.zip放入某一目录,
重启eclipse后,在windows-preferences-jbpm-installed jbpm runtime中设置运行环境。
5、新建JBPM工程
 
 
 
 
 
命令行处理器选项设置查询
db2 list command options
 
设置自动提交为off
db2 update command options using c off
 
 
 
2014-01-24 09:35:39,306 [Thread-102852] ERROR com.cup.mtq.comm.mina.entity.tcp.MinaClient -     
java.lang.NoClassDefFoundError: org/apache/mina/core/future/DefaultConnectFuture                
        at org.apache.mina.core.polling.AbstractPollingIoConnector.connect0(AbstractPollingIoCon
nector.java:323)                                                                                
        at org.apache.mina.core.service.AbstractIoConnector.connect(AbstractIoConnector.java:248
)                                                                                               
        at org.apache.mina.core.service.AbstractIoConnector.connect(AbstractIoConnector.java:186
)                                                                                               
        at com.cup.mtq.comm.mina.entity.tcp.MinaClient.connect(MinaClient.java:72)              
        at com.cup.mtq.comm.mina.entity.tcp.MinaClient.connect(MinaClient.java:37)              
        at com.cup.mtq.comm.mina.manager.SysMinaLinkCacheManager$MinaClientLinkReconnectThread.r
un(SysMinaLinkCacheManager.java:455)
解决:重启就好了
 
 
2014-03-04 10:42:52,139 [Thread-64] ERROR com.cup.mtq.comm.mina.entity.tcp.MinaClient - 
java.lang.IllegalStateException: Waiting too long to get the classloader lock: BaseClassLoader@6f876f87{vfszip:/MAMGMAPS/usr/ma_mgmas/upjas/upjas-minimal/server/default/cup-deploy/mjc.war/}
at org.jboss.classloader.spi.base.BaseClassLoader.acquireLockFairly(BaseClassLoader.java:1106)
at org.jboss.classloader.spi.base.BaseClassLoader.loadClassFromDomain(BaseClassLoader.java:838)
at org.jboss.classloader.spi.base.BaseClassLoader.doLoadClass(BaseClassLoader.java:502)
at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:447)
at java.lang.ClassLoader.loadClass(ClassLoader.java:619)
at org.apache.mina.core.polling.AbstractPollingIoConnector.connect0(AbstractPollingIoConnector.java:323)
at org.apache.mina.core.service.AbstractIoConnector.connect(AbstractIoConnector.java:248)
at org.apache.mina.core.service.AbstractIoConnector.connect(AbstractIoConnector.java:186)
at com.cup.mtq.comm.mina.entity.tcp.MinaClient.connect(MinaClient.java:72)
at com.cup.mtq.comm.mina.entity.tcp.MinaClient.connect(MinaClient.java:37)
at com.cup.mtq.comm.mina.manager.SysMinaLinkCacheManager$MinaClientLinkReconnectThread.run(SysMinaLinkCacheManager.java:455)
解决:jboss内存设置的比较小。或者环境中cpu或内存不够。
 
 
 
安装eclipse的jquery插件:
1、Help - Find and Install :从remote site中安装插件http://www.spket.com/update/
2.下载jQuery文件,(要下载开发版本). 
3. 设置spket ,Window -> Preferences -> Spket -> JavaScript Profiles -> New,输入“jQuery”点击OK; 
选择“jQuery” 并点击“Add Library”然后在下拉条中选取“jQuery”; 选择 “jQuery”并点击“Add File”,然后选中你下载的jQuery.js 文件;设成Default; 
4.设置js打开方式 (这一步很重要,不设置的话,也不会有jQuery的智能提示),
 Window -> Preferences ->General-> Editors-> File Associations-> 选择*.js,将Spket JavaScript Editor设为Default。 
 
 
xp中保存操作系统的DNS缓存记录
C:\WINDOWS\system32\drivers\etc\hosts
 
 
 
2014-02-21 09:51:50,472 [http-172.17.248.74-11009-4] ERROR com.cup.maps.parameter.sync.ActivationRequester - Parameter change activa
tion failed: can not deliver activation request to ParameterEvent MDB
javax.jms.JMSException: Failed to create session
        at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSessionInternal(ClientSessionFactoryImpl.java:864)
        at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSession(ClientSessionFactoryImpl.java:279)
        at org.hornetq.jms.client.HornetQConnection.createSessionInternal(HornetQConnection.java:513)
        at org.hornetq.jms.client.HornetQConnection.createSession(HornetQConnection.java:161)
        at com.cup.maps.parameter.sync.ActivationRequester.activateForCommonParaSync(ActivationRequester.java:172)
        at com.cup.maps.parameter.command.ActivateCommand.sendQueue(ActivateCommand.java:81)
        at com.cup.maps.parameter.command.ActivateCommand.forwardOthers(ActivateCommand.java:71)
        at com.cup.maps.parameter.command.AbstractCommand.execute(AbstractCommand.java:70)
        at com.cup.maps.parameter.ParameterServiceBean.operTask(ParameterServiceBean.java:871)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
        at org.jboss.ejb3.interceptors.container.ContainerMethodInvocationWrapper.invokeNext(ContainerMethodInvocationWrapper.java:7
2)
        at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorSequencer.java:76)
        at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(InterceptorSequencer.java:62)
        at sun.reflect.GeneratedMethodAccessor300.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:174)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(InvocationContextInterceptor.java:72)
        at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_fillMethod_549265597.invoke(Invocatio
nContextInterceptor_z_fillMethod_549265597.java)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:88)
        at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_549265597.invoke(InvocationCont
extInterceptor_z_setup_549265597.java)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:62)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:56)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:68)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
 
        at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:68)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
        at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:182)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.interceptor.EJB3TCCLInterceptor.invoke(EJB3TCCLInterceptor.java:86)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:363)
        at org.jboss.ejb3.remoting.IsLocalInterceptor.invokeLocal(IsLocalInterceptor.java:88)
        at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:75)
        at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
        at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
        at $Proxy275.invoke(Unknown Source)
        at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java
:188)
        at $Proxy295.operTask(Unknown Source)
        at com.cup.maps.portal.flex.ParameterFlexFacade.batchOperTask(ParameterFlexFacade.java:772)
        at com.cup.maps.portal.flex.ParameterFlexFacade$$FastClassByCGLIB$$2305f44f.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
        at com.cup.maps.common.AuthPermission.checkAccess(AuthPermission.java:67)
        at sun.reflect.GeneratedMethodAccessor449.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
        at com.cup.maps.portal.flex.ParameterFlexFacade$$EnhancerByCGLIB$$ee5b83a3.batchOperTask(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:421)
        at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
        at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1503)
        at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:884)
        at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
        at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
        at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)
        at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
        at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
        at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:278)
        at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:322)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 
        at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:322)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at com.cup.maps.portal.common.filter.SessionFilter.doFilter(SessionFilter.java:94)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at edu.yale.its.tp.cas.client.filter.CASFilter.doFilter(CASFilter.java:221)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:183)
        at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:95)
        at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
        at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.internalProcess(ActiveRequestResponseCacheValve.java
:74)
        at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:47)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:599)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:451)
        at java.lang.Thread.run(Thread.java:736)
Caused by:
HornetQException[errorCode=0 message=Failed to create session]
        ... 129 more
Caused by:
java.lang.IllegalStateException: Connection is null
        at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSessionInternal(ClientSessionFactoryImpl.java:745)
        ... 128 more
原因是jms的connection的session失效了
 
 
 
server.log里面报错:
21 Feb 2014 16:53:21,965 TRACE [org.jboss.management.j2ee.MBean] Failed to initialize state from: 'jboss.jmx:type=adaptor,name=Invok
er,protocol=jrmp,service=proxyFactory' : javax.management.InstanceNotFoundException : jboss.jmx:type=adaptor,name=Invoker,protocol=j
rmp,service=proxyFactory is not registered.
21 Feb 2014 16:53:21,965 DEBUG [org.jboss.management.j2ee.deployers.ServiceModuleJSR77Deployer] Create MBean, name: jboss.jmx:type=a
daptor,name=Invoker,protocol=jrmp,service=proxyFactory, SAR Module: jboss.management.local:J2EEServer=Local,j2eeType=ServiceModule,n
ame=jmx-invoker-service.xml
21 Feb 2014 16:53:21,967 DEBUG [org.jboss.management.j2ee.MBean] postRegister(), parent: jboss.management.local:J2EEServer=Local,j2e
eType=ServiceModule,name=jmx-invoker-service.xml
21 Feb 2014 16:53:21,968 DEBUG [org.jboss.management.j2ee.MBean] Failed to register as listener of: jboss.jmx:type=adaptor,name=MBea
nProxyRemote,protocol=jrmp
解决是:maven打包前clean一下就解决了,原因不明。
 
 
 
英特尔至强E5,服务器CPU(Xeon E5 系列CPU)
 
SCSI即小型计算机系统接口。
小型计算机系统接口(英语:Small Computer System Interface; 简写:SCSI),
一种用于计算机和智能设备之间(硬盘、软驱、光驱、打印机、扫描仪等)系统级接口的独立处理器标准。 
SCSI是一种智能的通用接口标准。它是各种计算机与外部设备之间的接口标准。
 
除了SCSI,IDE也是一种极为常用的接口。
 
 
MTQJ报错?
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 512
        at java.lang.System.arraycopy(Native Method)
        at java.io.OutputStreamWriter.write(OutputStreamWriter.java:261)
        at java.io.Writer.write(Writer.java:151)
        at org.apache.log4j.helpers.CountingQuietWriter.write(CountingQuietWriter.java:44)
        at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:301)
        at org.apache.log4j.RollingFileAppender.subAppend(RollingFileAppender.java:236)
        at org.apache.log4j.WriterAppender.append(WriterAppender.java:159)
        at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230)
        at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65)
        at org.apache.log4j.Category.callAppenders(Category.java:203)
        at org.apache.log4j.Category.forcedLog(Category.java:388)
        at org.apache.log4j.Category.info(Category.java:680)
        at com.cup.mtq.log.LogManager$LogOutputThread.run(LogManager.java:129)
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 512
        at java.lang.System.arraycopy(Native Method)
        at java.io.OutputStreamWriter.write(OutputStreamWriter.java:261)
        at java.io.Writer.write(Writer.java:151)
        at org.apache.log4j.helpers.CountingQuietWriter.write(CountingQuietWriter.java:44)
        at org.apache.log4j.WriterAppender.subAppend(
解决:磁盘满了,清了就好
 
 
 
myeclipse中spket安装jquery后没有编辑提示的原因是:
1、myeclipse要重启
2、jquery要下载开发版的
3、spket->javascript Profile中要把jquery设置成default
 
 
 
jsp访问时报错:编译jsp失败
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:116)
org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:316)
org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:149)
org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:386)
org.apache.jasper.compiler.Parser.parseDirective(Parser.java:450)
org.apache.jasper.compiler.Parser.parseElements(Parser.java:1399)
org.apache.jasper.compiler.Parser.parse(Parser.java:130)
org.apache.jasper.compiler.ParserController.doParse(ParserController.java:255)
org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:185)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:354)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:321)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
解决:换个jstl.jar包的1.2版本就好了。原因是servelt2.5版需要1.2的jstl包
 
 
 
CSS中点和井号:
#对应id
点对应class
 
jquery设置样式
$("#tt").attr("class","linkvisited");
 
 
jQuery中$("#id")只能选择第一个对象,不能选择所有相同id的元素。
通过 $("input[id='xxxx']"); 可以选择多个相同id的元素。
 
 
jQuery(elements);
我们传递一个element,然后产生一个jquery对象,这个是对象,一定要记住。我们可以把$("")看成是一个构造函数。
这就犹如java中的new 差不多.每调用一次构造函数 都是生成一个新的对象,用==比较 他们自然不会相等。
 
 
datatables 列宽 可拖动?
不支持
 
 
datatables从服务端取报错?
DataTables warning (table id = 'table1'): Requested unknown parameter '0' from the data source for row 0
解决:datatables 接收两种格式的数据,一种json格式的二维数组,另一种是json格式的数组对象,
如果是服务器端返回的json格式的数组对象,在js中需要设置mDataProp这个属性。
json数组:
var ourcountry=[["北京市"],["上海市"],["合肥市","芜湖市","蚌埠市"]]; 
json对象:
var zhongguo={provinces:[{name:"北京",cities:[{name:"北京市",quxian:["海淀区","朝阳区","东城区","西城区"]}]}, 
{name:"安徽省",cities:[{name:"芜湖市",quxian:["繁昌县","芜湖县","南陵县","三山区"]},{name:"合肥市",quxian:["肥西县","蜀山区","庐阳区"]}]}, 
"湖北省" 
]}; 
 
 
 
 
jquery ui 在$("#tabs").tabs时调用了/context?
解决:删除页面中的<base href="<%=basePath%>">语句即可。原因不明
 
 
 
upjas调试模式(监控模式)
打开upjas调试模式:
1. 把run.conf文件中的#JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"  注释去掉
2. 把jon_upjas_start文件中的 
# uncomment to enable jmx remote management
#JAVA_OPTS="$JAVA_OPTS \
#-Dcom.sun.management.jmxremote.port=12345 \
#-Dcom.sun.management.jmxremote.authenticate=false \
#-Dcom.sun.management.jmxremote.ssl=false \
#-Djboss.platform.mbeanserver \
#-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl"
 里面的注释全都去掉
3.重启upjas
 
 
aix查看网卡速率
netstat -v ent0
 
 
http keep-alive超时设置
nginx :keepalive_timeout :75s
tomcat:server.xml 中的Connector 元素中:keepAliveTimeout(单位毫秒);maxKeepAliveRequests:最大长连接个数
jboss:?
 
 
mtqj模拟性能测试端:
D:\mapsworkspace\mtqjperformancetest
 
mtqj打成jar包启动:
/usr/java6_64/bin/java -classpath ".:mjc-1.4.jar:slf4j-log4j12-1.6.1.jar:slf4j-api-1.6.1.jar:org.dtools.javaini-v1.1.00.jar:mina-core-2.0.7.jar:log4j-1.2.15.jar:commons-lang-2.1.jar" com.cup.mtq.Start
 
 
初始化的顺序跟Listener、Filter、Servlet在web.xml中的顺序无关
而多个Filter或多个Servlet的时候,谁的mapping在前面,谁先初始化。
如果web.xml中配置了<context-param>,初始化顺序:
context-param > Listener > Filter > Servlet 
 
 
mtqj以web应用方式使用时,增加是否初始化log4j:
在web.xml中指定下面即可:
<context-param>
<param-name>log4jinit</param-name>  
<param-value>false</param-value>  
</context-param>
修改文件:web.xml MjcLogger MtqInitListenser
 
 
MTQJ负载均衡策略,mtqNetwork.xml中设置负载均衡策略:
1、什么都没有:轮询
2、在host上设置:loadfactor="XXX"(XXX表示0-100),表示请求数负载
3、在domain上设置:lbmethod="bytraffic",在host上设置loadfactor="XXX"(XXX表示0-100),表示按流量负载
 
 
 
Caused by: java.net.UnknownHostException: UnknownHostException invoking http://P570_F_3:7001/csb/shcenter/BillDomain/IntegratedServicePlatformForIndustry/IsvrBatchParaSynchNotifyService/IsvrBatchParaSynchNotifyServiceProxy: P570_F_3
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
 
 
 
org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:48)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
 
 
 
PreparedStatement是如何大幅度提高性能的 
当一个数据库收到一个statement后,数据库引擎会先解析statement,然后检查其是否有语法错误。一旦statement被正确的解析,
数据库会选出执行statement的最优途径。遗憾的是这个计算开销非常昂贵。数据库会首先检查是否有相关的索引可以对此提供帮助,
不管是否会将一个表中的全部行都读出来。数据库对数据进行统计,然后选出最优途径。当决创建查询方案后,数据库引擎会将它执行。
存取方案(Access Plan)的生成会占用相当多的CPU。
一个perpared statement会同一个单独的数据库连接相关联。当数据库连接被关闭时prepared statement也会被丢弃
 
 
 
linux:
top
 
mysql
登陆
mysql客户端连接失败次数超过max_connect_errors次后, 会被自动锁住
 
查看状态变量
show global status;
 
查看二进制文件
show binary logs;
 
查看二进制日志内容
mysqlbinlog XXX
 
查看linux版本
lsb_release -a
 
 
lbpool是根据MySQL的复制机制设计的支持负 载均衡的JDBC连接缓冲池
 
 
d:\Program Files\MySQL\
d:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.5\
 
 
解决MySQL无法远程访问的3方案
1、改表法
mysql mysql -hlocalhost -uroot -p
update user set host='%' where user='root';
flush privileges;
 
 
判断mysql是主库还是从库
使用普通的driver也可以的:String driver = "com.mysql.jdbc.Driver";
使用这个url:String url = "jdbc:mysql:replication://localhost:3306,172.17.236.121:3306/test";
或者这个:String url = "jdbc:mysql://172.17.236.121:3306/test";
show global status like 'Slave_running';
System.out.println(rs.getString(1)+"="+rs.getString(2));//Slave_running=OFF off是主库、on是从库
 
 
 
postgre是个数据库?
 
采用RESOURCE_LOCAL管理事务时,要保证数据库支持事务。例如使用MySQL时,需要设置数据库的引擎类型为“InnoDB”,而“MyISAM”类型是不支持事务的。
 
系统异常包括RuntimeException及其子类,这些异常会导致JTA事务回滚。应用异常即CheckedException子类,不会导致回滚;但是如果应用异常标注了:
@ApplicationException(rollback=true),则JTA容器就会回滚
 
 
MapsDaoServiceBean在初始化时注入unitName = "mapsdb"的EntityManager,代码上将MapsDaoServiceBean对象保存在MAP中,导致了即使EntityManager替换了也没用
 
 
<input type="hidden" id="submittype" />
后台使用request.getParameter("submittype")取值为null,只能在jsp上使用name="submittype"属性后台才能取
 
 
.是类  #是id
id是唯一的,类是可以重用的.
比如你有多个地方样式要求一样的话,就用类.这样就不用些多个#了.
.name{.....}
<div class="name"></div>
<div class="name"></div>     /*就像这样.你多个地方都想要同一个样式就这样写.
 
#Idname{.......}
<div id="Idname"></div>        /*id只有一个.
 
div4=document.getElementById("fourth");
div4.className="yellow";
 
 
div没有disabled属性,因此不能简单的通过设置disabled属性达到效果。
 
任何对象的void finalize()方法只会被系统自动调用一次。
 
java的Calendar类add函数增加年时可以无限,但是数据库的time stamp类型的字段,最大值只能是9999-12-31 23:59:59.999999
 
 
前提:java用map缓存了数据库连接池返回的datasource后:
1、若数据库重启了,程序使用这个datasource时,它不为null,对程序透明,程序照常使用。
2、若数据库停了,程序使用这个datasource时,它不为null,但是在DataSource.getConnection()时报错如下:
org.jboss.util.NestedSQLException: Unable to get managed connection for jdbc/batdb; - nested throwable: (javax.resource.ResourceException: Unable to get managed connection for jdbc/batdb)
然后数据库再次启动后,缓存的datasource还是不为null,程序照常正常使用,对程序透明。
 
 
java.sql.sqlexception can not issue executeUpdate() from selects
 
 
jdbc执行语句select * from tbl_mimgm_ma_resp_cd into outfile 'd:/mysql/11.backup'报如下错误:
java.sql.SQLException:Can't create/write to file 'd:\11.backup'(Errcode:13)
解决:
1、在my.ini中[mysqld]里面添加一行:tmpdir="d:\mysql\"
2、重启mysql server后再次执行
 
 
my.ini在xp中位置如下:D:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.5
导出的文件若不指定绝对路径,位置是:
D:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.5\data\mimgmdb
其中mimgmdb是数据库名
 
 
jdbc执行语句select * from tbl_mimgm_ma_resp_cd into outfile 'd:/mysql/11.backup'报如下错误:
java.sql.SQLException:File 'd:/mysql/11.backup' already exists
解决:目前无法解决。只能先删除,再导出
 
 
jdbc执行语句select * from tbl_mimgm_ma_resp_cd into outfile d:/mysql/222.backup报如下错误:
com.mysql.jdbc.exception.jdbc4,MySQLSyntaxErrorException:You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near
'd:/mysql/222.backup' at line 1
解决:outfile后面的文件名需要打上单引号
 
 
java.sql.SQLException: Can't get stat of '/home/mi_mgmap/upjas/upjas-minimal/bin/dbpatch/20140520115311.replace.TBL_MIMGM_TRANS_ID_INF' (Errcode: 2)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
解决:
 
 
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: 'null' for column 'REC_UPD_TS' at row 2
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4235)
解决:数据库data文件中REC_UPD_TS字段处为null值,在load时报错。
 
 
-Xss128k: 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。根据应用的线程所需内存大小进行调整。
在相同物理内 存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
线程栈的大小是个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时
时出现溢出的可能性更大,如果该值设置过大,就有影响到创建栈的数量,如果是多线程的应用,就会
出现内存溢出的错误
 
新生代 = Eden区+Survivor区(这两个比值由-XX:SurvivorRatio=8决定)
-Xmn2g:设置年轻代大小为2G
新生代GC(Minor GC),当Eden区不足以分配对象时触发
老年代GC(Major GC/Full GC),比MinorGC慢10倍以上
 
大对象直接进入老年代,避免大对象在Eden区和Survivor区之间复制拷贝(由-XX:PretenureSizeThreshlod=3145728B)
 
如果对象在Eden出生并经过第一次MinorGC后仍然存活,并且能被Survivor容纳,将被移动到Survivor空间中,并将对象年龄设为1。
对象在Survivor区中每熬过一次MinorGC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代。
这个年龄值可以通过参数-XX:MaxTenuringThreshold来设置。
 
jvm启动时的数据区域:
1、程序计数器:线程私有,较小内存,当前线程所执行的字节码的行号指示器,无OutOfMemoryError情况。
2、java虚拟机栈:线程私有,生命周期与线程相同,每个方法执行时会创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等。抛出StackOverflowError、OutOfMemoryError异常。
3、本地方法栈:虚拟机使用Native方法服务。
4、java堆:各线程共享区域。新生代(Eden + From Survivor + To Survivor)+老年代。抛出OutOfMemoryError。
5、方法区:各线程共享区域。又叫永久代。存储被虚拟机加载的类信息、常量、静态变量、即时编译器JIT编译后的代码。抛出OutOfMemoryError。-XX:MaxPermSize。只有sun的虚拟机需要设置,jrockit和ibm虚拟机无需设置。
6、运行时常量池:方法区的一部分;class文件中除包含类版本、字段、方法、接口等外,还有编译期生成的各种字面常量和符号引用。抛出OutOfMemoryError。
7、直接内存Direct Memory:不是虚拟机运行时数据区的一部分。java NIO引入的使用native函数库直接分配的堆外内存,
java堆里面的DirectByteBuffer对象是这块堆外内存的引用,避免了在java堆和native堆来回复制数据。
抛出OutOfMemoryError。-XX:MaxDirectMemorySize。垃圾回收器不会主动回收,只在full gc时顺便清理direct memory
 
实践经验:
除java堆和永久代外,下面也会占用内存,这里所有内存的总和受到操作系统进程最大内存的限制。
1、Direct Memory:OutOfMemoryError:Direct buffer memory。
2、线程堆栈:-Xss。 StackOverflowError无法分配新的栈帧;OutOfMemoryError无法建立新的线程。
3、socket缓存区。每个socket连接都有Receive和Send两个缓存区;分别占37KB和25KB内存。
4、JNI代码:使用JNI调用本地库,使用内存不在堆里面。
5、虚拟机和GC:虚拟机和GC的代码执行也消耗一定内存。
 
导致Gc的情况:
1、老年代(tenured)被写满
2、perm被写满
3、System.gc()的显式调用。
4、上一次GC之后heap的各域分配策略动态变化。
 
 
 
F5对后台应用做健康检查
1、Layer2层,F5会发送给服务器IP地址的ARP请求,服务器会响应这个ARP请求。
2、Layer3层,F5会发送给服务器ping命令,用来确认IP地址是否在网络中存在或者主机是否正常工作。
3、Layer4层,F5的负载均衡器会试图建立一个连接到服务器TCP或者UDP的某个端口,发送一个TCP SYN
请求包,并检查回应的TCP SYN ACK数据包是否收到。
 
 
 
upjas停止时打出
Heap
 PSYoungGen      total 458752K, used 62915K [0x00000000e0000000, 0x0000000100000000, 0x0000000100000000)
  eden space 393216K, 16% used [0x00000000e0000000,0x00000000e3d70c08,0x00000000f8000000)
  from space 65536K, 0% used [0x00000000f8000000,0x00000000f8000000,0x00000000fc000000)
  to   space 65536K, 0% used [0x00000000fc000000,0x00000000fc000000,0x0000000100000000)
 ParOldGen       total 1048576K, used 1339K [0x00000000a0000000, 0x00000000e0000000, 0x00000000e0000000)
  object space 1048576K, 0% used [0x00000000a0000000,0x00000000a014ece0,0x00000000e0000000)
 PSPermGen       total 131072K, used 8292K [0x0000000090000000, 0x0000000098000000, 0x00000000a0000000)
  object space 131072K, 6% used [0x0000000090000000,0x0000000090819370,0x0000000098000000)
  
 
管理upjas启动vm参数
14:38:19,727 INFO  [ServerInfo] VM arguments: 
-Dprogram.name=run.sh -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 
-XX:PermSize=128m -XX:MaxPermSize=256m 
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps 
-Dorg.jboss.resolver.warning=true 
-Dsun.rmi.dgc.client.gcInterval=3600000 
-Dsun.rmi.dgc.server.gcInterval=3600000 
-Dsun.lang.ClassLoader.allowArraySyntax=true 
-Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef=true 
-Ddb2.jcc.charsetDecoderEncoder=3 
-Dorg.jboss.net.protocol.file.useURI=false 
-DpwdServerIp=172.17.248.74 
-DpwdServerPort=7000 
-DpwdServerIp_bak=172.17.252.63 
-DpwdServerPort_bak=11140 
-Xms1536m -Xmx1536m 
-Djava.net.preferIPv4Stack=true 
-Djava.endorsed.dirs=/home/mi_mgmap/upjas/upjas-minimal/lib/endorsed 
 
 
管理upjas启动时gc日志
2014-05-06T14:38:29.602+0800: [GC [PSYoungGen: 393216K->46465K(458752K)] 393216K->46465K(1507328K), 0.2396330 secs] [Times: user=0.39 sys=0.07, real=0.24 secs] 
2014-05-06T14:38:31.725+0800: [GC [PSYoungGen: 147560K->61885K(458752K)] 147560K->61885K(1507328K), 0.2032700 secs] [Times: user=0.34 sys=0.06, real=0.20 secs] 
2014-05-06T14:38:31.929+0800: [Full GC (System) [PSYoungGen: 61885K->0K(458752K)] [ParOldGen: 0K->61565K(1048576K)] 61885K->61565K(1507328K) [PSPermGen: 29108K->29067K(131072K)], 1.1917110 secs] [Times: user=2.09 sys=0.07, real=1.19 secs] 
2014-05-06T14:38:39.731+0800: [GC [PSYoungGen: 393216K->35370K(458752K)] 454781K->96935K(1507328K), 0.0990800 secs] [Times: user=0.26 sys=0.01, real=0.10 secs] 
2014-05-06T14:38:46.592+0800: [GC [PSYoungGen: 428586K->59203K(458752K)] 490151K->120768K(1507328K), 0.2902710 secs] [Times: user=0.54 sys=0.00, real=0.28 secs] 
2014-05-06T14:38:53.579+0800: [GC [PSYoungGen: 452419K->65514K(458752K)] 513984K->150727K(1507328K), 0.3100880 secs] [Times: user=0.59 sys=0.02, real=0.31 secs] 
2014-05-06T14:39:02.693+0800: [GC [PSYoungGen: 458730K->65533K(371712K)] 543943K->180368K(1420288K), 0.2337030 secs] [Times: user=0.47 sys=0.02, real=0.23 secs] 
2014-05-06T14:39:05.698+0800: [GC [PSYoungGen: 371709K->75946K(415232K)] 486544K->190782K(1463808K), 0.2553100 secs] [Times: user=0.70 sys=0.00, real=0.26 secs] 
jlog.properties properties file found and used:URL=file:/home/mi_mgmap/upjas/upjas-minimal/server/default/cup-deploy/appCfg/jlog.properties
log4j.properties properties file found and used:URL=file:/home/mi_mgmap/upjas/upjas-minimal/server/default/cup-deploy/appCfg/log4j.properties
2014-05-06T14:39:14.944+0800: [GC [PSYoungGen: 382122K->85144K(409152K)] 496958K->219570K(1457728K), 0.4262070 secs] [Times: user=0.70 sys=0.05, real=0.42 secs] 
2014-05-06T14:39:21.885+0800: [GC [PSYoungGen: 385688K->66670K(412416K)] 520114K->231316K(1460992K), 0.5258480 secs] [Times: user=0.85 sys=0.07, real=0.52 secs] 
2014-05-06T14:39:32.110+0800: [GC [PSYoungGen: 367214K->60090K(419456K)] 531860K->247241K(1468032K), 0.3460030 secs] [Times: user=0.60 sys=0.02, real=0.35 secs] 
2014-05-06T14:39:41.029+0800: [GC [PSYoungGen: 372154K->54631K(416896K)] 559305K->260258K(1465472K), 0.3492870 secs] [Times: user=0.52 sys=0.03, real=0.35 secs] 
defaultCasLogin:http://172.17.248.56:6008/sso/login
2014-05-06T14:39:54.952+0800: [GC [PSYoungGen: 366695K->45038K(421184K)] 572322K->269223K(1469760K), 0.3133260 secs] [Times: user=0.50 sys=0.02, real=0.31 secs] 
 
 
 
启动时,YoungGen的大小是448M(1536*7/24);当使用到384M(即6/7的总内存时)时触发一次MinorGC
ParOldGen大小是1024M
PSPermGen大小是128M
 
并行(Parallel):垃圾收集线程并行工作,用户线程处理等待状态。
并发(Concurrent):用户线程与垃圾收集线程同时执行。
 
 
Parallel Scavenge收集器也被称作“吞吐量优先”收集器,新生代垃圾收集器,使用复制算法,并行处理,目标是达到一个可控的吞吐量,它的参数包括:
-XX:MaxGCPauseMillis     大于0的毫秒数,收集器尽量保证内存回收话费时间不超过该值。
-XX:GCTimeRatio     大于0小与100的整数,垃圾收集时间占总时间的比率,相当于吞吐量的倒数,默认99,就是容许最大1%(1/(99+1))的垃圾收集时间
-XX:UseAdaptiveSizePolicy   这个开关打开之后,就不需要手工指定新生代大小(-Xmn)、Eden与Survivor比例(-XX:SurvivorRatio),虚拟机动态调整。
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC 使用CMS收集器,(CMS收集时的停顿时间只是收集过程中的一小部分)
 
Serial Old收集器,是Serial收集器的老年版本,单线程收集器,使用标记-整理算法。
Parallel Old:Parallel Scavenge的老年代版本,使用多线程和“标记-整理”算法。
CMS(Concurrent Mark Sweep)收集器是以获取最短回收停顿时间为目标的收集器,使用标记-清除算法,几种运用在互联网站或B/S系统的服务端上,重视响应速度。
优点是:并发收集(不会导致用户线程停顿)、低停顿。缺点是:对cpu资源较敏感;无法处理浮动垃圾;产生大量空间碎片。
G1收集器,基于标记-整理算法,
 
 
UseParallelOldGC = Parallel Scavenge + Parallel Old
 
 
 
运行日志
异常堆栈
GC日志         ibm jdk gc(xml格式) 查看工具ga441.zip
线程快照(threaddump/javacore)     kill -3
堆转储快照(heapdump/dump/hprof)-XX:+HeapDumpOnOutOfMemoryError   or  kill -3   or    jmap工具
 
 
 
 
jps:列出正在运行的虚拟机进程。 -q -m -l -v
jstat:监视虚拟机各种运行状态信息,可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。如:jstat -gcutil pid
jinfo:实时查看或者调整各项虚拟机参数。
jmap:生成堆转储快照heapdump文件。如:jmap -dump:format=b,file=d:/eclipse.bin pid
jhat:与jmap搭配,分析heapdump文件,之后生成html文件,浏览器中键入http://localhost:7000/就可以看到分析结果。
jstack:生成虚拟机当前时刻的线程快照,是当前虚拟机内每一个线程正在执行的方法堆栈的集合。主要目的是定位线程长时间停顿的原因。如:jstack -l pid
jconsole:运行监视、故障处理
jvisualvm:除运行监视、故障处理外,还提供性能分析(双击应用程序-右边Profiler-性能分析CPU、内存)。工具-插件-可用插件,里面列出所有可用插件。BTrace动态日志。
 
 
 
 
apache在做负载均衡时要对同一sessionid分配到同一个服务器上?
 
 
系统总内存 = RAM + SWAP分区(linux)或者分页文件(aix)
 
 
java代码编译出来后形成的class文件中存储的是字节码,虚拟机通过解释方式执行字节码命令,比起C编译成本地二进制代码来说速度慢不少。
为解决慢的问题,jdk1.2以后,虚拟机内置了两个运行时编译器,如果一段java方法被调用的次数到达一定程度,就会被判定为热代码(hot spot code),从而交给
JIT(just in Time Compiler)编译器即时编译为本地代码,以提高运行速度。
 
虚拟机运行在-client模式时,使用代号为C1的轻量编译器,运行在-server模式下,使用代号为C2的重量级编译器,
-client,-server
这两个参数用于设置虚拟机使用何种运行模式,client模式启动比较快,但运行时性能和内存管理效率不如server模式,通常用于客户端应用程序。相反,server模式启动比client慢,但可获得更高的运行性能。
在windows上,缺省的虚拟机类型为client模式,如果要使用server模式,就需要在启动虚拟机时加-server参数,以获得更高性能,对服务器端应用,推荐采用server模式,尤其是多个CPU的系统。在Linux,Solaris上缺省采用server模式。
 
使用-classpath后虚拟机将不再使用CLASSPATH中的类搜索路径,如果-classpath和CLASSPATH都没有设置,则虚拟机使用当前路径(.)作为类搜索路径。
 
使用-XX:+DisableExplicitGC屏蔽程序主动触发的System.gc()
 
 
表 1. IBM SDK 5.0 中的 GC 策略
策略选项描述
针对吞吐量进行优化-Xgcpolicy:optthruput(可选)默认策略。对于吞吐量比短暂的 GC 停顿更重要的应用程序,通常使用这种策略。每当进行垃圾收集时,应用程序都会停顿。
针对停顿时间进行优化-Xgcpolicy:optavgpause通过并发地执行一部分垃圾收集,在高吞吐量和短 GC 停顿之间进行折中。应用程序停顿的时间更短。
分代并发-Xgcpolicy:gencon以不同方式处理短期存活的对象和长期存活的对象。采用这种策略时,具有许多短期存活对象的应用程序会表现出更短的停顿时间,同时仍然产生很好的吞吐量。
子池-Xgcpolicy:subpool采 用与默认策略相似的算法,但是采用一种比较适合多处理器计算机的分配策略。建议对于有 16 个或更多处理器的 SMP 计算机使用这种策略。这种策略只能在 IBM pSeries? 和 zSeries? 平台上使用。需要扩展到大型计算机上的应用程序可以从这种策略中受益。
 
ibm的分代并发:nursery(年轻代)占总javaheap的22.5%,tenured(老年代)占总javaheap的75%,还少2.5%不知道去哪里???
ibm jdk关于gc的几个配置项(upjas在这个文件里面vi upjas_all_setEnv.sh):
-verbose:gc     打开gc日志项
-verbose:gc -Xverbosegclog:gc.log  打开gc日志,并记录到bin下的gc.log文件中去
-XX:+PrintGCDetails -XX:+PrintGCDateStamps  gc日志记录gc的详细信息以及时间
-Xgcpolicy:optavgpause  gc策略(有几项:optthruput、optavgpause、gencon、subpool)
 
倒数第一行前加入:
JAVA_OPTS="$JAVA_OPTS -verbose:gc -Xverbosegclog:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
 
再加两个参数 -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime对暂停时间看得更清晰。 
 
 
upjas的run.conf设置了
-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
 
 
 
JConsole连接监控:此进程中未启动代理管理java进程不了什么原因?
解决:在vm arguments中添加“-Dcom.sun.management.jmxremote”
 
class文件结构:
1、魔数
2、class文件版本
3、常量池
4、访问标志
5、类索引、父类索引与接口索引集合
6、字段表集合
7、方法表集合
8、属性表集合
 
方法的描述与字段的描述几乎一致,依次包括了访问标志(acess_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)
 
打印class文件结构工具:
javap -verbose Testjavap
结果:
Compiled from "Testjavap.java"
public class Testjavap extends java.lang.Object
  SourceFile: "Testjavap.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = class        #2;     //  Testjavap
const #2 = Asciz        Testjavap;
const #3 = class        #4;     //  java/lang/Object
const #4 = Asciz        java/lang/Object;
const #5 = Asciz        i;
const #6 = Asciz        I;
const #7 = Asciz        <init>;
const #8 = Asciz        ()V;
const #9 = Asciz        Code;
const #10 = Method      #3.#11; //  java/lang/Object."<init>":()V
const #11 = NameAndType #7:#8;//  "<init>":()V
const #12 = Field       #1.#13; //  Testjavap.i:I
const #13 = NameAndType #5:#6;//  i:I
const #14 = Asciz       LineNumberTable;
const #15 = Asciz       LocalVariableTable;
const #16 = Asciz       this;
const #17 = Asciz       LTestjavap;;
const #18 = Asciz       main;
const #19 = Asciz       ([Ljava/lang/String;)V;
const #20 = Asciz       args;
const #21 = Asciz       [Ljava/lang/String;;
const #22 = Asciz       SourceFile;
const #23 = Asciz       Testjavap.java;
 
{
public int i;
 
public Testjavap();
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   iconst_0
   6:   putfield        #12; //Field i:I
   9:   return
  LineNumberTable:
   line 2: 0
   line 4: 4
   line 2: 9
 
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      10      0    this       LTestjavap;
 
 
public static void main(java.lang.String[]);
  Code:
   Stack=0, Locals=1, Args_size=1
   0:   return
  LineNumberTable:
   line 11: 0
 
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      1      0    args       [Ljava/lang/String;
 
 
}
 
eclipse中编译class的major_version属性设置在:
window-Preferences-java-Compiler-Configure Project Specific Settings-选择某一项目
- ok - “Compiler compliance level”选择6.0 - ok即可。
 
 
DK 编译器版本target 参数十六进制 minor.major十进制 minor.major
jdk1.1.8不能带 target 参数00 03 00 2D45.3
jdk1.2.2不带(默认为 -target 1.1)00 03 00 2D45.3
jdk1.2.2-target 1.200 00   00 2E46.0
jdk1.3.1_19不带(默认为 -target 1.1)00 03 00 2D45.3
jdk1.3.1_19-target 1.300 00   00 2F47.0
j2sdk1.4.2_10不带(默认为 -target 1.2)00 00   00 2E46.0
j2sdk1.4.2_10-target 1.400 00   00 3048.0
jdk1.5.0_11不带(默认为 -target 1.5)00 00   00 3149.0
jdk1.5.0_11-target 1.4 -source 1.400 00   00 3048.0
jdk1.6.0_01不带(默认为 -target 1.6)00 00   00 3250.0
jdk1.6.0_01-target 1.500 00   00 3149.0
jdk1.6.0_01-target 1.4 -source 1.400 00   00 3048.0
jdk1.7.0不带(默认为 -target 1.6)00 00   00 3250.0
jdk1.7.0-target 1.700 00   00 3351.0
jdk1.7.0-target 1.4 -source 1.400 00   00 3048.0
Apache Harmony 5.0M3不带(默认为 -target 1.2)00 00   00 2E46.0
Apache Harmony 5.0M3-target 1.400 00   00 3048.0
 
 
class文件类加载的生命周期:
1、加载
2、连接:验证、准备、解析
3、初始化
4、使用
5、卸载
 
只有遇到以下四种情况jvm才会立即对类进行初始化:
1、遇到new、getstatic、putstatic、invokestatic这四条字节码指令。
2、使用java.lang.reflect包的方法对类进行反射调用
3、当初始化一个类时,如果发现其父类没有进行初始化,需要先初始化其父类
4、当虚拟机启动时,用户需要指定一个要执行的类(包含main方法的那个类),虚拟机会先初始化这个主类。
除此之外,引用类的方式是被动引用,不会触发初始化:
1、通过子类引用父类的静态字段,不会导致子类初始化
2、通过数组定义来引用类,不会触发此类的初始化
3、调用别的类的常量,在编译时直接进入类的常量池,因此不会触发类的初始化。
 
 
<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语块(static{})中的语句合并而成,与类的构造函数(init())不同,
父类的<clinit>()方法先执行。
执行接口的<clinit>()方法不需要先执行父接口的<clinit>()方法。
虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确的加锁和同步。
 
 
类加载器:
1、启动类加载器(Bottstrap ClassLoader)负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数指定的路径中的,且被虚拟机识别的(严格按照文件名,如rt.jar)
2、扩展类加载器(Extension ClassLoader)负责加载<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库
3、应用程序类加载器(Application ClassLoader)负责加载classpath中所指定的类库。
 
 
每一个栈帧都包括了局部变量表、操作数栈、动态连接、方法返回地址和一些额外的附加信息,在编译时,栈帧需要多大的局部变量表、多深的操作数栈都已经完全确定了。
 
java虚拟机提供了四条方法调用字节码指令:
1、invokestatic:调用静态方法。
2、invokespecial:调用实例构造器init方法、私有方法、父类方法。
3、invokevirtual:调用所有虚方法。
4、invokeinterface:调用接口方法,在运行时确定一个实现此接口的对象。
 
 
重载参数匹配优先级
char
int
long
Character
Serializable
Object
char... arg(变长参数的优先级最低)
 
变量被定义成volatile后具有两种特性;
1、保证此变量对所有线程可见:当前一线程修改此变量值时,另外的线程立即得知,普通变量在线程间传递需要通过主存完成。
showdown(){}停止线程这类场景很适合volatile来控制并发,调用showdown时可以保证所有线程立即停下。
2、禁止指令重排序化:在一个线程的方法执行过程中,赋值或者声明语句可能被重新排序,加了volatile后可以避免此情况
 
 
java内存模型定义了如何在工作内存和主内存间相互操作的的八个操作,要求lock、unlock、read、load、assign、use、store、write八个操作都具有原子性。
lock:作用于主内存的变量,把一个变量标识为一条线程独占的状态。
unlock:解锁,作用于主内存的变量,把一个处于锁定状态的变量释放出来。
read:作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存中。
load:作用于工作内存的变量,把read操作从主内存中得到的变量值放入工作内存的变量副本中。
use:作用于工作内存的变量,把工作内存中一个变量的值传递给执行引擎。
assign:作用于工作内存的变量,把一个执行引擎接收到的值赋给工作内存的变量。
store:作用于工作内存的变量,把工作内存的一个变量值传送到主内存中。
write:作用于主内存的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中。
 
把一个变量从主内存复制到工作内存,要顺序执行read和load操作。把变量从工作内存同步到主内存,要顺序执行store和write操作。
java内存模型只要求两个操作要按顺序执行,并不保证必须是连续执行的。
 
 
并发的三个特性是:原子性、可见性、有序性。
 
java的线程是被映射到系统的原生线程来实现的。java提供10个级别的线程优先级(10最高,1最低),windows只有7种
 
线程安全程度从高到低:
1、不可变:Immutable,如:java.lang.String  java.lang.Integer(此类中定义了private final int value;)
2、绝对线程安全:
3、相对线程安全:Vector HashTable Collections的synchronizedCollection()方法包装的集合
4、线程兼容:ArrayList HashMap  对象本身并不是线程安全的,但是通过调用端正确的使用,保证并发环境安全的使用
5、线程对立:不管调用端采用如何措施,都无法在多线程环境中并发使用的代码。Thread的suspend和resume方法,如果suspend中断的线程就是即将要执行resume的那个线程,那就肯定要死锁。
 
 
线程安全的实现方法
1、互斥同步:synchronized使用操作系统互斥量来实现锁机制
2、非阻塞同步
3、无同步方案:可重入代码+线程本地存储
 
 
一些确保线程安全的方法 访问共享的,可变的数据,要求同步,为了保证变量元素的可见性,可以采用如下方法: 
① 线程封闭 最简单的方式就是不共享数据,如果数据仅在单线程中访问,就不需要任何同步。线程封闭技术是实现线程安全的最简单的方式,当对象封闭在一个线程中,
这种做法会自动成为线程安全的,即使被封闭的对象本身并不是。比如JDBC的连接池,虽然JDBC本身规范并没有要求Connection对象是线程安全的,但是在典型的服务器
应用中,线程总是从池中获得一个Connection对象,并且用它处理一个单一的请求,最后把它归还,每个线程都会同步地处理大多数请求,而且在Connection对象在被
归还前,池不会将它再分配给其他线程。
② 栈限制 将变量限制在方法中。 
③ ThreadLocal 它允许将变量和线程关联在一起,使得每个线程都有一份单独的拷贝。
④ 不可变性 不可变对象永远是线程安全的,一个对象是不可变的饿,要求它的状态创建后不会改变,所有域都是final类型,并且,它被正确创建。
 
 
 
StringBuffer的append方法是加上synchronized的。
 
JAVA编译期优化:
几乎没有
javac将java代码转变为字节码的编译器称作前端编译器。
 
 
JAVA运行期优化:
当程序需要迅速启动和执行时,解释器可以首先发挥作用,随着时间推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码,提高执行效率。
-Xint强制虚拟机运行于解释模式
-Xcomp强制虚拟机运行于编译模式
热点代码被执行client模式是1500次,server模式下是10000次,超过这个数将会触发JIT编译。这个次数是一段时间的被调用次数。使用-XX:CounterHalfLifeTime参数设置半衰期时间单位是秒。
-XX:-BackgroundCompilation来禁止后台JIT编译
-XX:+PrintCompilation要求虚拟机在即时编译时将编译成本地代码的方法名打印出来。(debug版的虚拟机支持)
-XX:+PrintInlining要求虚拟机输出内联信息。
 
JIT优化有很多技术,包括:
1、公共子表达式消除:b*c和c*b是一组公共表达式。
2、数组边界检查消除:访问数组元素foo[i]时系统会自动进行上下界的范围检查,否则会抛出ArrayIndexOutOfBoundsExcepiton,
如果编译器通过分析数据流判断循环变量的取值范围永远在[0,foo.length)之内,就可以把数组的上下界检查消除掉。
3、方法内联:把目标方法的代码复制到调用的方法中,避免发生真是的方法调用。只有使用了invokespecial指令调用的私有方法、实例构造器、父类方法和使用
invokestatic指令进行调用的静态方法、使用invokevirtual指令的被final修饰的方法才能内联。
java大部分方法都是虚方法。
激进优化:”类型继承关系分析CHA“技术,查询此方法是否有多个版本可供选择,如果只有一个版本,可以进行内联。如果加载了导致继承关系发生变化的新类,
需要抛弃已编译的代码,退回到解释状态执行,或者重新编译;如果有多个版本,编译器将会做最后一次努力。
4、逃逸分析:分析对象动态作用域。如果能证明一个对象不会逃逸到方法或者线程之外,那么可以在栈上分配对象;
如果能确认一个变量不会逃逸出线程,无法被其它线程访问,那么对此变量的同步措施就可消除;
把一个java对象拆散,根据访问情况,将其成员变量恢复到原始类型访问,叫标量替换,如果进一步证明对象不会逃逸,
那么虚拟机可能不会创建这个对象,使用成员变量代替,在栈上分配(栈上存储的数据很大机会会被虚拟机分配至物理机器的高速寄存器中存储)。
 -XX:DoEscapeAnalysis开启逃逸分析
 -XX:+PrintEscapeAnalysis查看分析结果
 -XX:+EliminateAllocations开启标量替换
 -XX:+EliminateLocks开启同步消除
 -XX:+PrintEliminateAllocations 查看标量的替换情况
 
 
java虚拟机家族:
sun hotspot:sun jdk1.3后的默认虚拟机。
bea JRockit:bea公司专注于服务端应用,内部不含解释器的实现,全部代码都靠JIT。
ibm J9:ibm单独开发的jvm
 
apache harmony:间接催生了google android平台的Dalvik虚拟机(嵌入式)。
 
 
apache提供了一个工具htcacheclean来清理由mod_disk_cache模块生成的缓存。
htcacheclean -p 目录 -l 50k
 
linux下最大文件描述符的限制有两个方面,一个是用户级的限制,另外一个则是系统级限制。
以下是查看Linux文件描述符的三种方式:
[root@localhost ~]# sysctl -a | grep -i file-max --color
fs.file-max = 392036
[root@localhost ~]# cat /proc/sys/fs/file-max
392036
[root@localhost ~]# ulimit -n
1024
查看当前进程的文件描述符限制linux:
vi /proc/[pid]/limits
 
 
apache的错误日志由核心模块mod_core提供。
LogLevel指定记录错误级别:emerg、alert、crit、error、warn、notice、info、debug
默认错误文件放在ServerRoot的logs目录中,使用ErrorLog来重新指定新位置或文件名。关闭错误日志:ErrorLog /dev/null
 
 
AB测试服务器性能
D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 100 -c 10 http://172.17.254.155:11000/mjc/
ab -n 100 -c 50 http://146.240.25.40:12000/wcg/webtest/1?a=1
ab -n 100 -c 50 http://146.240.25.39:4488/
ab -n 100 -c 50 http://146.240.25.40:4488/
 
ab -n 10000 -c 10 http://172.17.248.74:11000/test/webtrans
 
ab -n 100 -c 50 http://146.240.25.39:12000/test/webtrans
 
 
报class "org.apache.log4j.PropertyConfigurator"'s signer information does not... 
博客分类: tomcat 
Apachelog4j 
今天将tomcat5.5中的工程放在tomcat6.0里跑,报: 
class "org.apache.log4j.PropertyConfigurator"'s signer information does not。。。。。 
郁闷了,仔细看似乎是log4j的问题,其实不然,检查jftp.jar包,发现它里面也有log4j的包,可能是冲突了,于是干脆把jftp.jar包删了,重启,没事了!阿门! 
但是不知道jftp.jar做什么用的,这样删掉会不会出问题,为了保险起见删掉jftp.jar里面包含有Apache的代码,因为我的Project也有Apache的jar,估计是冲突。将jftp.jar里面的所有org包下的class都删掉。 
jftp.jar这个包初看好像是用ftp做上传功能用的,如果没用到全删。免得以后再出这样的问题。 
 
 
 
mtqj的web.xml中配置了如下语句,即可使得mtqj不会初始化log4j:
<context-param>
<param-name>log4jinit</param-name>  
<param-value>false</param-value>  
</context-param>
<listener>   
<!-- 指定Listener 的实现类-->   
<listener-class>com.cup.mtq.MtqInitListener</listener-class>   
</listener>  
 
 
wcg.war应用启动,读CommPacket.ini文件时,nohup报错
java.lang.IllegalArgumentException: URI scheme is not "file"
解决:web-inf/classes里面添加了mtqCfg的目录
 
eclipse中报错没找到.class file等?
解决:Project-> Build Automatically
 
 
 
 
 
Tomcat一个小时进行一次 Full GC,正常么?3
2014-06-08T04:33:07.721+0800: [GC [PSYoungGen: 253229K->64K(509248K)] 327975K->74809K(1557824K), 0.0392510 secs] [Times: user=0.08 sys=0.00, real=0.04 secs] 
2014-06-08T04:33:07.761+0800: [Full GC (System) [PSYoungGen: 64K->0K(509248K)] [ParOldGen: 74745K->74745K(1048576K)] 74809K->74745K(1557824K) [PSPermGen: 54430K->54429K(131072K)], 1.5088410 secs] [Times: user=2.82 sys=0.00, real=1.51 secs] 
2014-06-08T05:33:09.273+0800: [GC [PSYoungGen: 253178K->96K(512448K)] 327924K->74841K(1561024K), 0.0258150 secs] [Times: user=0.04 sys=0.00, real=0.02 secs] 
2014-06-08T05:33:09.299+0800: [Full GC (System) [PSYoungGen: 96K->0K(512448K)] [ParOldGen: 74745K->74746K(1048576K)] 74841K->74746K(1561024K) [PSPermGen: 54430K->54429K(131072K)], 1.3636130 secs] [Times: user=2.65 sys=0.00, real=1.37 secs] 
解决:Full GC (System)表明是程序中显示调用的gc。
一个小时一次,是tomcat的一个bug,不是你程序的问题,通过参数-XX:+DisableExplicitGC 就能去掉这一个小时一次的FGC。当然也有其他很多方法
 
 
org.apache.cxf.binding.soap.SoapFault: Unmarshalling Error: unexpected element (uri:"", local:"others"). Expected elements are <{}baseDomainName>,<{}serviceName>,<{}timeout>,<{}baseHostName>,<{}remoteDomainName>,<{}isFile>,<{}remoteHostName>,<{}systemName>,<{}data>,<{}fileContent> 
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
 
 
 
jaxb无法处理xml<->HashMap转换
jaxb在做xml与object互转时需要要如下事情
1、jdk1.6以上自带jaxb工具包
2、首先定义xsd文件
3、在windows的cmd里面执行命令,生成xsd文件中定义的元素对应的java类
xjc XXX.xsd -p 包名
例如:xjc mtqNetwork.xsd -p jaxb
4、此时就可以写测试程序了:请见jaxb/Test.java
 
 
 
cxf无法处理HashMap的入参。解决方法是给HashMap参数做个适配器,把JAXB不支持的对象类型(除了HashMap还有TimeStamp)转换方法重写下。本质上是把HashMap转成String传输。
1、新建类MapAdapter:(需要xstream-1.3.1.jar包)
package com.cup.wcg;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
/**
 * <数据模型转换>
 * <Map<String,Object> 与 String之间的转换>
 * 
 * @author  Owen
 * @version  [版本号, Apr 28, 2010]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@XmlType(name = "MapAdapter")
@XmlAccessorType(XmlAccessType.FIELD)
public class MapAdapter extends XmlAdapter<String, Map<String, Object>>
{
   /** *//**
    * Convert a bound type to a value type.
    * 转换JAXB不支持的对象类型为JAXB支持的对象类型
    *
    * @param map map
    *      The value to be convereted. Can be null.
    * @return String   
    * @throws Exception
    *      if there's an error during the conversion. The caller is responsible for
    *      reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
    */
   public String marshal(Map<String, Object> map)
       throws Exception
   {
   XStream xs = new XStream(new DomDriver());
  return xs.toXML(map);
 
   }
   /** *//**
    * Convert a value type to a bound type.
    * 转换JAXB支持的对象类型为JAXB不支持的的类型
    *
    * @param model
    *      The value to be converted. Can be null.
    * @return Map<String,Object>
    * @throws Exception
    *      if there's an error during the conversion. The caller is responsible for
    *      reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
    */
   @SuppressWarnings("unchecked")
   public Map<String, Object> unmarshal(String model)
       throws Exception
   {
   XStream xs = new XStream(new DomDriver());
   return (HashMap)xs.fromXML(model);
   }
}
 
2、创建webservice中带HashMap的入参:
@WebMethod
public String callByMap(@XmlJavaTypeAdapter(com.cup.wcg.MapAdapter.class) HashMap<String,String> map){
if(map==null){
log.info("map is null");
return "map is null";
}
else{
log.info("map key="+map.get("key"));
return "map key="+map.get("key");
}
}
 
如果HashMap是对象中的一个属性,采用如下方式:
  @XmlJavaTypeAdapter(MapAdapter.class)
    public HashMap<String,String> getMap()
    {
        return map;
    }
    
    public void setMap(@XmlJavaTypeAdapter(MapAdapter.class) HashMap<String,String> map)
    {
        this.map = map;
    }
 
 
3、调用时先转一把,从HashMap到String。
java.util.HashMap<String,String> map = new java.util.HashMap<String,String>();
map.put("key", "value");
XStream xs = new XStream(new DomDriver());
String s =  xs.toXML(map);
System.out.println(s);
res2 = client.invoke("callByMap",s);
System.out.println("Echo responsse: " + res2[0]);
 
xstream-1.3.1.jar包的maven位置:
<dependency>
  <groupId>com.thoughtworks.xstream</groupId>
  <artifactId>xstream</artifactId>
  <version>1.3.1</version>
</dependency>
 
 
报错
org.apache.cxf.binding.soap.SoapFault: Unmarshalling Error: java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory 
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
解决:去除war包中的xml-apis-1.0.b2.jar
 
 
Exception in thread "MtqResponseProcessThread_5" java.lang.NoClassDefFoundError:org/apache/commons/lang/StringUtils
at com.cup.mtq.cache.XmlHandle.getServiceByName()
解决:缺少commons-lang-2.1.jar
 
 
 
 
IE访问前置管理报错:http://146.240.25.38:11000/mi
Network Error (tcp_error)
A communication error occurred: ""  
The Web Server may be down, too busy, or experiencing other problems preventing it from responding to requests. You may wish to try again at a later time.  
For assistance, contact your network support team.  
解决:mi管理系统没有启动成功
 
 
android LogCat中不输出任何的信息 ?
简单的恢复方法:
1、clean logcat的内容
2、在Android 的 Devices视图,对自己的应用点一下debug。
一般这样以后Logcat 里就会突然出现很多消失了很久的log了。 
 
 
 
mysql 查看编码格式
mysql> SHOW VARIABLES LIKE 'character_set_%';
mysql> SHOW VARIABLES LIKE 'collation_%';
 
 修改编码格式
1. SET NAMES 'utf8';
它相当于下面的三句指令:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
 
一般只有在访问之前执行这个代码就解决问题了,下面是创建数据库和数据表的,设置为我们自己的编码格式。
2. 创建数据库
mysql> create database name character set utf8;
 
3. 创建表
CREATE TABLE `type` (
`id` int(10) unsigned NOT NULL auto_increment,
`flag_deleted` enum('Y','N') character set utf8 NOT NULL default 'N',
`flag_type` int(5) NOT NULL default '0',
`type_name` varchar(50) character set utf8 NOT NULL default '',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
 
4. 修改数据库成utf8的.
mysql> alter database name character set utf8;
 
5. 修改表默认用utf8.
mysql> alter table type character set utf8;
 
6. 修改字段用utf8
mysql> alter table type modify type_name varchar(50) CHARACTER SET utf8;
 
 
 
 
JVM Crash 异常退出:SIGSEGV (0xb)问题定位分析?
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fc4b5d82120, pid=4844, tid=140482762118912
#
# JRE version: 6.0_37-b06
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.12-b01 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x69e120]  MarkSweep::IsAliveClosure::do_object(oopDesc*)+0x20
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
原因:系统上有两个jre环境。指定当前用户下JAVA_HOME即可。
# configuration of vms
export JAVA_HOME=${VMS_HOME}/jdk
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$CLASSPATH 
 
 
 
高性能:high performance
高速缓存、并行计算、异地镜像
 
高可用
负载均衡、数据灾备、异地容灾
 
高可扩展
开发框架、多层设计、业务分割
 
 
大型网站技术架构:核心原理与案例分析
pdf书下载?
 
 
CDN对动态网站内容加速效果:
优化访问线路:使用CDN动态加速,在A和B之间增加一个节点C,节点C长期存在于互联网上,不管是A访问C,还是B访问C,速度都不慢;因此,加入C节点以后,会让A访问B的速度会更快。
降低资源请求
不少CDN平台已经转型成为云安全加速平台,不仅支持内容分发,同时支持防攻击、防黑,有效减少安全隐患
 
 
 
到你的http://www.dnspod.cn用户后台更改你的
A记录:地址记录,用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP地址,就需要添加A记录。
CNAME: 如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录。
TXT:在这里可以填写任何东西,长度限制255。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)。
NS:域名服务器记录,如果需要把子域名交给其他DNS服务商解析,就需要添加NS记录。
AAAA:用来指定主机名(或域名)对应的IPv6地址(例如:ff06:0:0:0:0:0:0:c3)记录。
MX:如果需要设置邮箱,让邮箱能收到邮件,就需要添加MX记录。
URL:从一个地址301重定向到另一个地址的时候,就需要添加URL记录(注:DNSPod目前只支持显性301重定向)。
SRV:记录了哪台计算机提供了哪个服务。格式为:服务的名字、点、协议的类型,例如:_xmpp-server._tcp。
 
注意:你解析时"线路类型"要选择"默认"如果选择其它线路,那么有可能有些宽带不能访问你的网站.
 
 
查询本机到服务器中间经过的路由器ip地址
tracert 域名/IP
 
 
查询DNS服务器的域名解析记录?
nslookup
现在的Dns可以根据访问ip的不同把域名解析到不同的ip上的
 
 
services-config.xml中
<channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
            <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
            <properties>
                <add-no-cache-headers>false</add-no-cache-headers>
            </properties>
</channel-definition>
1、endpoint中class修改成flex.messaging.endpoints.SecureAMFEndpoint或者flex.messaging.endpoints.AMFEndpoint均可,但是不能没有。
如果是SecureAMFEndpoint客户端与服务端的报文处于加密状态,如果是AMFEndpoint则没加密,但是两个都是二进制的格式。
如果是HTTPChannel/HTTPEndpoint(需要用http访问),则双方使用HTTP/XML格式报文,如果是SecureHTTPChannel则是加密。
按我的理解,使用SecureAMFChannel是使得客户端与服务端之间建立HTTPS链路,然后使用AMFEndpoint是传输二进制对象,使用SecureAMFEndpoint则是对此对象再次进行了加密。
2、endpoint中url中的/messagebroker配置在web.xml中的servlet-mapping处:<url-pattern>/messagebroker/*</url-pattern>。因此后面的/amfsecure是可以随便写的。
3、remoting-config.xml中<default-channels>中可以配置多个,flex页面连不上第一个channel的endpoint,会退而连第二个。
 
 
通过抓包发现,对于https的链路,握手并建立链路后,上面走的报文就不能以http协议来解析了,只能按照TCP来解包。
 
 
linux
vmstat 报告虚拟内存的统计信息。
 
Linux在计算进程情况时不将正在运行的 vmstat 自己计算进去。 
vmstat对系统的虚拟内存、进程、CPU活动进行监视,同时它也对磁盘和forks和vforks操作的个数进行汇总。
不足是vmstat不能对某个进程进行深入分析,它仅是一对系统的整体情况进行分析。
例如:[angel@home /angel]# vmstat
procs memory swap io system cpu
r b w swpd free buff cache si so bi bo in cs us sy id
0 0 0 7180 1852 56092 48400 0 0 6 5 24 8 0 0 18
其中:
Procs
r:等待运行的进程数
b:处在非中断睡眠状态的进程数
w:被交换出去的可运行的进程数。
Memory
swpd:虚拟内存使用情况,单位:KB
free:空闲的内存,单位KB
buff:被用来做为缓存的内存数,单位:KB
Swap
si:从磁盘交换到内存的交换页数量,单位:KB/秒
so:从内存交换到磁盘的交换页数量,单位:KB/秒
IO
bi:发送到块设备(也就是硬盘,因为硬盘是块设备)的块数,单位:块/秒
bo:从块设备接收到的块数,单位:块/秒 从块设备收到的块数,单位:块/秒
System
in:每秒的中断数,包括时钟中断
cs:每秒的环境(上下文)切换次数
CPU按CPU的总使用百分比来显示
us: CPU使用时间
sy: CPU系统使用时间
id:闲置时间
wa:cpu等待IO的时间(如果wa的值很高而且虚拟内存基本没有使用,则说明硬盘的速度是性能的一个瓶颈,此时应该更换一个速度更快的硬盘)
 
 
查看linux上某个进程的详细信息
ps aux
 
查看linux上某端口是哪个进程
netstat -nltp |grep 80
lsof -i:80 (还可以看到是哪个用户启的)
fuser -n tcp 80
 
 
 
Logging Error: Caught an IOException
java.io.IOException: 系统资源不足,无法完成请求的服务。
 
 
 
CET时区,GMT时区
⑴Greenwich Mean Time (GMT)格林尼治标准时间英国、爱尔兰、冰岛和葡萄牙属于该时区。这个时区与中国北京时间的时差是8个小时,也就是说比北京时间晚8个小时。
比如,如果是北京时间的下午3:00,也就是这个时区的上午7:00。
⑵Central European Time(CET)中欧时区奥地利、比利时、克罗地亚、捷克共和国、丹麦、法国、德国、荷兰、匈牙利、卢森堡、马耳他、意大利、摩纳哥、
挪威、波兰、斯洛文尼亚、斯洛伐克、西班牙、瑞士和瑞典,都属于这个时区。
该时区与北京时间的时差是7个小时。比如,北京时间的下午3:00,那么是这个时区的上午8:00。
⑶Eastern European Time(EET)东欧时区属于这个时区的欧洲国家有:保加利亚、赛浦路斯、爱脱尼亚、芬兰、希腊、拉脱维亚、立陶宛、罗马尼亚、土耳其和乌克兰。
这个时区与北京时间的时差是6个小时。比如,北京时间的下午3:00,也就是这个时区的上午9:00。大部分欧洲国家实行夏令时(Summer Time or DST)。
三月份的最后一个周未是夏令时的开始,这一天他们把时钟往后调一个小时,比如2:00am,他们调整为3:00am。十月份的最后一个周未是夏令时的结束,
这一天他们把时钟往前调一个小时,比如2:00am,他们调整为1:00am。
 
 
 
通过kill -3 进程号能生成javacore....txt日志,但是没法生成.phd文件。
而.phd文件是JVM内存映射文件,获取它才能分析此时JVM内存的情况,进而分析出服务器宕机的原因。
 
对于IBM JDK需要做以下设置:
1.设置JVM参数:
   -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpOnCtrlBreak
2.设置操作系统环境变量:
   export IBM_HEAP_DUMP=true
   export IBM_HEAPDUMP=true
   export IBM_HEAPDUMP_OUTOFMEMORY=true
   export IBM_JAVADUMP_OUTOFMEMORY=true
   export IBM_JAVACORE_OUTOFMEMORY=true
重启服务器。如果这样仍然解决不了问题,则需要在服务器启动脚本添加一行:
    #!/bin/ksh
    #...
    set -m
HP JDK生成Heapdump文件需要在在环境变量上,加上export _JAVA_HEAPDUMP=1
 
 
Thread Dump分析
通过分析Thread Dump,可以了解JVM到底有哪些线程正在工作,有助于找出死锁,性能低下的原因。 
Sun HotSpot有两种方式: 
jstack pid > /tmp/my_thread_dump.log (生成的是文本文件,直接看即可。)
kill -3 pid, dump文本会生成在标准输出中,在upjas1.x中就是$UPJAS_HOME/bin/nohup.out中,需要手工截取 
IBM J9: 
kill -3 pid, thread dump文本会生成在类似 javacore.20131223.135411.7130.0002.txt 的文件中
 
Heap Dump分析
通过分析Heap Dump,可以了解JVM中到底哪些对象占用了大量内存,有助于定位内存泄漏等问题。 
Sun HotSpot: 
jmap -dump:format=b,file=/tmp/mydump.hprof pid
说明
其中 /tmp/mydump.hprof 是用户自己指定的文件名。 
IBM J9 
kill -3 pid
heap dump会生成在类似 heapdump.20131223.135411.7130.0001.phd 的文件中 
说明
kill -3 pid之所以能在upjas环境下生成heapdump,是因为upjas_all_setEnv.sh中设置了ibm J9能识别的参数: -Xdump:heap 
 
 
 
 
org.apache.cxf.endpoint.Client是线程安全的,测试程序在:D:\isvrupjasworkspace\Testupjascxf\src\Test里面
 
 
 
WeakHashMap与HashMap的用法基本相同,区别在于:后者的key保留对象的强引用,即只要HashMap对象不被销毁,其对象所有key所引用的对象不会被垃圾回收,
HashMap也不会自动删除这些key所对应的键值对对象。但WeakHashMap的key所引用的对象没有被其他强引用变量所引用,
则这些key所引用的对象可能被回收。WeakHashMap中的每个key对象保存了实际对象的弱引用,当回收了该key所对应的实际对象后,
WeakHashMap会自动删除该key所对应的键值对。
 
 
System.gc(); 
//告诉垃圾收集器打算进行垃圾收集,而垃圾收集器进不进行收集是不确定的 
 
System.runFinalization(); 
//强制调用已经失去引用的对象的finalize方法 
 
 
 
 
用Jmeter发送TCP二进制的消息
1、tcp:右键添加-》Sampler -》TCP取样器
2、要发送二进制的话可以在TCPClient classname的这个参数中填入
org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl
这样在text to send的区域直接写入HEX形式的二进制
 
 
 
"Java请求"是指JMeter对Java Class进行性能测试
 
 
jmeter csv data set config 使用文件中配置的参数
 
 
Jmeter日志输出和日志级别设置
Jmeter日志默认存放在%JMeter_HOME%\bin目录,文件名通常是JMeter.log。日志记录与JMeter本身运行有关的日志信息。
 
Jmeter使用Log4j日志组件输出日志,%JMETER_HOME%\bin\jmeter.properties中的log_level.jmeter用于控制Jmeter日志记录级别。log_level.jmeter可以设置以下日志级别:FATAL_ERROR, ERROR, WARN, INFO,DEBUG,其中FATAL_ERROR打印日志最少,DEBUG级别日志最详细
 
 
DNS协议运行在UDP协议之上,使用端口号53
 
 
确定同类业务:成本、客户矩阵
 
 
关闭 Apache 的web日志?
httpd.conf文件里面有如下配置,注掉就不记日志了
ErrorLog "logs/error_log"
CustomLog "logs/access_log" common
 
 
 
传统上,Linux 的先辈 Unix 还有一个环境变量:LD_LIBRARY_PATH 来处理非标准路经的共享库
 
 
apache反向代理时部分图片显示不出?
解决:图片的链接一般是img src="/mjc/resources/images/filter.gif"这种,如果apache代理配置成这样
ProxyPass         /mi http://146.240.25.38:11000/mjc
ProxyPassReverse  /mi http://146.240.25.38:11000/mjc
当使用http://146.240.25.38:4488/mi访问网站时,图片的链接变成了http://146.240.25.38:4488/mjc/resources/images/filter.gif就无法成功代理。
只能改成如下配置:
ProxyPass         /mjc http://146.240.25.38:11000/mjc
ProxyPassReverse  /mjc http://146.240.25.38:11000/mjc
 
 
 
wget命令测试http服务
 
 
浏览器关了,但是apache上https的端口还有很多状态在CLOSE_WAIT、TIME_WAIT?
 
 
 
问题:使用apache做类似于F5的角色的方法?(访问通讯协议:浏览器--https-->APACHE--http-->管理mgm server)
1、apache上安装、配置ssl
略,参考:学习\apache2.2和php5的安装使用\linux上安装apache2.2\(可行)Linux上Apache服务器的搭建与配置手册(包含openssl安装及ssl代理+ssl证书).doc
2、apache/conf/extra> vi httpd-ssl.conf文件中</VirtualHost>之前配置如下:
SSLProxyEngine on
ProxyRequests off
ProxyPreserveHost on
ProxyPass         /maps http://172.17.248.186:11000/maps
ProxyPassReverse  /maps http://172.17.248.186:11000/maps
3、管理要做相应修改,使得登陆时sso会跳到正确地址。
172.17.248.186的maps的appCfg/securityClient.properties中配置:
146.240.25.38=https://172.17.248.33:4433
(其中146.240.25.38是代理apache的ip,172.17.248.186上安装了管理应用,其flex页面必须使用HTTPS才能打开)
4、浏览器访问:
https://146.240.25.38:4489/maps(4489是代理apache上https端口)
 
 
问题:使用apache访问外网https方法?目前只会单向的,(访问通讯协议:应用--http-->APACHE--https-->外部HTTPS SERVER)
1、apache上安装、配置ssl
同上,例外是此处可不用打开下面这个配置,也无需配置此文件:
#Include conf/extra/httpd-ssl.conf
2、apache/conf > vi httpd.conf文件配置:
SSLProxyEngine on
ProxyRequests off
ProxyPreserveHost on
ProxyPass         /mjc https://172.17.248.185:11009/mjc
ProxyPassReverse  /mjc https://172.17.248.185:11009/mjc
3、浏览器使用http://146.240.25.38:4488/mjc即可访问
(其中146.240.25.38是代理apache的ip,4488是其http端口,172.17.248.185表示开启了HTTPS端口的外部应用)
 
 
双向https
请求http的形式发送到apache上,通过apache服务器继续以https形式去往外部,调用其他公司为银联提供的服务,双向加密,由于本情形配置较复杂,请联系主机组协助。
ProxyRequests Off
SSLProxyEngine On
SSLProxyMachineCertificateFile /home/apache/chmoNFC/htdocs/certificate/120.204.69.183.pem
SSLProxyCACertificateFile /home/apache/chmoNFC/htdocs/certificate/120.204.69.183.crt
ProxyPass /tsm balancer://TSMProxy/tsm
ProxyPassReverse /tsm balancer://TSMProxy/tsm
<Proxy balancer://TSMProxy>
    BalancerMember  https://112.106.165.36:9443
    SetEnv proxy-nokeepalive 1
</Proxy>
在配置中120.204.69.183.pem和120.204.69.183.crt两个证书文件会有业务室或应用科室提供。
 
 
 
通常来说,一个CLOSE_WAIT会维持至少2个小时的时间?(系统默认超时时间的是7200秒,也就是2小时)
一、 修改方法:(暂时生效,重新启动服务器后,会还原成默认值) 
sysctl -w net.ipv4.tcp_keepalive_time=600   
sysctl -w net.ipv4.tcp_keepalive_probes=2 
sysctl -w net.ipv4.tcp_keepalive_intvl=2 
注意:Linux的内核参数调整的是否合理要注意观察,看业务高峰时候效果如何。 
二、 若做如上修改后,可起作用;则做如下修改以便永久生效。 
vi /etc/sysctl.conf 
 
若配置文件中不存在如下信息,则添加: 
net.ipv4.tcp_keepalive_time = 1800 
net.ipv4.tcp_keepalive_probes = 3 
net.ipv4.tcp_keepalive_intvl = 15 
 
编辑完 /etc/sysctl.conf,要重启network 才会生效 
/etc/rc.d/init.d/network restart 
然后,执行sysctl命令使修改生效,基本上就算完成了。 
------------------------------------------------------------ 
修改原因: 
当客户端因为某种原因先于服务端发出了FIN信号,就会导致服务端被动关闭,若服务端不主动关闭socket发FIN给Client,此时服务端Socket会处于CLOSE_WAIT状态(而不是LAST_ACK状态)。通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(系统默认超时时间的是7200秒,也就是2小时)。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源,那么通常是等不到释放那一刻,系统就已崩溃。因此,解决这个问题的方法还可以通过修改TCP/IP的参数来缩短这个时间,于是修改tcp_keepalive_*系列参数: 
tcp_keepalive_time: 
/proc/sys/net/ipv4/tcp_keepalive_time 
INTEGER,默认值是7200(2小时) 
当keepalive打开的情况下,TCP发送keepalive消息的频率。建议修改值为1800秒。 
 
tcp_keepalive_probes:INTEGER 
/proc/sys/net/ipv4/tcp_keepalive_probes 
INTEGER,默认值是9 
TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适) 
 
tcp_keepalive_intvl:INTEGER 
/proc/sys/net/ipv4/tcp_keepalive_intvl 
INTEGER,默认值为75 
当探测没有确认时,重新发送探测的频度。探测消息发送的频率(在认定连接失效之前,发送多少个TCP的keepalive探测包)。乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒,也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值) 
 
【检测办法】 
1. 系统不再出现“Too many open files”报错现象。 
 
2. 处于TIME_WAIT状态的sockets不会激长。 
 
在 Linux 上可用以下语句看了一下服务器的TCP状态(连接状态数量统计): 
 
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 
 
返回结果范例如下:
ESTABLISHED 1423 
FIN_WAIT1 1 
FIN_WAIT2 262 
SYN_SENT 1 
TIME_WAIT 962
-----------------------------------------------------------------------------------------------
 
apache/conf> vi extra/httpd-default.conf
KeepAlive On
keep-alvie默认是开启的
 
 
服务器负载均衡有三大基本Feature:负载均衡算法,健康检查和会话保持
 
 
 
java.lang.reflect.UndeclaredThrowableException
        at $Proxy298.parseSchema(Unknown Source)
        at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.addSchemas(DynamicClientFactory.java:423)
        at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:271)
        at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:198)
        at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:191)
        at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:146)
        at com.cup.maps.online.OnlineTrans.getResponseByType(OnlineTrans.java:630)
        at com.cup.maps.online.OnlineTrans.access$000(OnlineTrans.java:57)
        at com.cup.maps.online.OnlineTrans$ServiceDealThread.run(OnlineTrans.java:834)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:611)
        at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:52)
        ... 9 more
Caused by: java.lang.NullPointerException
        at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
        at org.apache.xerces.dom.ParentNode.item(Unknown Source)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:246)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:277)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:246)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:277)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:246)
        at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:123)
        at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.parseSchema(SchemaCompilerImpl.java:136)
        ... 14 more
解决:通讯配置文件同步,会有多个线程同时使用cxf生成ws客户端,此处代码非线程安全导致报错。
 
 
 
TestHttpHeartBeat测试HttpClient的executeMethod执行3000次,未见内存泄露
 
 
 
Exception in thread "pool-1-thread-1" java.lang.IllegalStateException: Unable to create JAXBContext for generated packages: "com.cup.mtq" doesnt contain ObjectFactory.class or jaxb.index
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:345)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:198)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:191)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:146)
at TestcxfCreateWsClient.run(TestcxfCreateWsClient.java:52)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.xml.bind.JAXBException: "com.cup.mtq" doesnt contain ObjectFactory.class or jaxb.index
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:342)
... 7 more
 javac: 找不到文件: C:\DOCUME~1\沈雷\LOCALS~2\Temp\cxf-tmp-833848\cxf-compiler3952818340990681712.tmp (系统找不到指定的文件。)
解决:使用ExecutePool会导致此问题,使用Thread线程调用cxf.createClient不会有问题。
另外,在.profile中添加PATH=$PATH:/usr/java6_64/bin:.生效后重启也能解决问题
 
 
 
前置管理启动时报错:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.)
at org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.getLocalManagedConnection(LocalManagedConnectionFactory.java:225)
at org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.createManagedConnection(LocalManagedConnectionFactory.java:195)
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.createConnectionEventListener(InternalManagedConnectionPool.java:639)
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.getConnection(InternalManagedConnectionPool.java:273)
at org.jboss.resource.connectionmanager.JBossManagedConnectionPool$BasePool.getConnection(JBossManagedConnectionPool.java:689)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.getManagedConnection(BaseConnectionManager2.java:404)
... 95 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1137)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:356)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2504)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2541)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2323)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:832)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:417)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:344)
at org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.getLocalManagedConnection(LocalManagedConnectionFactory.java:207)
... 100 more
解决:排除程序和jar包冲突问题后,发现管理应用的ip和访问用户mi_mgmap没有访问mimgmdb数据库的权限,如此增加即可:
grant all privileges on mimgmdb.* to mi_mgmap@'146.240.10.64' identified by 'mi_mgmap';
grant all privileges on mionldb.* to mi_mgmap@'146.240.10.64' identified by 'mi_mgmap';
 
 
 
服务器启动时,ServletContextListener的contextInitialized()方法被调用;服务器将要关闭时,ServletContextListener 的 contextDestroyed()方法被调用;
spring在web应用启动的listener类:org.springframework.web.context.ContextLoaderListener就用到了ServletContextListener。
 
 
 
系统室在146.240.25.38的apache上配置了ProxyRemote,使其通过访问代理服务访问外网,做法是:
在apache/conf/httpd.conf文件代理配置前添加:
ProxyRemote * http://172.18.64.89:3128
 
 
ProxyPreserveHost On 意思是传送原始请求的Host信息给被代理的机器。
 
 
javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: The element type "domain" must be terminated by the matching end-tag "</domain>".]
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:514)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:215)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
        at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:184)
解决:mtqService和mtqNetwork均有校验
 
 
 
linux
# uname -a # 查看内核/操作系统/CPU信息 
# head -n 1 /etc/issue # 查看操作系统版本 
# cat /proc/cpuinfo # 查看CPU信息 
# hostname # 查看计算机名 
# lspci -tv # 列出所有PCI设备 
# lsusb -tv # 列出所有USB设备 
# lsmod # 列出加载的内核模块 
# env # 查看环境变量资源 
# free -m # 查看内存使用量和交换区使用量 
# df -h # 查看各分区使用情况 
# du -sh <目录名> # 查看指定目录的大小 
# grep MemTotal /proc/meminfo # 查看内存总量 
# grep MemFree /proc/meminfo # 查看空闲内存量 
# uptime # 查看系统运行时间、用户数、负载 
# cat /proc/loadavg # 查看系统负载磁盘和分区 
# mount | column -t # 查看挂接的分区状态 
# fdisk -l # 查看所有分区 
# swapon -s # 查看所有交换分区 
# hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备) 
# dmesg | grep IDE # 查看启动时IDE设备检测状况网络 
# ifconfig # 查看所有网络接口的属性 
# iptables -L # 查看防火墙设置 
# route -n # 查看路由表 
# netstat -lntp # 查看所有监听端口 
# netstat -antp # 查看所有已经建立的连接 
# netstat -s # 查看网络统计信息进程 
# ps -ef # 查看所有进程 
# top # 实时显示进程状态用户 
# w # 查看活动用户 
# id <用户名> # 查看指定用户信息 
# last # 查看用户登录日志 
# cut -d: -f1 /etc/passwd # 查看系统所有用户 
# cut -d: -f1 /etc/group # 查看系统所有组 
# crontab -l # 查看当前用户的计划任务服务 
# chkconfig –list # 列出所有系统服务 
# chkconfig –list | grep on # 列出所有启动的系统服务程序 
# rpm -qa # 查看所有安装的软件包
 
查看主机名
vi /proc/sys/kernel/hostname
hostname
 
hostname –a: 获取主机别名。
hostname –d: 获取DNS域名。
hostname –f: 获取FQDN名称。
hostname –i: 获取主机的IP地址。
hostname –s: 获取域名的netbios名称。
 
hostname和ip的对应文件:
vi /etc/hosts
 
 
HttpClient对于要求接受后继服务的请求(301、302、303、307),比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。
client.executeMethod(post);
        System.out.println(post.getStatusLine().toString());
        post.releaseConnection();
        //检查是否重定向
        int statuscode = post.getStatusCode();
        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
            (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
            (statuscode == HttpStatus.SC_SEE_OTHER) ||
(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
//读取新的URL地址
            Header header = post.getResponseHeader("location");
            if (header != null) {
                String newuri = header.getValue();
                if ((newuri == null) || (newuri.equals("")))
                    newuri = "/";
                GetMethod redirect = new GetMethod(newuri);
                client.executeMethod(redirect);
                System.out.println("Redirect:"+ redirect.getStatusLine().toString());
                redirect.releaseConnection();
            } else
                System.out.println("Invalid redirect");
        }
 
 
HttpClient支持自动重传,如果要自定义exception重传需要实现HttpMethodRetryHandler类,然后设置:
httpget.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
 
 
<%@ page isELIgnored="true" %> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言。
<%=request.getParameter(“username”)%> 等价于 ${param.username}
<%=user.getAddr( ) %> 等价于 ${user.addr}
<%=request.getAttribute(“userlist”) %> 等价于$ { requestScope.userlist } 注意不是request.getParameter
EL表达式:http://baike.baidu.com/view/1488964.htm?fr=aladdin
 
 
 
DWR的逆向Ajax主要包括两种模式:主动模式和被动模式。其中主动模式包括polling和comet两种,被动模式只有piggyback这一种。默认是下面的第一种piggyback
1、piggyback方式
 这是默认的方式。
如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。
只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。
2、comet方式
当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候
直接通过前面挂起的连接再次传送数据。服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,
从而影响到服务质量。
3、polling方式
由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,
然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。
 
<!-- 使用polling和comet的方式 -->
 <init-param>
   <param-name>pollAndCometEnabled</param-name>
   <param-value>true</param-value>
 </init-param>
<!-- comet方式 --> 
 <init-param>  
<param-name>activeReverseAjaxEnabled</param-name>  
<param-value>true</param-value> 
</init-param> 
<!-- polling方式:在comet方式的基础之上,再配置以下参数 -->
  <init-param>  
  <param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>  
  <param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value> 
  </init-param>
<!-- 毫秒数。页面默认的请求间隔时间是5秒 --> 
<init-param> 
 <param-name>disconnectedTime</param-name> 
 <param-value>60000</param-value>  
</init-param>
 
 
veloctiy中将某javabean输出到前台vhtml时,需要该javabean是public的,并且该属性的get函数也是public的才行。例如:
public class Model {
 String abc = "a111111";
public String getAbc() {
return abc;
}
}
ctx.put("model2", new Model());
 
 
velocity页面取值的区别?一个int型,一个string
alert("@@@@@@@@@@@="+$tblcd);       267777
alert("@@@@@@@@@@@="+'$tblcd');01013001
 
 
在spring 中,常用的ViewResolver 有如下几种:
InternalResourceViewResolver 将逻辑视图名字解析为一个路径 
BeanNameViewResolver 将逻辑视图名字解析为bean的Name属性,从而根据name属性,找定义View的bean 
ResourceBundleResolver 和BeanNameViewResolver一样,只不过定义的view-bean都在一个properties文件中,用这个类进行加载这个properties文件 
XmlViewResolver 和ResourceBundleResolver一样,只不过定义的view-bean在一个xml文件中,用这个类来加载xml文件 
 
DispatcherServlet会加载所有的viewResolver到一个list中,并按照优先级进行解析。
注意:①order中的值越小,优先级越高。
   ②而id为viewResolver的viewResolver的优先级是最低的。
 
 
问:velocityViewResolver不起作用?
解决:如果为DispatcherServlet指定多个ViewResolver的话,不要给予InternalResourceViewResolver以及其他UrlBasedViewResolver子类过高的优先级,
因为这些ViewResolver即使找不到相应的视图,也不会返回null以给我们轮询下一个ViewResolver的机会。要给org.springframework.web.servlet.view.velocity.VelocityViewResolver
最高级别的等级。
 
 
 
@ModelAttribute获取POST请求的FORM表单数据
JSP表单如下
<form method="post" action="hao.do">
    a: <input id="a" type="text"   name="a"/>
    b: <input id="b" type="text"   name="b"/>
    <input type="submit" value="Submit" />
 </form>
Java  Pojo如下
    public class Pojo{
        private String a;
        private int b;
    }
Java Controller如下
@RequestMapping(method = RequestMethod.POST) 
public String processSubmit(@ModelAttribute("pojo") Pojo pojo) { 
    return "helloWorld"; 
}
 
 
switch语句的判断条件可以接受int,byte,char,short,enum。不能接受其他类型.
 
构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading
overload和override的区别 
override(重写) 
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。
overload(重载)
1、参数类型、个数、顺序至少有一个不相同。  
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。
 
 
abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
都可以的
 
Error与Exception有什么区别?
Exception表示应用程序级错误,Error表示系统错误或低层资源的错误 
 
List, Set, Map是否继承自Collection接口?
Map不继承,另外两个继承
 
short s1 = 1; s1 += 1;有什么错?
不会报错,+=这个运算具有隐式转换的功能
 
 
Math类中提供了三个与取整有关的方法:ceil、floor、round。ceil的英文意义是天花板,该方法就表示向上取整,floor的英文意义是地板,该方法就表示向下取整
round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整
 
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),
由于非线程安全,效率上可能高于Hashtable。
 
 
Anonymous Inner Class (匿名内部类)匿名的内部类是没有名字的内部类。
匿名的内部类不能extends(继承)其它类,但一个内部类可以作为一个接口,由另一个内部类实现。
 
String s = new String("xyz");创建了几个String Object?
一个引用s,一个对象new String在堆中,一个存于常量池,即永久代中。
 
银行卡包括借记卡,准贷记卡和贷记卡,其中,准贷记卡跟贷记卡并称为信用卡。 
1、贷记卡是指发卡银行给予持卡人一定的信用额度,持卡人可在信用额度内先消费,后还款的银行卡,一般可以透支取现。
如果在贷记卡里面你的账户有钱的话,这部分钱不会获得银行利息,即贷记卡存款不计息。
2、准贷记卡是指持卡人须先按发卡银行要求交存一定金额的备用金(其实这个备用金你马上就可以全部取走的,跟没存没多少差别),
当备用金账户余额不足支付时,可在发卡银行规定的信用额度内透支的银行卡,这个卡一般不可以透支取现,不过可以透支消费,
但透支消费后往往没有免息期。另外,如果在准贷记卡里面你的账户有钱的话,是可以从银行获得活期利息的。 
3、借记卡是指先存款后消费(或取现),没有透支功能的银行卡。其按功能不同,又可分为转账卡(含储蓄卡)、专用卡及储值卡。
如果在借记卡里面你的账户有钱的话,是可以从银行获得活期利息的。
 
 
apache负载均衡
http://146.240.25.39:4488/mi
 
 
hibernate java project 最小依赖包
hibernate-release-4.0.0.Beta4.zip包里面lib/required下的jar包全部添加到工程的library里面,
另外还需添加slf4j的实现包slf4j-log4j12-1.5.8.jar和log4j的实现包log4j-1.2.16.jar,还有别忘了把JDBC的驱动jar包也加入到library
 
 
UPJAS1.x包含的组件版本
Component Version 
JBoss Application Server 5.1.0.GA 
JBoss Microcontainer 2.0.10.GA 
JBoss Web (based on Tomcat 6.0) 2.1.12.GA-patch-01 
JBoss EJB3 1.3.8 
Hibernate Core 3.3.2.GA_CP04 
Hibernate Entity Manager 3.4.0.GA_CP04 
Hibernate Annotations 3.4.0.GA_CP04 
Hibernate Validator 3.1.0.GA 
JBoss WS-CXF 3.1.2.SP9 
JPA 1.0.0 
HornetQ HornetQ_2_2_20_EAP_GA 
 
 
tomcat数据源配置使用:
1、apache-tomcat-6.0.37\conf\context.xml增加
<Resource name="jdbc/mysqldb"
       auth="Container"
       type="javax.sql.DataSource"
       driverClassName="com.mysql.jdbc.Driver"
       url="jdbc:mysql://146.240.54.1:60016/mimgmdb?useUnicode=true&amp;characterEncoding=utf-8&amp;useOldAliasMetadataBehavior=true&amp;zeroDateTimeBehavior=convertToNull"
       username="mi_mgmap"
       password="mi_mgmap"
       maxActive="100"
       maxIdle="30"
       maxWait="10000"
    logAbandoned="true" />
2、index.jsp中调用:
<%
Context initContext = new InitialContext();
DataSource ds = (DataSource)initContext.lookup("java:comp/env/jdbc/mysqldb");
Connection conn = ds.getConnection();
Statement stat = conn.createStatement();
String sql = "select * from tbl_user";
ResultSet rs = stat.executeQuery(sql);
if(rs.next())
out.print(rs.getString(1));
conn.close();
initContext.close();
%>
 
换成db2的配置:(竟然无需db2驱动。。。)
<Resource name="jdbcMapsMng"
       auth="Container"
       type="javax.sql.DataSource"
       driverClassName="com.ibm.db2.jcc.DB2Driver"
       url="jdbc:db2://172.17.252.83:60004/mamgmdb:currentSchema=MA_MGMDB;"
       username="ma_mgmdb"
       password="ma_mgmdb"
       maxActive="100"
       maxIdle="30"
       maxWait="10000"
 logAbandoned="true" />
 
 
 
jboss数据源配置:
1、新增server/default/cup-deploy/jdbc/mysql-mimgm-ds.xml文件,内容如下:
<datasources>
  <local-tx-datasource>
        <jndi-name>miMng</jndi-name>
        <connection-url>jdbc:mysql://172.17.254.249:3306/mimgmdb?useUnicode=true&amp;characterEncoding=utf-8&amp;useOldAliasMetadataBehavior=true&amp;zeroDateTimeBehavior=convertToNull</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <user-name>mi_mgmdb</user-name>
        <password>mi_mgmdb</password>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <!-- should only be used on drivers after 3.22.1 with "ping" support
    <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
    -->
    <!-- sql to call when connection is created
    <new-connection-sql>some arbitrary sql</new-connection-sql>
      -->
    <!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers
    <check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
      -->
    <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
    <use-java-context>false</use-java-context>
    <min-pool-size>5</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <blocking-timeout-millis>30000</blocking-timeout-millis>
    <idle-timeout-minutes>10</idle-timeout-minutes>
    <set-tx-query-timeout/>
    <query-timeout>60</query-timeout> <!-- maximum of 1 minutes for queries -->
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>
2、修改server/default/conf/login-config.xml文件,如果已在第1步中配置了password,这个文件可以不用改,但是密码是明文的,
如果在这个文件里面加了以后,启动后密码是密文(其实可破解)。
<application-policy name="EncryptDBPassword_mimgmdb">
               <authentication>
                 <login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
                   <module-option name="username">ma_mgmdb</module-option>
                   <module-option name="password">-5cdd895416a30c6207a6df87216de44</module-option>
                   <module-option name="managedConnectionFactoryName">jboss.jca:name=miMng,service=LocalTxCM</module-option>
                 </login-module>
                </authentication>
</application-policy>
 
3、使用
外部client程序调用:
Context initContext = new InitialContext();
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url",
"jnp://172.17.236.133:11004");//"jnp://172.17.236.133:11004"
props.setProperty("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
initContext = new InitialContext(props);
 
DataSource ds = (DataSource)initContext.lookup("miMng");
Connection conn = ds.getConnection();
Statement stat = conn.createStatement();
String sql = "select * from tbl_user";
ResultSet rs = stat.executeQuery(sql);
if(rs.next())
System.out.print(rs.getString(1));
conn.close();
initContext.close();
 
war包内程序调用:
<%
Context initContext = new InitialContext();
DataSource ds = (DataSource)initContext.lookup("miMng");
Connection conn = ds.getConnection();
Statement stat = conn.createStatement();
String sql = "select * from tbl_user";
ResultSet rs = stat.executeQuery(sql);
if(rs.next())
out.print(rs.getString(1));
conn.close();
initContext.close();
%>
 
 
报错:
org.jboss.resource.JBossResourceException: Apparently wrong driver class specified for URL: 
class: com.mysql.jdbc.Driver, url: jdbc:mysql://146.240.54.1:60016/mimgmdb?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true&zeroDateTimeBehavior=convertToNull
org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.getDriver(LocalManagedConnectionFactory.java:492)
解决:将war包的WEB-INF/lib下的mysql驱动移动到server\default\lib下就好了
 
 
 
高危漏洞
Slow HTTP Denial Of Service Attack
这个攻击的原理和slowloris有点类似,略有不同的是利用的HTTP POST:POST的时候,指定一个非常大的
content-length,然后以很低的速度发包,比如10-100s发一个字节,hold住这个连接不断开。这样当客
户端连接多了后,占用住了webserver的所有可用连接,从而导致DOS。
 
 
管理系统因浏览器flash插件原因无法显示?
解决:安装install_flash_player_ax_14.0.0.176.1407893783.exe
 
 
 
java.net.UnknownHostException: miftcom01: miftcom01
        at java.net.InetAddress.getLocalHost(InetAddress.java:1360)
        at org.jboss.system.server.ServerInfo.getHostName(ServerInfo.java:344)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:59)
        at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:150)
        at org.jboss.beans.info.plugins.DefaultPropertyInfo.get(DefaultPropertyInfo.java:133)
        at org.jboss.managed.plugins.factory.AbstractInstanceClassFactory.getValue(AbstractInstanceClassFactory.java:202)
        at org.jboss.deployers.plugins.managed.BeanMetaDataICF.getValue(BeanMetaDataICF.java:205)
        at org.jboss.deployers.plugins.managed.BeanMetaDataICF.getValue(BeanMetaDataICF.java:54)
        at org.jboss.managed.plugins.factory.AbstractManagedObjectPopulator.populateValues(AbstractManagedObjectPopulator.java:204)
        at org.jboss.managed.plugins.factory.AbstractManagedObjectPopulator.populateManagedObject(AbstractManagedObjectPopulator.java:130)
        at org.jboss.managed.plugins.factory.AbstractManagedObjectFactory.initManagedObject(AbstractManagedObjectFactory.java:422)
        at org.jboss.managed.api.factory.ManagedObjectFactory.initManagedObject(ManagedObjectFactory.java:77)
        at org.jboss.system.server.profileservice.ProfileServiceBootstrap.initBootstrapMDs(ProfileServiceBootstrap.java:450)
        at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:242)
        at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:461)
        at org.jboss.Main.boot(Main.java:221)
        at org.jboss.Main$1.run(Main.java:556)
        at java.lang.Thread.run(Thread.java:662)
解决:vi /etc/hosts查看hostname与ip设置是否一致。
 
 
 
javascript调用android4.2中的方法失败?
Android4.2对webview中Javascript接口声明进行了修改,Android 4.2以上版本调用Javascript接口失败的解决方法是在方法之前
使用声明@JavascriptInterface。
view plaincopyprint?.addJavascriptInterface(new Object()
{  
                @JavascriptInterface  
                public void download(int bookId)  
                {  
                    bid = String.valueOf(bookId);  
                    downLoad.show();  
                }
 
 
访问url:http://172.17.252.88:10000/mjc/MtqWebService?wsdl报如下错:
Error creating bean with name 'MtqWebServiceServlethttp': Invocation of init method failed; 
nested exception is javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException
解决:MjcRequest类缺少无参构造函数,考,报错这么模糊。
public MjcResponse callByObject(MjcRequest mr) {}
public MjcRequest(){}
 
 
mtqj1.4.3版本改造成访问这个url需要给content-length,否则报411
http://172.17.248.74:11000/mjc/webtrans/s?aa=1111
 
 
mtq.properties中的READ_TIME_OUT设置是mtqj同步交易超时最大值。
注掉READ_TIME_OUT后刷新并不能还原成原先java中定义的值。
 
增加link的para=OB,表示mjc在调用时,函数入参是MjcCoreRequest,返回参数是MjcCoreResponse
 
mtqj的java端接口(MtqWebService+MtqMethodInvocationHandler)使用改变:
callByObject(MjcRequest mjcRequest):交易报文默认使用UTF-8转字节传递
callByObjectUsedBytes(MjcCoreRequest mjcCoreRequest):字节传递
http接口-MtqWebAction:取request.getInputStream(),字节传递
 
日志由异步线程来打的坏处是:
如果tps高导致记录的日志太大的话,而异步线程在写磁盘的速度又低,会导致日志队列变的巨大,导致fullgc时间过长,且无法清理。陷入死循环。
 
 
ConcurrentLinkedQueue非阻塞队列
BlockingQueue    阻塞队列
 
 
ant中条件判断这里有2种形式,一种是运用 target 的if and unless attributes (ant 中自带功能),
一种是运用ant-contrib(一个ant的插件)中的if else。
 
 
2014-09-25 16:45:32,937 [Thread-4630] ERROR com.cup.maps.online.OnlineTrans - WS调用失败:
java.lang.reflect.UndeclaredThrowableException
at $Proxy298.parseSchema(Unknown Source)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.addSchemas(DynamicClientFactory.java:423)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:271)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:198)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:191)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:146)
at com.cup.maps.online.OnlineTrans.getResponseByType(OnlineTrans.java:628)
at com.cup.maps.online.OnlineTrans.access$000(OnlineTrans.java:57)
at com.cup.maps.online.OnlineTrans$ServiceDealThread.run(OnlineTrans.java:834)
Caused by: 
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor500.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:52)
... 9 more
Caused by: 
java.lang.StackOverflowError
at org.apache.xerces.dom.ElementNSImpl.setName(Unknown Source)
at org.apache.xerces.dom.ElementNSImpl.<init>(Unknown Source)
at org.apache.xerces.dom.CoreDocumentImpl.createElementNS(Unknown Source)
at com.sun.xml.internal.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:118)
at com.sun.tools.internal.xjc.reader.internalizer.DOMBuilder.startElement(DOMBuilder.java:84)
at org.xml.sax.helpers.XMLFilterImpl.startElement(Unknown Source)
at com.sun.tools.internal.xjc.reader.internalizer.WhitespaceStripper.startElement(WhitespaceStripper.java:109)
at org.xml.sax.helpers.XMLFilterImpl.startElement(Unknown Source)
at com.sun.tools.internal.xjc.reader.internalizer.VersionChecker.startElement(VersionChecker.java:94)
at org.xml.sax.helpers.XMLFilterImpl.startElement(Unknown Source)
at com.sun.tools.internal.xjc.reader.internalizer.AbstractReferenceFinderImpl.startElement(AbstractReferenceFinderImpl.java:80)
at org.xml.sax.helpers.XMLFilterImpl.startElement(Unknown Source)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:236)
...
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:119)
at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.parseSchema(SchemaCompilerImpl.java:131)
... 13 more
解决:多线程调用DynamicClientFactory.createClient()时出现死循环,导致StackOverflowError错误。解决方法重启。
提出的缺陷
http://stackoverflow.com/questions/23907726/jaxwsdynamicclientfactory-newinstance-createclientwsdl-java-lang-reflect-u
http://mail-archives.apache.org/mod_mbox/cxf-issues/201405.mbox/%3CJIRA.12717029.1401278298753.30879.1401278406504@arcas%3E
 
 
 
2014-09-25 16:46:29,770 [Thread-4635] ERROR com.cup.maps.online.OnlineTrans - WS调用失败:
java.lang.reflect.UndeclaredThrowableException
at $Proxy298.bind(Unknown Source)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:273)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:198)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:191)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:146)
at com.cup.maps.online.OnlineTrans.getResponseByType(OnlineTrans.java:628)
at com.cup.maps.online.OnlineTrans.access$000(OnlineTrans.java:57)
at com.cup.maps.online.OnlineTrans$ServiceDealThread.run(OnlineTrans.java:834)
Caused by: 
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor528.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:52)
... 8 more
Caused by: 
java.lang.reflect.UndeclaredThrowableException
at $Proxy300.error(Unknown Source)
at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.error(SchemaCompilerImpl.java:276)
at com.sun.tools.internal.xjc.util.ErrorReceiverFilter.error(ErrorReceiverFilter.java:73)
at com.sun.xml.internal.xsom.impl.parser.ParserContext$2.error(ParserContext.java:178)
at com.sun.xml.internal.xsom.impl.parser.ParserContext$1.reportError(ParserContext.java:156)
at com.sun.xml.internal.xsom.impl.parser.NGCCRuntimeEx.reportError(NGCCRuntimeEx.java:146)
at com.sun.xml.internal.xsom.impl.parser.DelayedRef.resolve(DelayedRef.java:98)
at com.sun.xml.internal.xsom.impl.parser.DelayedRef.run(DelayedRef.java:64)
at com.sun.xml.internal.xsom.impl.parser.ParserContext.getResult(ParserContext.java:107)
at com.sun.xml.internal.xsom.parser.XSOMParser.getResult(XSOMParser.java:202)
at com.sun.tools.internal.xjc.ModelLoader.createXSOM(ModelLoader.java:515)
at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:228)
... 12 more
Caused by: 
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:52)
... 24 more
Caused by: 
java.lang.RuntimeException: Error compiling schema from WSDL at {http://145.0.153.23:10080/mjc/MtqWebService?WSDL}: undefined simple or complex type 'tns:callByObject'
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory$InnerErrorListener.error(DynamicClientFactory.java:579)
... 29 more
Caused by: 
org.xml.sax.SAXParseException: undefined simple or complex type 'tns:callByObject'
at com.sun.xml.internal.xsom.impl.parser.ParserContext$1.reportError(ParserContext.java:152)
... 19 more
解决:上面那个报错发生后,再次调用这个函数DynamicClientFactory.createClient均会出现这个问题。
 
 
 
 
ulimit 限制的是当前 shell 进程以及其派生的子进程.
建议设置成无限制(unlimited)的一些重要设置是:
数据段长度:ulimit –d unlimited
最大内存大小:ulimit –m unlimited
堆栈大小:ulimit –s unlimited
CPU 时间:ulimit –t unlimited
虚拟内存:ulimit –v unlimited
 
 
 
response.getoutputstream 可以close()多次吗?
解决:试验后发现可以执行多次不报错。
 
 
 
替换某个目录/home/mi_mgmap/sl下的所有文件的某个字符串/SERVICE01/ma,改成/maps
即使用/maps替换/SERVICE01/ma,命令如下:
sed -i "s/\/SERVICE01\/ma/\/maps/g" `grep /SERVICE01/ma -rl /home/mi_mgmap/sl`
注意:特殊字符 / 需要用 \/ 代替;`是1左边的符号;/home/mi_mgmap/sl是需要替换文件的目录
 
 
查找某一类型文件(比如.h文件)中含有的字符串(比如ABC)
find . -name "*.h"|xargs grep -R ABC
 
 
调整JBOSS最大连接数.
配置deploy/jboss-web.deployer/server.xml文件 .
       <Connector         port="8080"         address="0.0.0.0"         maxThreads="1600"         minSpareThreads="100"
         maxSpareThreads="250"         emptySessionPath="false"         enableLookups="false"         redirectPort="8443"
         acceptCount="800"         connectionTimeout="20000"         disableUploadTimeout="true"         URIEncoding="UTF-8"/>
maxThreads:表示最多同时处理的连接数。应该将线程数(最大线程数)设置比最大预期负载(同时并发的点击)多25%(经验规则)。
acceptCount:当同时连接的人数达到maxThreads时,还可以接收排队的连接。
minSpareThread:指“启动以后,总是保持该数量的线程空闲等待”;设置比预期负载多25%。 
maxSpareThread:指“如果超过了minSpareThread,然后总是保持该数量的线程空闲等待”;设置比预期负载多25%。
其中主要修改两个参数maxThreads和acceptCount值。增加maxThreads,减少acceptCount值有利缩短系统的响应时间。
但是maxThreads和acceptCount的总和最高值不能超过6000,而且maxThreads过大会增加CPU和内存消耗,
故低配置用户可通过降低maxThreads并同时增大acceptCount值来保证系统的稳定。
下表罗列出了在不同并发情况下jboss参数与并发在线的一般关系。
并发数服务器内存jboss参数
  maxThreadsacceptCount
50以下2G256800
50-3004G6001024
300-8008G10241528
800-10008G10242048
1000-120012G15262048
1200-150016G20482048
 
 
top命令找到占用CPU最高的java线程?
1、top -Hp 28174 -d 2 -n 6 
解释:查找进程号pid=28174的所有线程,每隔2秒显示一次,共6次。
找到最耗CPU的线程是20766,转换成16进制511e
2、/usr/java/jdk1.6.0_37/bin/jstack -l  28174 | grep 511e -A 20
用jstack命令查看线程堆栈,-A 20表示显示以511e开头的后20行记录。
例:
"DestroyJavaVM" prio=10 tid=0x00002aaab4268800 nid=0x511e waiting on condition [0x0000000000000000]  
   java.lang.Thread.State: RUNNABLE  
   Locked ownable synchronizers:  
        - None
(此方法还能看到哪个线程存活时间最长)
 
 
 
jsp、freemarker、velocity优缺点
jsp优点:官方标准,支持TAG、EL,使用java代码,丰富的第三方标签库。缺点是前后分离较难,容易破坏MVC结构。
velocity优点:不能写java代码,严格的前后分离;性能最佳;使用表达式语言。缺点是非官方标准;文档少。
freemarker优点:不能写java代码,严格的前后分离;性能较好;使用表达式语言;内置大量常用功能;支持jsp标签。缺点是非官方标准;文档少。
 
JSF优点是开发大量数据交互和表单展示时比较方便;缺点是学习曲线陡峭,UI组件及其生命周期需要学习,组件限制了前端展示的自由度,
对于企业内部系统比较合适。最好的框架是自己开发的框架,修改方便,了解框架极限。
 
 
 
velocity在与spring一起使用时,要使得vhtml模板能使用jsp里面的request对象,要在spring-mvc.xml中的
<bean id="velocityViewResolver"
配置
<property name="requestContextAttribute" value="req"/>
这样在vhtml中可使用如下方法:
${req.contextPath}      == /biz (注意前面有个斜杠/)
 
 
 
Velocity与jQuery的$发生冲突时的三种解决办法:
Velocity的$与Jquery的$发生冲突时的解决方法有以下几个:
1、使用jQuery代替$。
   如:jQuery.ajax();
   缺点:不适合扩展,一旦替换成第三方库时,那就麻烦大发
2、使用jQuery.noConflict。
   如:var j = jQuery.noConflict(); j.ajax();
   缺点:当使用jQuery的相关插件时,会使得插件失效哦!
3、wrap jQuery中的冲突方法。
   如$.ajax()在Velocity中会冲突,则重新定义如下:
function dw(){}
dw.ajax=function(s){
    jQuery.ajax(s);
}
dw.ajax();
方案3基本上解决了1、2中的缺点~~~故推荐使用第三种方法!
 
 
 
SPRING MVC 的请求参数获取的几种方法?
1、通过@PathVariabl注解获取路径中传递参数
JAVA
 @RequestMapping(value = "/{id}/{str}")
 public ModelAndView helloWorld(@PathVariable String id, @PathVariable String str) {
 System.out.println(id);
 System.out.println(str);
 return new ModelAndView("/helloWorld");
}
2、用@ModelAttribute注解获取POST请求的FORM表单数据
JSP
<form method="post" action="hao.do">
 a: <input id="a" type="text" name="a"/>
 b: <input id="b" type="text" name="b"/>
 <input type="submit" value="Submit" />
</form>
JAVA pojo
 public class Pojo{
 private String a;
 private int b;
}
JAVA controller
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pojo") Pojo pojo) {
 return "helloWorld";
 }
3、直接用HttpServletRequest获取
JAVA
@RequestMapping(method = RequestMethod.GET)
public String get(HttpServletRequest request, HttpServletResponse response) {
 System.out.println(request.getParameter("a"));
 return "helloWorld";
}
4、用注解@RequestParam绑定请求参数a到变量a
当请求参数a不存在时会有异常发生,可以通过设置属性required=false解决,
例如: @RequestParam(value="a", required=false)
JAVA
@RequestMapping(value = "/requestParam", method = RequestMethod.GET)
public String setupForm(@RequestParam("a") String a, ModelMap model) {
 System.out.println(a);
return "helloWorld";} 
 
 
 
<UL id=comparePro>
        <li id=compare_prod_list_001>信用卡贷款活动产品1-中国建设银行</li>
         <li id=compare_prod_list_002>信用卡贷款活动产品2-中国建设银行</li>
        <li id=compare_prod_list_003>信用卡贷款活动产品3-中国建设银行</li>
<li id=other>其他</li>
</UL>
要取到所有 id以compare_prod_list_开头的<li>   :  var list=$('li[id^=compare_prod_list_]');
 
 
 
遍历json 对象的属性并且动态添加属性
 var person= {
  name: 'zhangsan',
  pass: '123' ,
  'sni.ni' : 'sss',
  hello:function (){
     for(var i=0;i<arguments.length;i++){
             //在不知参数个数情况下可通过for循环遍历            
             // arguments这个是js 默认提供
            alert("arr["+i+"]="+arguments[i]);
     }    
  }
 }
  
//遍历属性
 for(var item in person){
    if(typeof person[item]  === 'string'){
      alert("person中"+item+"的值="+person[item]);
    }else if(typeof person[item] === 'function'){
        person[item](1,1);//js 的function的参数可以动态的改变
    } 
 }
//添加属性
 person.isMe = 'kaobian'; // 这种是属性名字正常的
//当属性名字不正常时,像下面这种,必须用这种形式的,
 person['isMe.kaobian'] = 'hello kaobian'; //上面的也可以用下面的形式
 
 for(var item in person){
    if(typeof person[item]  === 'string'){
      alert("person中"+item+"的值="+person[item]);
    }else if(typeof person[item] === 'function'){
 
        person[item](1,1);
    } 
 } 
 
 
调用load方法的完整格式是:load( url, [data], [callback] ),其中
url:是指要导入文件的地址。
data:可选参数;因为Load不仅仅可以导入静态的html文件,还可以导入动态脚本,例如PHP文件,所以要导入的是动态文件时,我们可以把要传递的参数放在这里。
callback:可选参数;是指调用load方法并得到服务器响应后,再执行的另外一个函数。
一:如何使用data
1.加载一个php文件,该php文件不含传递参数
$("#myID").load("test.php");
//在id为#myID的元素里导入test.php运行后的结果
2. 加载一个php文件,该php文件含有一个传递参数
$("#myID").load("test.php",{"name" : "Adam"});
//导入的php文件含有一个传递参数,类似于:test.php?name=Adam
3. 加载一个php文件,该php文件含有多个传递参数。注:参数间用逗号分隔
$("#myID").load("test.php",{"name" : "Adam" ,"site":"61dh.com"});
//导入的php文件含有一个传递参数,类似于:test.php?name=Adam&site=61dh.com
4. 加载一个php文件,该php文件以数组作为传递参数
$("#myID").load("test.php",{'myinfo[]', ["Adam", "61dh.com"]});
//导入的php文件含有一个数组传递参数。
注意:使用load,这些参数是以POST的方式传递的,因此在test.php里,不能用GET来获取参数。
 
 
 
$(":input")                  选择所有的表单输入元素,包括input, textarea, select 和 button
$(":text")                     选择所有的text input元素
 
$("#myELement")    选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素
$("div")           选择所有的div标签元素,返回div元素数组
$(".myClass")      选择使用myClass类的css的所有元素
$("*")             选择文档中的所有的元素,可以运用多种的选择方式进行联合选择:例如$("#myELement,div,.myclass")
 
层叠选择器:
$("form input")         选择所有的form元素中的input元素
$("#main > *")          选择id值为main的所有的子元素
$("label + input")     选择所有的label元素的下一个input元素节点,经测试选择器返回的是label标签后面直接跟一个input标签的所有input标签元素
$("#prev ~ div")       同胞选择器,该选择器返回的为id为prev的标签元素的所有的属于同一个父元素的div标签
 
基本过滤选择器:
$("tr:first")               选择所有tr元素的第一个
$("tr:last")                选择所有tr元素的最后一个
$("input:not(:checked) + span")  
 
过滤掉:checked的选择器的所有的input元素
$("tr:even")               选择所有的tr元素的第0,2,4... ...个元素(注意:因为所选择的多个元素时为数组,所以序号是从0开始)
 
$("tr:odd")                选择所有的tr元素的第1,3,5... ...个元素
$("td:eq(2)")             选择所有的td元素中序号为2的那个td元素
$("td:gt(4)")             选择td元素中序号大于4的所有td元素
$("td:ll(4)")              选择td元素中序号小于4的所有的td元素
$(":header")
$("div:animated")
内容过滤选择器:
 
$("div:contains('John')") 选择所有div中含有John文本的元素
$("td:empty")           选择所有的为空(也不包括文本节点)的td元素的数组
$("div:has(p)")        选择所有含有p标签的div元素
$("td:parent")          选择所有的以td为父节点的元素数组
可视化过滤选择器:
 
$("div:hidden")        选择所有的被hidden的div元素
$("div:visible")        选择所有的可视化的div元素
属性过滤选择器:
 
$("div[id]")              选择所有含有id属性的div元素
$("input[name='newsletter']")    选择所有的name属性等于'newsletter'的input元素
 
$("input[name!='newsletter']") 选择所有的name属性不等于'newsletter'的input元素
 
$("input[name^='news']")         选择所有的name属性以'news'开头的input元素
$("input[name$='news']")         选择所有的name属性以'news'结尾的input元素
$("input[name*='man']")          选择所有的name属性包含'news'的input元素
 
$("input[id][name$='man']")    可以使用多个属性进行联合选择,该选择器是得到所有的含有id属性并且那么属性以man结尾的元素
 
子元素过滤选择器:
 
$("ul li:nth-child(2)"),$("ul li:nth-child(odd)"),$("ul li:nth-child(3n + 1)")
 
$("div span:first-child")          返回所有的div元素的第一个子节点的数组
$("div span:last-child")           返回所有的div元素的最后一个节点的数组
$("div button:only-child")       返回所有的div中只有唯一一个子节点的所有子节点的数组
 
表单元素选择器:
 
$(":input")                  选择所有的表单输入元素,包括input, textarea, select 和 button
 
$(":text")                     选择所有的text input元素
$(":password")           选择所有的password input元素
$(":radio")                   选择所有的radio input元素
$(":checkbox")            选择所有的checkbox input元素
$(":submit")               选择所有的submit input元素
$(":image")                 选择所有的image input元素
$(":reset")                   选择所有的reset input元素
$(":button")                选择所有的button input元素
$(":file")                     选择所有的file input元素
$(":hidden")               选择所有类型为hidden的input元素或表单的隐藏域
 
表单元素过滤选择器:
 
$(":enabled")             选择所有的可操作的表单元素
$(":disabled")            选择所有的不可操作的表单元素
$(":checked")            选择所有的被checked的表单元素
$("select option:selected") 选择所有的select 的子元素中被selected的元素
 
选取一个name 为”S_03_22″的input text框的上一个td的text值
$(”input[@name =S_03_22]“).parent().prev().text()
 
名字以”S_”开始,并且不是以”_R”结尾的
$(”input[@name ^='S_']“).not(”[@name $='_R']“)
 
一个名为radio_01的radio所选的值
$(”input[@name =radio_01][@checked]“).val();
 
$("A B") 查找A元素下面的所有子节点,包括非直接子节点
$("A>B") 查找A元素下面的直接子节点 www.2cto.com
$("A+B") 查找A元素后面的兄弟节点,包括非直接子节点
$("A~B") 查找A元素后面的兄弟节点,不包括非直接子节点
 
 
unix系统提供两个数据文件:
utmp记录当前登陆进系统的各个用户
wtmp跟踪各个登陆和注销事件
who命令读取utmp并打印
last命令读取wtmp并打印
 
 
 
测试85-/maps/usr/ma_onl/xty/unix>uname -a
AIX P570_H_5 1 6 00C7112D4C00(操作系统 主机名 操作系统主版本 从版本号 硬件号码)
 
 
hostname 主机名
超级用户通过此命令设置主机名,该名字通常是TCPIP网络上主机的名字。
 
测试85-/maps/usr/ma_onl/xty/unix>date -u +%a
Sun
测试85-/maps/usr/ma_onl/xty/unix>date -u +%x
11/09/14
格式输出
 
测试85-/maps/usr/ma_onl/xty/unix>echo $TZ 
Asia/Shanghai
该环境变量决定时区
 
 
 
UNIX下core文件的分析 一般步骤:
1. file core文件,可以显示出core文件是哪个进程产生的
2.使用gdb或者dbx加载core文件,  gdb 进程名  core文件
3.where,显示堆栈信息,显示出coredump的地方
 
 
 
使用如下方法提交表单时,recid将不会传到后台。必须在form表单中增加一个input=hidden列,名字叫recid
var path = "${req.contextPath}/vm/edit/$tblcd?recid="+1;
  jQuery('#form2').attr("action", path).submit();
 
 
0配置的spring mvc需要在web.xml如下配置:
<context:component-scan base-package="com.cup.maps.parameter.bizcontrol.contol" />
 
<aop:aspectj-autoproxy />
spring aop需要增加到:
<context:component-scan base-package="com.cup.maps.parameter.bizcontrol.contol,com.cup.maps.parameter.bizcontrol.advice">
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect" />
</context:component-scan>
<aop:aspectj-autoproxy />
 
 
使用stax读取xml:
"<message name="PARAM_EDITPAGE_TYPE_0">0</message>"
1、reader.getAttributeName(0)   ->   name
2、reader.getAttributeValue(0)->   PARAM_EDITPAGE_TYPE_0
3、reader.getElementText()->   0
在调用语句3后,1、2都不能调用了,会报错。
 
 
jquery复选框全选、全不选?
<input type="checkbox" id="recids" />全选
<input type="checkbox" id="recid" value="$actives.recid"/>
<input type="checkbox" id="recid" value="$actives.recid"/>
 
function doInit(){//初始化加载
  jQuery("#recids").change(function(){ 
jQuery(":checkbox").prop("checked",this.checked); 
});
}
 
 
Hibernate
save() 保存持久化对象,返回对应的主键值
persist()保存持久化对象,无返回值
load()加载持久化实例,无匹配时抛出HibernateException异常;如果设置了延迟加载,返回未初始化对象,直到调用该对象方法时,Hibernate才会访问db
get()加载持久化实例,无匹配时返回null;而且无延迟加载功能。
 
持久化对象的修改,会在flush()时保存入数据库,如:
News n = sess.load(News.class,new Integer(pk));
n.setTitle("");
sess.flush();
 
对于托管对象,可以采用update() merge() updateOrSave()方法保存修改:
update()
merge()   与update区别是不会持久化给定对象
updateOrSave()
lock()  将某个托管对象重新持久化
 
delete() 删除持久化实例
 
Hibernate映射文件
 
 
主从表级联操作,持久化实体操作的传播:(默认是none)
<one-to-one name="person" cascade="persist"/>
<one-to-one name="person" cascade="persist,delete,lock"/>
<one-to-one name="person" cascade="all"/>
 
Hibernate批量插入,多次调用下面语句将导致OutofMemory,解决是每隔若干条save记录后session.flush()+session.clear():
session.save(bean);    //session级别缓存。
 
 
HQL查询:
session.createQuery("...").setString("","").list();
 
 
apache配置负载均衡session粘性?
解决:
1、需要在apache的配置文件httpd.conf里最后一段加上
ProxyPass       /mposWcg balancer://wcgbalancer stickySession=JSESSIONID
ProxyPassReverse  /mposWcg balancer://wcgbalancer
<Proxy balancer://wcgbalancer>
BalancerMember http://172.18.63.69:12000/mposWcg loadfactor=1 route=Node1
BalancerMember http://172.18.63.70:12000/mposWcg loadfactor=1 route=Node2
</Proxy>
2、增加jboss的server.xml中jvmRoute并重启,两台设置要不一样
vi ~/upjas/upjas-minimal/server/default/deploy/jbossweb.sar/server.xml
修改 <Engine name="jboss.web" defaultHost="localhost">
成<Engine name="jboss.web" defaultHost="localhost" jvmRoute="Node1">
 
原理是给浏览器的Cookie中出了jsessionid外还增加了jvmRoute值,apache可以知道是从哪个jboss来的。
Cookie:"JSESSIONID=33430E7895899E3CD7A051A4457D1D85.Node1"
 
 
 
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:608)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
at java.lang.Class.privateGetPublicMethods(Class.java:2556)
at java.lang.Class.getMethods(Class.java:1412)
at org.springframework.beans.ExtendedBeanInfoFactory.supports(ExtendedBeanInfoFactory.java:53)
at org.springframework.beans.ExtendedBeanInfoFactory.getBeanInfo(ExtendedBeanInfoFactory.java:44)
at org.springframework.beans.CachedIntrospectionResults.<init>(CachedIntrospectionResults.java:236)
at org.springframework.beans.CachedIntrospectionResults.forClass(CachedIntrospectionResults.java:152)
at org.springframework.beans.BeanWrapperImpl.getCachedIntrospectionResults(BeanWrapperImpl.java:321)
at org.springframework.beans.BeanWrapperImpl.getPropertyDescriptorInternal(BeanWrapperImpl.java:351)
at org.springframework.beans.BeanWrapperImpl.isWritableProperty(BeanWrapperImpl.java:427)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
... 26 more
Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
... 40 more
解决:加入jta.jar
 
 
 
java.lang.ClassNotFoundException: antlr.RecognitionException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at org.hibernate.hql.ast.ASTQueryTranslatorFactory.createQueryTranslator(ASTQueryTranslatorFactory.java:58)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:98)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1694)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:914)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:912)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
at com.cup.maps.parameter.bizcontrol.dao.ParamDao.getInqFldByTblcd(ParamDao.java:14)
at com.cup.maps.parameter.bizcontrol.service.ParamSerivceImpl.genInqFldInParaFileds(ParamSerivceImpl.java:118)
at com.cup.maps.parameter.bizcontrol.service.ParamSerivceImpl.setParamQueryInq(ParamSerivceImpl.java:103)
at com.cup.maps.parameter.bizcontrol.contol.InitController.bizParaminit(InitController.java:41)
at com.cup.maps.parameter.bizcontrol.contol.InitController$$FastClassByCGLIB$$886e2fe6.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:91)
at com.cup.maps.parameter.bizcontrol.advice.DealforVm.privcheck(DealforVm.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at com.cup.maps.parameter.bizcontrol.contol.InitController$$EnhancerByCGLIB$$529de169.bizParaminit(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1760)
at java.lang.Thread.run(Thread.java:662)
解决:引入antlr.jar
 
 
org.hibernate.hql.ast.QuerySyntaxException: TblMamgmParaFldAttr is not mapped [from TblMamgmParaFldAttr a]
at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:181)
at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
解决:使用hbm.xml中的class name 而不是table真实表名。
find("from TblMamgmParaFldAttr a");
 
 
 
org.hibernate.MappingException: Unknown entity: com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmParaFldAttr
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:629)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:91)
解决:spring和hibernate整合在配置sessionFactory时有两种配置方法。
方法一:不要hibernate.cfg.xml,在applicationContext.xml中配置如下
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"></property>
<property name="mappingResources">
<list>
<value>com/cup/maps/parameter/bizcontrol/model/hibernate/TblMamgmParaFldAttr.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.DB2Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.release_mode">
auto
</prop>
<prop key="hibernate.transaction.auto_close_session">
true
</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
 
方法二:
applicationContext.xml中配置:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"></property>
<property name="configLocations">  
        <value>classpath:hibernate.cfg.xml</value>  
    </property> 
</bean>
hibernate.cfg.xml中配置(propertry要再mapping之前):
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.DB2Dialect</property>
<property name="show_sql">true</property> 
<property name="hibernate.show_sql">true</property>  
<property name="hibernate.connection.release_mode">auto</property>  
<property name="hibernate.transaction.auto_close_session">true</property> 
<mapping
resource="com/cup/maps/parameter/bizcontrol/model/hibernate/TblMamgmIndustryInsAttr.hbm.xml" />
<mapping
resource="com/cup/maps/parameter/bizcontrol/model/hibernate/TblMamgmParaFldAttr.hbm.xml" />
</session-factory>
</hibernate-configuration>
 
 
 
 
Caused by: java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter
...
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:77)
... 16 more
Caused by: java.lang.ClassNotFoundException: javassist.util.proxy.MethodFilter
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 21 more
解决:缺少javassist.jar,在upjas\upjas-minimal\lib下。
 
 
 
org.hibernate.QueryException: could not resolve property: tblcd of: com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmParaFldAttr
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:61)
解决:字段名有问题,tblcd改成tblCd。
criteria.add(Restrictions.eq("tblcd", tblcd)).add(Restrictions.eq("inqFldIn", "1"));
改成
criteria.add(Restrictions.eq("tblCd", tblcd)).add(Restrictions.eq("inqFldIn", "1"));
 
 
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:64)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:623)
解决:
Session session = sessionFactory.getCurrentSession();这句报错。因为是直接从spring中获得的bean。
正确代码如下:
SessionFactory sessionFactory = (SessionFactory)SpringContextUtil.getBean("mgmSessionFactory");
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
。。。
tx.commit();
//session.close(); 无需调用close
 
 
org.hibernate.SessionException: Session was already closed
org.hibernate.impl.SessionImpl.close(SessionImpl.java:304)
com.cup.maps.parameter.bizcontrol.cache.ParamCache.init(ParamCache.java:60)
解决:如果不是使用的SessionFactory.getSession()来获得Session。而是使用SessionFactory.getCurrentSession()或者sessionFactory.openSession();
方法来获得Session时,当事务结束的时候,不管是提交还是回滚事务,hibernate会自动关闭Session的。
因此在tx.commit();后面不需要再session.close();
 
 
java.lang.UnsupportedOperationException: The user must supply a JDBC connection
at org.hibernate.connection.UserSuppliedConnectionProvider.getConnection(UserSuppliedConnectionProvider.java:54)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
解决:
 
 
 
 
win7 TortoiseCVS-1.12.5 cvs checkout乱码?
解决:卸载当前cvsnt软件,重新安装老版本cvsnt_setup.exe,重启win7就好了
 
 
 
解决Spring MVC ResponseBody 乱码问题?
在SpringMVC中,ResponseBody返回的中文是乱码,google了一下,原因是这可以说是spring mvc的一个bug,
spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list则使用
MappingJacksonHttpMessageConverter,返回string,则使用 StringHttpMessageConverter,这个convert
使用的是字符集是iso-8859-1,而且是final的
     public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");    
解决方法是在
    <context:annotation-config />  
前面加入以下配置:
    <bean  class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >    
        <property name="messageConverters">    
             <list>    
                 <bean class = "org.springframework.http.converter.StringHttpMessageConverter">    
                    <property name = "supportedMediaTypes">    
                         <list>
                             <value>text/plain;charset=UTF-8</value>    
                         </list>
                    </property>    
                 </bean>    
             </list>    
        </property>    
    </bean>    
但是也有网友认为前面这种方式不太优雅,而且不一定有效,经试验下面这种方法也可以:
    @RequestMapping(value="qxyjqyresult",produces = "plain/text; charset=UTF-8")  
        @ResponseBody  
        public String getQxyjqyResult(String filename) throws Throwable {  
    return "中文"  
    }  
也就是用produces。
 
 
 
使用另外一个相关联的对象的标识符作为主键。 
<id>元素中的<generator>用来为该持久化类的实例生成唯一的标识,hibernate提供了很多内置的实现。 
Increment:由hibernate自动递增生成标识符,用于为long, short或者int类型生成唯一标识。 
identity :由底层数据库生成标识符(自动增长),返回的标识符是 long, short 或者int类型的。 
sequence :hibernate根据底层数据库序列生成标识符,返回的标识符 是long, short或者 int类型的。 
hilo     :使用一个高/低位算法来高效的生成long, short 或者int类型的标识符。 
uuid.hex :用一个128-bit的UUID算法生成32位字符串类型的标识符。 
native   :根据底层数据库的能力选择identity, sequence 或者hilo中的一个。 
assigned :让应用程序在save()之前为对象分配一个标示符。 
foreign :使用另外一个相关联的对象的标识符。和<one-to-one>联合一起使用。
 
 
List list = session
.createQuery(
"select b.id.drdlItemKey,b.drdlItemVal from TblMamgmDrdlCfg a,TblMamgmDrdlItemDef b where a.drdlId = b.id.drdlId and a.drdlNm = :dropDownNm")
.setString("dropDownNm", dropDownNm).list();
联合主键在hbm.xml中的联合主键配置是: <composite-id name="id" class="com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDefId">
原生sql中使用则是b.id.drdlItemKey。
 
 
 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlCfg.drdlItemList, no session or session was closed
解决:这个是懒加载异常,就是在查询时没有加载关联表的对象,你读取这个关联对象的时候,hibernate的session已经关闭,所以无法获取对象。
你可以在配置文件里关闭懒加载 lazy=false
 
 
 
spring mvc中遇到了如何实现页面跳转的问题.比如在页面A中的提交按钮用户提交后,需要重定向到另外一个新的页面,并且有可能要把一些参数带
过去.
  这其实在实现中有两个方法
1 在controller中实现redirect,可以使用sendRedirect()方法,然后返回
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception 
{
........
 response.sendRedirect("photohouxuandetail.do?pid="+pid);
   return null;
}
2 还可以用redirect来实现,这样viewResolver认为是重定向操作,不再渲染该视图了,而是直接向客户端发出redirect响应
   return new ModelAndView("redirect:photohouxuandetail.do?pid="+pid);
 
 
 
 
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDef.operIn; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDef.operIn
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:665)
解决:在Hibernate中使用数据库字段默认值的配置 
1、在相关表的映射XML文件的class项增加:dynamic-insert="true"
2、同时需在相关字段设置:not-null="false"
 
 
 
org.springframework.dao.DataIntegrityViolationException: could not update: [com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDef#component[drdlId,drdlItemKey]{drdlItemKey=1111, drdlId=1111}]; SQL [update MA_MGMDB.TBL_MAMGM_DRDL_ITEM_DEF set DRDL_ITEM_VAL=?, OPER_IN=?, EVENT_ID=?, REC_ID=?, REC_UPD_USR_ID=?, REC_UPD_TS=?, REC_CRT_TS=? where DRDL_ID=? and DRDL_ITEM_KEY=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not update: [com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDef#component[drdlId,drdlItemKey]{drdlItemKey=1111, drdlId=1111}]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
解决:DataIntegrityViolationException。字段对应属性非空,改成not-null="false"
 
 
 
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'paramService' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'bziControltxAdvice' must be of type [org.aopalliance.aop.Advice], but was actually of type [org.springframework.transaction.interceptor.TransactionInterceptor]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
解决:TransactionInterceptor是 org.aopalliance.aop.Advice
的一个实现,可能是Jar包的冲突。
到jar包中去查看。
 我的问题是: aopalliance-1.0.jar 和 aopalliance-alpha1.jar之间的冲突。
 
 
 
 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataTableController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.cup.maps.parameter.bizcontrol.service.ParamSerivceImpl com.cup.maps.parameter.bizcontrol.contol.DataTableController.pService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.cup.maps.parameter.bizcontrol.service.ParamSerivceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
解决:强制转换的必须是接口类ParamService,而不是实际类ParamSerivceImpl
ParamService pService = (ParamSerivceImpl) SpringContextUtil.getBean("paramService");
改成
ParamService pService = (ParamService) SpringContextUtil.getBean("paramService");
 
 
 
 
Hibernate: select tmpmamgmin_.INDUSTRY_INS_ATTR_CD, tmpmamgmin_.INDUSTRY_INS_ATTR_NM as INDUSTRY2_6_, tmpmamgmin_.INDUSTRY_INS_ID_CD as INDUSTRY3_6_, tmpmamgmin_.INDUSTRY_INS_CATA_OPT as INDUSTRY4_6_, tmpmamgmin_.TEST_MD as TEST5_6_, tmpmamgmin_.RVSL_IN as RVSL6_6_, tmpmamgmin_.TO_RVSL_IN as TO7_6_, tmpmamgmin_.SYS_TO_SYS_FLAG as SYS8_6_, tmpmamgmin_.PROD_CUP_OPER_SPEC as PROD9_6_, tmpmamgmin_.CHNL_LD_CUP_OPER_SPEC as CHNL10_6_, tmpmamgmin_.CHNL_LD_CUP_BRANCH_OPER_SPEC as CHNL11_6_, tmpmamgmin_.CHNL_OPER_SPEC as CHNL12_6_, tmpmamgmin_.SP_OPER_SPEC as SP13_6_, tmpmamgmin_.SUCC_SP_RESP_INF as SUCC14_6_, tmpmamgmin_.REPAY_SP_RESP_INF as REPAY15_6_, tmpmamgmin_.NOTOUTBILL_SP_RESP_INF as NOTOUTBILL16_6_, tmpmamgmin_.SPEC_SP_RESP_INF as SPEC17_6_, tmpmamgmin_.CORRECT_USR_NO_SP_RESP_INF as CORRECT18_6_, tmpmamgmin_.REMARK as REMARK6_, tmpmamgmin_.OPER_IN as OPER20_6_, tmpmamgmin_.EVENT_ID as EVENT21_6_, tmpmamgmin_.REC_ID as REC22_6_, tmpmamgmin_.REC_UPD_USR_ID as REC23_6_, tmpmamgmin_.REC_UPD_TS as REC24_6_, tmpmamgmin_.REC_CRT_TS as REC25_6_ from MA_MGMDB.TMP_MAMGM_INDUSTRY_INS_ATTR tmpmamgmin_ where tmpmamgmin_.INDUSTRY_INS_ATTR_CD=?
org.springframework.orm.hibernate3.HibernateSystemException: identifier of an instance of com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmIndustryInsAttr was altered from 00002400-1-001     to 00002400-1-001; nested exception is org.hibernate.HibernateException: identifier of an instance of com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmIndustryInsAttr was altered from 00002400-1-001     to 00002400-1-001
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)
解决:实体中主键被修改了,所以报错。从00002400-1-001     改成了00002400-1-001,因为页面trim的关系。
 
 
 
spring多次执行flush也不会有问题:
this.getHibernateTemplate().flush();
 
 
 
 
在hibernate中实现oracle的主键自增策略
1、在oracle 首先创建sequence
      create sequence seq_id
      minvalue 1
      start with 1
      increment by 1
      cache 20;
2.在你的hbm.xml中的配置
   
     <id column="ID0000" name="id" type="integer">
         <generator class="sequence">
              <param name="sequence">seq_id</param>
         </generator>
     </id>
 
 
 
spring3中bean自动注入
@Resource(name="paramService")
ParamService paramService;
 
 
在dwr_spring.xml中配置的bean,必须在applicationContext.xml中配置,spring-mvc.xml不可以。
 
 
spring托管类,要想达到这个效果:在初始化并注入所有属性后,执行某个方法:
1、实现InitializingBean
public class ParamCache  implements InitializingBean
 
2、实现这个方法afterPropertiesSet
public void afterPropertiesSet() throws Exception {
init();
}
 
 
使用sessionFactory时未绑定事务,使用方法:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(TblMamgmParaTblAttr.class);
tx.commit();
 
 
 
 
DAO层
DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件
中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,
DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。 
 
Service层
Service层主要负责业务模块的逻辑应用设计。同样是首先设计接口,再设计其实现的类,接着再Spring的配置文件中配置其实现的关联。
这样我们就可以在应用中调用Service接口来进行业务处理。Service层的业务实现,具体要调用到已定义的DAO层的接口,封装Service层
的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。 
 
Controller层
Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程,控制的配置也同样是在Spring的配置文件
里面进行,针对具体的业务流程,会有不同的控制器,我们具体的设计过程中可以将流程进行抽象归纳,设计出可以重复利用的子单元流程模块,
这样不仅使程序结构变得清晰,也大大减少了代码量。 
 
View层 
此层与控制层结合比较紧密,需要二者结合起来协同工发。View层主要负责前台jsp页面的表示, 
 
 
DAO层,Service层这两个层次都可以单独开发,互相的耦合度很低,完全可以独立进行,这样的一种模式在开发大项目的过程中尤其有优势,
Controller,View层因为耦合度比较高,因而要结合在一起开发,但是也可以看作一个整体独立于前两个层进行开发。这样,在层与层之前
我们只需要知道接口的定义,调用接口即可完成所需要的逻辑单元应用,一切显得非常清晰简单。 
 
DAO设计的总体规划需要和设计的表,和实现类之间一一对应。 
 
DAO层所定义的接口里的方法都大同小异,这是由我们在DAO层对数据库访问的操作来决定的,对数据库的操作,我们基本要用到的就是新增,
更新,删除,查询等方法。因而DAO层里面基本上都应该要涵盖这些方法对应的操作。除此之外,可以定义一些自定义的特殊的对数据库访问的方法。 
 
Service逻辑层设计 
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层
的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的
业务处理方法。 
 
在DAO层定义的一些方法,在Service层并没有使用,那为什么还要在DAO层进行定义呢?这是由我们定义的需求逻辑所决定的。DAO层的操作
经过抽象后基本上都是通用的,因而我们在定义DAO层的时候可以将相关的方法定义完毕,这样的好处是在对Service进行扩展的时候不需要
再对DAO层进行修改,提高了程序的可扩展性。
 
 
前置PIT环境管理启动时现象:nohup和serverlog中没有报错,cpu占用率近于0,等待很长时间以后nohup中报错,获取不了数据源miMng。
原因:server/default/lib中upjas_dbpm.jar没有删除,而upjas_setEnv.sh里面设置了dbpm的ip地址和PIT环境不在一个网段,所以用了很长的时间
去连接,可能jar包里面还重试了多次。
 
 
onblur="if(value==''){value='your email address'}" 失去焦点的时候
onfocus="" 得到焦点的时候
 
 
$("#textDiv").show();//显示div  
$("#imgDiv").hide();//隐藏div  
$("#sendPhoneNum").css("display", "none");   //通过jquery的css方法,设置div隐藏
$("#top_notice").attr("style", "display:block;");  //给元素设置style属性
 
 
用CSS设置浮动层
margin-top:0px; position:absolute; display:none
 
 
velocity 字符串解析报错:
#set($bmpnumvalue=${flds.value}.substring($bmpnum,$bmpnumend))
要改成下面这种,原因未知
#set($bmpnumvalue=$flds.value.substring($bmpnum,$bmpnumend))
 
jquery如果判断元素是否隐藏(hide)?_百度知道
$("p").is(":hidden")
 
 
让input表单只读的几种方法
方法1: onfocus=this.blur()
<input type="text" name="input1" value="建站学" onfocus=this.blur()>
方法2: readonly
<input type="text" name="input1" value="建站学" readonly>
<input type="text" name="input1" value="建站学" readonly="true">
方法3: disabled
<input type="text" name="input1" value="建站学" disabled>
 
 
Hibernate配置文件中设置隔离级别,默认是4
#hibernate.connection.isolation 4
<property name=” hibernate.connection.isolation”>4</property>
1:读操作未提交(Read Uncommitted)
2:读操作已提交(Read Committed)
4:可重读(Repeatable Read)
8:可串行化(Serializable)
 
1、更新丢失(Lost Update):两个事务都企图去更新一行数据,导致事务抛出异常退出,两个事务的更新都白费了。
2、脏数据(Dirty Read):如果第二个应用程序使用了第一个应用程序修改过的数据,而这个数据处于未提交状态,这时就会发生脏读。
第一个应用程序随后可能会请求回滚被修改的数据,从而导致第二个事务使用的数据被损坏,即所谓的“变脏”。
3、不可重读(Unrepeatable Read):一个事务两次读同一行数据,可是这两次读到的数据不一样,就叫不可重读。如果一个事务在提交数据之前,
另一个事务可以修改和删除这些数据,就会发生不可重读。
4、幻读(Phantom Read):一个事务执行了两次查询,发现第二次查询结果比第一次查询多出了一行,这可能是因为另一个事务在这两次查询
之间插入了新行。
 
1、读操作未提交(Read Uncommitted):说明一个事务在提交前,其变化对于其他事务来说是可见的。这样脏读、不可重读和幻读都是允许的。
当一个事务已经写入一行数据但未提交,其他事务都不能再写入此行数据;但是,任何事务都可以读任何数据。这个隔离级别使用排写锁实现。
2、读操作已提交(Read Committed):读取未提交的数据是不允许的,它使用临时的共读锁和排写锁实现。这种隔离级别不允许脏读,
但不可重读和幻读是允许的。
3、可重读(Repeatable Read):说明事务保证能够再次读取相同的数据而不会失败。此隔离级别不允许脏读和不可重读,但幻读会出现。
4、可串行化(Serializable):提供最严格的事务隔离。这个隔离级别不允许事务并行执行,只允许串行执行。这样,脏读、不可重读
或幻读都不可发生。
 
 
 
java.io.IOException: Missing config file: 'WEB-INF/para/dwr_spring.xml'
org.directwebremoting.impl.DwrXmlConfigurator.setServletResourceName(DwrXmlConfigurator.java:78)
org.directwebremoting.impl.StartupUtil.configureFromInitParams(StartupUtil.java:645)
jboss里面WEB-INF/para/dwr_spring.xml说是找不到?
解决:权宜之计
1、删除配置未知
<!--   <init-param>  
      <param-name>config-1</param-name>  
      <param-value>WEB-INF/para/dwr_spring.xml</param-value>  
  </init-param>
 -->
2、把dwr.xml配置文件移动位置,并改名。
把WEB-INF/para/dwr_spring.xml移动到web.xml平级目录,然后改名成dwr.xml
 
 
 
 
hibernate 默认jdbc事务,并整合spring后配置(在applicationContext.xml文件中):
<bean id="MgmDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbcMapsMng"></property>
</bean>
<bean id="mgmSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="MgmDataSource"></property>
<property name="configLocations">  
        <value>classpath:hibernate.cfg.xml</value>  
    </property> 
</bean>
<!-- 配置事务管理器 指定其作用的sessionFactory把事务交给Spring去处理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
    <ref bean="mgmSessionFactory"/>
    </property>
    </bean>    
<!-- bizcontrol 配置事务的传播特性 -->
    <tx:advice id="bziControltxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="active*" propagation="REQUIRED"/>
    <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
    <tx:method name="*" read-only="true"/>
    </tx:attributes>
    </tx:advice>
    
<!-- 那些类的哪些方法参与事务 -->
    <aop:config>
    <aop:pointcut id="allServiceMethod" expression="execution(* com.cup.maps.parameter.bizcontrol.service.*.*(..))"/>
    <aop:advisor pointcut-ref="allServiceMethod" advice-ref="bziControltxAdvice"/>
    </aop:config> 
 
 
hibernate 使用jboss的jta事务,并整合spring
1、applicationContext.xml文件中配置:
<bean id="MgmDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbcMapsMng"></property>
</bean>
<bean id="mgmSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="MgmDataSource"></property>
<property name="configLocations">  
        <value>classpath:hibernate.cfg.xml</value>  
    </property> 
</bean>
  <!-- 配置Spring使用JTA事务 -->
  <tx:jta-transaction-manager />
  
<!-- bizcontrol 配置事务的传播特性 -->
    <tx:advice id="bziControltxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="active*" propagation="REQUIRED"/>
    <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
    <tx:method name="*" read-only="true"/>
    </tx:attributes>
    </tx:advice>
<!-- 那些类的哪些方法参与事务 -->
    <aop:config>
    <aop:pointcut id="allServiceMethod" expression="execution(* com.cup.maps.parameter.bizcontrol.service.*.*(..))"/>
    <aop:advisor pointcut-ref="allServiceMethod" advice-ref="bziControltxAdvice"/>
    </aop:config>
2、hibernate.cfg.xml中配置:
<property name="hibernate.current_session_context_class">jta</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
3、com.cup.maps.parameter.bizcontrol.service包下的所有类的save、active、delete开头的方法自动具有事务属性。
 
 
 
 
 
 
 
form提交时
action="${req.contextPath}/vm/paramimport/$tblcd"
必须要写成这样
action="${req.contextPath}/vm/paramimport/${tblcd}"
 
 
 
dwr返回list<javabean>时报错:bean is null
解决:dwr.xml中要配置新加bean的东东,否则页面bean==null
 <convert converter="bean" match="com.cup.maps.parameter.bizcontrol.model.DropDownItem">  
        <param name="include" value="key,value" />  
</convert>
 
 
jquery获得某个name是INQ_加变量eventDef表示的值的select元素:
解决:jQuery("select[name=INQ_"+eventDef+"]").empty();
 
 
弹出框
 var sw = screen.width;
 var sh = screen.height;
 var w = 500;
 var h = 600; 
 var l = (sw-w)/2;
 var t = 200;
 var parm=",toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,maxsige=yes";
 var scoll="width="+w+",height="+h+",left="+l+",top="+t;
 var urls = "${req.contextPath}/vm/load/biztree?bpmparamaction=hySearch";
 window.open(urls,"_blank",scoll+parm);
注意:window.open()浏览器不支持隐藏地址栏
 
window.open()使用POST方式提交?
解决:注意form的target="newWin"
function submitForm(){  
  window.open('','newWin','width=400,height=500,scrollbars=yes');  
  form对象.submit();  
}
<FORM name=form action="YourActionFile.html" method="post" target="newWin">  
...  
</Form>
 
 
alert(parseInt("11111010", 2));
alert(parseInt("11111010", 2).toString(16));
 
 
 
 
overflow从字面意义上来讲就是溢出的意思,换句话说,你有个层,但是里面的内容,图片或者文字要比层大,
overflow就是针对这种情况进行处理的。
包含4个属性值,visible,hidden,auto,scroll
visible就是超出的内容仍然正常被显示出来。
hidden就是超出的内容被隐藏。
auto是默认值,根据内容剪切或者加滚动条。
scroll就是总加滚动条
 
 
 
bizcontrol生效页面,IE8无法生效?
解决:F12,浏览器模式选型IE8兼容性视图,文本模式选择IE8标准。原因是IE8兼容性模式下才支持JSON.stringify。
 
 
bizcontrol新增修改页面,IE8无法保存?
解决:发现IE8没有tmpvalue.trim()函数竟然,使用jQuery.trim(tmpvalue)替代。
 
 
firefox里生效页面,选择一条记录,点参数查看,然后点返回,报“文档已过期”错误,IE里面没有此错误?
解决:无法解决,不过在报“文档已过期”错误的那个页面上,点“重试”再次进入参数查看页面,点返回,回到参数查询页面。
 
 
hibernate关联记录,配置过滤条件和排序字段
<set name="drdlItemList" table="TBL_MAMGM_DRDL_ITEM_DEF" lazy="false" where="OPER_IN NOT IN ('D','d')" order-by="DRDL_ITEM_KEY">
        <key column="DRDL_ID" />
        <one-to-many
        class="com.cup.maps.parameter.bizcontrol.model.hibernate.TblMamgmDrdlItemDef" />
        </set>
 
 
 
db2查看锁表信息
>db2pd -db mamgmdb -locks show detail
 
表解锁
db2 force application all
 
 
SELECT * FROM SYSCAT.TABLES WHERE TBSPACEID = 2 AND TABLEID = 512;
 
SELECT * FROM SYSCAT.COLUMNS WHERE  TABNAME= '*******' AND COLNO = 8 
 
 
 
 
Javascript 判断是否存在函数的方法?
function aa()
{
 this.length=1;
 this.size =2;
}
if (typeof(aa)=="function")
alert(1);
else
alert(2);
 
使用SqlMapClientTemplate查询?
当执行没有参数的查询时: 
List result = getSqlMapClientTemplate().queryForList("TestSpace.qryTest");  
"TestSpace"为iBatis SqlMap文件的命名空间;"qryTest"为iBatis SqlMap的查询方法id 
 
当按照主键获取某条记录信息时: 
Long id = new Long("2");  
Object resultObj = getSqlMapClientTemplate().queryForObject("TestSpace.getTest", id);
 
 
LRU缓存介绍与实现 (Java)?
public class LRUCache<K,V> extends LinkedHashMap<K, V>{
    private LinkedHashMap<K,V>  cache =null ;
    private int cacheSize = 0;       
    public LRUCache(int cacheSize){
        this.cacheSize = cacheSize;
        int hashTableCapacity = (int) Math.ceil (cacheSize / 0.75f) + 1;
        cache = new LinkedHashMap<K, V>(hashTableCapacity, 0.75f,true)
        {
            // (an anonymous inner class)
            private static final long serialVersionUID = 1;
 
            @Override
            protected boolean removeEldestEntry (Map.Entry<K, V> eldest)
            {
                System.out.println("size="+size());
                return size () > LRUCache.this.cacheSize;
            }
        };
    }   
    public V put(K key,V value){
        return cache.put(key, value);
    }
    public V get(Object key){
        return cache.get(key);
    }
}
LRUCache<String, String> lruCache = new LRUCache<String, String>(5);
 
 
LinkedHashMap缺省是使用插入顺序的,如何构造一个访问顺序的LinkedHashMap呢?
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) accessOrder = true 即可。
 
LinkedHashMap提供按照访问的次序来排序的功能?
LinkedHashMap改写HashMap的get(key)方法(HashMap不需要排序)和HashMap.Entry的recordAccess(HashMap)方法
public Object get(Object key) {
        Entry e = (Entry)getEntry(key);
        if (e == null)
            return null;
        e.recordAccess(this); 
        return e.value;
    }
void recordAccess(HashMap m) {
            LinkedHashMap lm = (LinkedHashMap)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }
注 意addBefore(lm.header)是将该entry放在header线性表的最后。(参考LinkedHashMap.Entry extends HashMap.Entry 
比起HashMap.Entry多了before, after两个域,是双向的)
 
 
 
关于在RCP程序开发过程中遇到的:No Application ID has been found错误提示?
原因:依赖项添加不完整,漏掉了某些插件。
解决:运行配置中,在Main选项卡中选择运行方式为run an Application,然后在plugins选项卡中选择chose plugins and fregments from the list,
然后在列表中Workspace Plugins里面选择自己的插件,在target platform中先设为全不选,然后再点击右边的add required Plugins。
这样就可以把必须的插件都自动的添加到项目中。
 
 
 
Jar mismatch! Fix your dependenciesmPOSAppUnknownAndroid Dependency Problem?
解决:在开发Android项目的时候,有时需要引用多个项目作为library。在引用项目的时候,有时会出现“Jar mismatch! Fix your dependencies”错误。
这是因为两个项目的jar包(android-support-v4.jar)不一致。
解决方法是把2个jar都删除,然后各自加上最新的jar包。
 
 
Conversion to Dalvik format failed with error 1?
解决:做为lib工程,java build path标签的Libraries中不应该直接从Add External JARs引入android.jar,而是应该从Add Library
进入,再从Android Classpath Container进,点next,点Finish进入。

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Viewing all 167 articles
Browse latest View live
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>