Java琐记

  1. svn项目倒入,所选的文件夹一定是src上面以及的;然后eclipse会自动创建一个项目,项目名称就是src上级文件夹的名称;然后会按照路径下的文档结构如导入到eclipse的结构中;
  2. 被标记为// TODO的地方将会在"Task"窗口中显示出来;名称近似的"Task List"显示的Myln的任务列表;
  3. 要得到格式化的日期字符串使用的是SimpleDateFormat,这个类本身和日期没关系,只是负责格式,它的创建实例的时候传入格式new SimpleDateFormat("yyyyMMddHHmmss");如果想要获得某个日期(比如当前时间)的改格式化字符串:sdf.format(new Date());所以SimpleDateFormat只是负责格式,核心方法就是format,接受日期参数;这让我想起了"夫人"只是负责美;
  4. jdk的类查看文档或者源代码发生:"no source attachement"问题解决:Installed JREs界面,点击edit,指定对应的jar包后选择右侧按钮"Source attachment...",选择jdk原生文件包或者Program/java/jdkx.x/src.zip,添加即可;Jdk的源码就是前面所指的位置;解压缩之后也是达到了80M,纯文本文件啊,这些都是我将仔细去阅读;
  5. 类加载,对于相同byteCode的类,如果版本不同,在JVM中仍然将会被认为是两个不同的类,这也是为什么model类(实体类)要部署到_lib_下面原因,实体类的部署将会导致一系列的问题,抛出ClassCastException;但是这里有一个问题:难道业务处理类就没有这个问题了吗?
  6. 原来Eclipse可以和VS一样都是关联项目;动物快跑的Extension里面直接可以访问Entity工程里面定义的Entity,原来是在Build Path里面的Projects种添加了Entity工程的引用;两个Java就这样在一个Workspace里面完美交互了;那么workspace的概念是否是Solution呢?不同的是Workspace里面的项目必须在workspace所在的文件夹下,但是Solution的文件可以是物理位置不同的项目;
    1. 反编译推荐一:jad,和Eclipse配套使用Jadclipse(http://sourceforge.net/projects/jadclipse/ )以及jad.exe;配置Eclipse:Preference…/ Java/ JadClipse/;指定Path to decompiler(jad.exe的路径);然后Windows -> Perference -> General -> Editors -> File Associations中指定以及*.class(without Source)的jadClipse编辑器,其中*.class是指指定了source的class,这个可以不需要改动;
    2. 反编译推荐二:JD-GUI,可以将jar包按照内在文件路径反编译为java工程;
  7. SynchronizedJVM层面的同步,系统会监控将其释放,但是lock却是代码级别,需要在finally块中手动调用lock.unlock()进行锁释放;不过lock更加灵活,有定时锁,所以对于高并发的场合,lock可以提供性能;比如trylock,如果获取不到锁,就立即返回;lock(obj, timeout)就是定时锁,请求一段时间没有反应就返回;lock.lock(),就是死心眼,一直等下去;
  8. lock以及sync可以锁定两类对象,一类是"this",就是锁定当前代码段;另一类是指定对象,比如锁定一个List,保证在以下代码执行中该List不会被修改;如果想要操作排队去吧;
    1. Flume采用Http方式,采用JSON Handler,注意传递内容不用Encode;
    2. Collection:List,Set
    3. List:ArrayList,LinkList,Vector
    4. Set:HashSet,LinkSet,SortedSet:TreeSet
    5. Map:Hashtable,HashMap,LinkHashMap,SortedMap:TreeMap
    6. 调试Java发现异常:Unsupported major.minor version 52.0这是因为Java_Home指向1.7,但是Jar是使用JDK1.8编译;将JAVA_HOME指向1.8即可;
    7. 异常:Expected FS Format between '1' and '4', but found '6',这是因为repository使用1.8,但是eclipse的subEclipse版本却很低,下载使用site1.10.zip;Help -> Install New Installation... -> Archeve;
    8. Java中Double是double的封装类,前者是对象,后者是基本数据类型,这意味着Double是可以为空,但是double是不能的;着Redis的conn.zscore(...)中,返回的是Double,需要进行非空判断;如果想要获得一个准确的非空的值可以使用.doubleValue()获得;不做我觉得这样基本不需要了,除了不安全之外,没有任何作用;
    9. Java中Double是double的封装类,前者是对象,后者是基本数据类型,这意味着Double是可以为空,但是double是不能的;着Redis的conn.zscore(...)中,返回的是Double,需要进行非空判断;如果想要获得一个准确的非空的值可以使用.doubleValue()获得;不做我觉得这样基本不需要了,除了不安全之外,没有任何作用;
    10. 为了避免死锁,可以在创建锁对象的时候,通过Expire命令指定过期时间,或者通过set ... EX 3的方式进行指定;
    11. 我曾经一度以为watch--multi-continue模式(发现键值被改了,重新执行)毫无用处;作为更新操作而言,这种机制可能是有问题,因为添加watch本事就是为了防篡改,如果发现被改了就重新执行修改操作,那么也就不需要添加watch跟踪了;但是在查询场景下,如果跟踪的key被修改了,通常意味着查询结果有变化;比如自动补齐查询的条件是用户是工会的人;如果发现"工会的人"这个键发生了变化,那么导致查询结果可能就变化了,这个时候,就需要重新查询以获得准确数据;
      1. CollectionListSet
      2. ListArrayListLinkListVector
      3. SetHashSetLinkSetSortedSetTreeSet
      4. MapHashtableHashMapLinkHashMapSortedMapTreeMap
      5. servlet其实是一种标准,SUN提出来的用于运行在web服务器的小应用;具有很好的移植性,所以servlet程序既可以部署在tomcat上面,可以部署在IIS上面;tomcat原生支持servlet,是一个servlet容器,tomcat其实就是负责网络通信,接受http80(或者指定的某个端口)请求,封装为request然后发送给servlet(基于URL:请求端口以及路径),然后servlet处理完毕后将response交给tomcattomcat在处理并封装http包发送给请求端;当然tomcat还负责注入验证之类的功能,所以可以看到servlet容器和servlet分工之明确;值得注意的是尽管tomcat原生支持servlet,但是并没有直接使用,而是使用standwrap对其进行封装;struts1就是基于servlet架构;struts2是基于portletportlet也是基于servlet,因为web服务器都是可以支持(IIS需要添加插件)servlet,所以各个框架底层都是对servlet的封装;
      6. servlet三个生命周期:init(首次客户端请求),service(处理客户端请求)以及destroy
      7. MINA的应用场景,系统拆分各个子系统,子系统间通信并发量(主要是数据库数据插入)比较大,采用Webservice技术估计无法承担,于是采用MINA作为中间件,进行子系统间通信,保证了性能,同时共用了各个子系统的逻辑实现,数据库层的共享也避免了;我突然理解了MINA作为消息中间件的场景;
      8. tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory;maven执行cobertura总是报这个错误,原来是默认引用的sjf太老了;<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.6</version>
        </dependency>
        <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
        </dependency>
        问题搞掂;
      9. slf4f到底是什么,是日志门面simple logger facade for java
        1.
        如果你的日志中引入的是slf4f,那么就可以不进行任何配置,在classpath路径下,引入slf4j-api-1.4.1.jar(这是slf4j的核心包);
        2.
        如果只是simple风格,classpath添加slf4j-simple-1.4.1.jar即可,如果是jdk1.4风格,引入slj4j-jdk14-1.4.1.jar
        3.
        如果是log4j,需要引入两个包:slf4j-log4j12-1.4.1.jarlog4j-1.2.x.jar(当然还有log4j.properties);
        4.
        如果是logback,需要引入logback-classic-0.9.29.jarlogback-core-0.9.29.jar;其中classic功能类似于slf4j-log4j
      10. Eclipse里面有个"Link with editor"功能十分给力,可以根据你选择的文件自动定位到左侧的package Explorer中位置;可以再Package Explorer中设置(可逆的两个箭头图标),也可以在设置top element level菜单中设置;
      11. Spring可以指定一个属性文件(.properties文件),然后通过${email.url}方式占位,email.url在属性文件中定义;但是这并不是Spring的高级用法,应该是声明的方式吧;
      12. Eclipse其实内置了apache server,但是为什么还要搞tomcat插件呢?我理解内置的Server关联tomcat后,配置文件全部是在Eclipse中维护的,因为Eclipse将会创建一个工程,名称为Server,所有的配置文件将在这个工程中进行维护,之前步骤中指定的tomcat物理路径不过是指定了运行tomcatRuntime environment(虚拟机),读取配置还是在Eclipse里面工程维护;但是如果是tomcat插件,则是原生的使用指定的tomcat即使是配置文件都是读取tomcat根目录下的conf里面的配置文件;
  9. 最好是一个Web项目使用一个tomcat进行测试,因为再看console的时候不会混淆;当然一个工作空间多个Web项目更多的可能是测试情况,一般情况下应该只有一个Web项目;但是如果是Webservice也有可能是多个;
    1. 天去必捷必信息面试,回答了一段时间笔试题,发现Java还有很多基础知识细节有问题,手下是throw和throws,throws只是声明了方法级别可以捕获的异常;另外,throws意味着:显式声明本程序将会抛出那些异常(将不会做处理),这些异常需要调用方在代码中进行处理,所以调用方是一定要对这些异常进行处理,要么继续声明throws这些异常,让再外层调用方处理,要么就对异常进行捕获,try-catch块中捕获特定异常;throws的本质其实是告诉外部调用:这个异常我就不处理了,你看需要处理一下;
    2. 还有一道题目是final先执行还是先return,后来网调而且还有自己Debug测试,先执行return语句逻辑,但是不返回,比如"return b+=80"先让b=b+80,但是不返回;然后再走final,走完了final语句,再进行return;所以整体来讲就是先走逻辑,再有final,最后返回;
    3. 发现JSP打印出来的文字乱码,原来jsp文件头使用的编码方式是"ISO-8859-1",修改为UTF8搞掂;
    4. jps-v命令,查看java进程的状态;比如rocketMq(需要使用到jre)启动后,使用jps看将会看到其中一项就是rocketmq;但是安装了openjdk却没有这个,那是因为我安装的是openjdk的jre版本,还有delevl版本,里面应该会有的;
    5. Java.net.InetAddress.getLocalHost throws UnknowHostException,通过hostname,获得一个KXXX名称,将这个名称添加到etc/hosts的127.0.0.1的后面以及..0.1项的后面;问题解决;分析应该是对于该主机名称不知道应该如何解析;将名称添加到hosts文件,这样主机名和IP能够对应上去;之前访问google被屏蔽,就是通过修改hosts文件(window下面),将google请求映射到某个IP实现了访问,hosts文件的作用在于将请求的名称和IP进行映射;如果没有映射,那么就要交给DNS进行处理;
    6. RocketMQ发布在git上面,管理使用的是Maven,导入到方式:首先在git repository视图中,在右上角点击"add a new repository and add it to this view";然后配置为rocketmq的git地址即可;添加仓库成功后,File-import-Existing maven project,路径就选择本地仓库路径即可导入maven项目;
    7. 使用file对象避免了Windows以及Linux下的差别,file(file,name),从构建文件夹,在构建文件(基于文件夹),在通过getAbsolutePath函数获得完成路基,此时已经根据操作系统不同而返回相应的路径了;
    8. eclipse小应用,Ctrl+pageup或者Ctrl+pgdn可以在前后tab间切换,ctrl+c是单行或者多行注释;
    9. iosession的isclosing是返回当前session是否已经关闭或者是否正在关闭;
    10. 等待采用awaitxxx方法,不要采用wait,后者是指需要通过原生notify方式进行触发;
      1. 在eclipse里面,只要在注释中结尾添加</br>,即可实现格式化的时候不会合并为一行,而且现实更友好;
      2. logback可以设置logger样式,嫌打出全称太长,可以通过设置%logger{15}来进行设置;
      3. java 程序要打包成包含们menifest文件,就要指定main函数;
      4. jar文件打包有两种方式:第一种是原始的jar文件,这种方式里面是不会把lib里面的内容进行封装;runnable jar则是自动的将这些引用到的jar文件进行封装,并写入到menifest文件;
      5. 对于list<integer>要注意了,因为remove两个重载的方法,一个是索引,一个是对象,造成重复,需要把要删除的int处理为(object)n强转为对象元素;
      6. classloader. getSystemResourceAsStream方式完美适配调试和发布配置文件内置场景。
      7. 其实附加jar应该采用add jar的方式,因为我现在已经在工程内部维护了一个lib文件夹,那么引用的jar包都放入到此文件夹即可,这样,在build path的时候,不需要选择外部jar,而是内部jar;
      8. 在使用Junit进行测试的时候,fail一定要放到exception下面,否则先打出fail,异常信息就不会再输出了。
      9. 被final修饰类,该类不可被修改,比如Long以及String,他们一旦被创建,都不会再被修改。
      10. printwriter提供了一个autoflush参数,已经一个println方法,两者结合使用可以不需要手动进行fLush。尝试使用outputstreamwriter替代,但是没有成功.
      11. bufferreader里面多封装了一个readline,避免了reader里面只能读read的机制,所谓的buffer其实就是预读到第一个换行符。
      12. PrintoutputStream,构造的时候可以指定是否autoflush,如果不进行指定需要进行手动调用flush函数进行清空缓冲区;还可以使用OutputStreamWriter对于socket.getOutputStream进行封装;我觉得它比较专业。因为printwriter总是感觉是用于输出到控制台的。
      13. servlet是单例的,但是会通过dispatchThread对象进行线程调度,执行service方法的其实已经是线程池中的线程,serlet初始化会分析加载web.xml文件中的内容。这和传输其实很像,transportruntime是单例启动,对于见听到的请求交给mina有他分配线程池。
      14. 在web.xml文件中添加一个监听器,这个监听器继承自 servletcontextlistener,实现其中的destroy方法即可实现servlet销毁是动作;
      15. Java的快捷键配置想要导出导入:workspace里面的.metadata/.plugins/...core.runtime/setting/org.eclipse.ui.workbench.prefs里面的...commands属性中定义的,即是。
      16. web项目的工程引用,除了要在build path中添加项目之外,还要在右键-属性-deployment assembly中添加project, 之后就会在打包war的时候,将引用工程打入
      17. 双击变量方法后,同名的将会一起变色,这个配置在windows_preference_java _editor_mark ocurrences, 勾选上mark ocurrences...,即可。
      18. 文件锁只是用于多虚拟机间进行加锁,多线程的文件锁还是需要自己来实现。
      19. remote.internalantprogram异常,Ant在执行的时候报错,解决方案:The solution is to go to Run as → External tools configuration… → JRE where the default was set to "Separate JDK": jdk1.6.0_31 (I had set up JDKs 6-8 in Preferences after installing). I changed this to "run in the same JRE as the workspace" and now it works.
      20. 点开ecliose,告知jawa.exe找不到,但是老天知道我已经配置好了Javahome,后来知道是因为Jdk是32位,eclipse是64位造成,指定了64位的Jdk解决。
      21. Ant打包

1. ant中是顺序执行,比如对于transport工程而言,应该首先删除lib文件,创建lib文件,然后再打包infras包和protocal包;

2.对于引用项目默认是会和当前项目打到一个jar包中,这样引用项目的独立性就没有了,通过设置fileset属性(删除引用的工程的file节点)来指定jar包只是来自于当前项目的class文件(默认会将引用项目fileset包含到jar节点中)。

3.对于引用项目使用到的jar包(外部引用),在copyfile节点中进行定义。

4.引用项目单独打到指定位置后(比如lib文件夹下),需要在主体jar的class-path中进行添加。

  1. 即使是agent,你也可以将logbackjar包放进去,因为对于他们,到最后是不需要考虑将引用包打进去的(调整ant.xml配置来实现)。所以为了能够看到日志,可以这样做,同时要看到logback的这种特性
  2. 启动eclipse,报错,share JNI library找不到,这是因为eclipse的位数和系统默认的Jdk不一致。java -version,有64字样的为64位。只需要在ini文件中增加-vm 换行 ……jvm.dll即可。javaw.exe也可,但是将会导致启动一个javaw.exe的进程。client下的jvm.dll在设计为启动快速而做了优化,而server下的jvm则是在运行时的快速做了优化,绑定那个看需要了。
  3. 作为算术运算数字类型转换,要注意,返回值类型一定是运算元素类型都一致才可以:
    (double)(a/100),如果a是long,那么返回值类型还是long,除非:(double)a/100才可以。
  4. 莫名的发现有web工程编译错误,class not found,该类安静的在工程中躺着,去掉几个空行,再次启动,搞定。或者对于项目进行clean也可。
  5. 在JSP上面,通过task.feedbackstr,将会自动绑定调用getfeedbackstr;
  6. 采用ant打包,如果程序没有变化,将不会进行打包覆盖,比如transport.jar,打包的时候如果没变化将不会进行覆盖,但是tran_lib下面的如果有那么变化将会覆盖。
  7. 今天调试,在eclipse环境下调试web,发现有问题,网站起不来。后来发现在插件路径下(.meta/.plugin/org...server.core/tmp0/wtpwebapps)只是拷贝了web-info文件夹内容导致的,这个问题的解决可以手工到目录下将该文件夹删除(此时运行项目将会报错,说xxx文件找不到或者不可读),然后在server右键点击clean…即可。关键在于基于eclipse的插件原理,即使是Server插件(tomcat)其实也是一个插件,他的目录是在plugin下面。
  8. executorshutdown的本质是向其下属线程发送中断请求,只有实现了捕获中断的线程才会相应中断,进而关闭,比如进程逻辑中有阻塞类的take,有thread.sleep
  9. watcher并不很好支持多线程,因为文件会被重复下发,而且只有第一个线程是会一直处理任务,其他线程无法获得。
  10. swt其他线程来修改控件,要通过display.getdefault(),并注入runnable来进行操作。Swt其实和winForm是一样的。不允许你在UI线程做并发事情。
  11. 验证过,只要把logback.xml放在部署应用的根目录即可自动被slf4j发现。正确的部署是要把配置文件放到部署根目录,但是在eclipse环境下运行有问题,需要设置为资源文件夹,于是解决方案在于ant打包的时候,不要把resource文件夹内容打包到jar中,而是拷贝到部署根目录即可
  12. 使用ant进行文件复制,通常有两种方式:第一种,<copy todir=""><fileset dir=""><include/exclude name=""></fileset></copy>如果想要覆盖已有文件overwrite="true",默认是false
  13. 可以通过继承servletcontextlistener来进行web容器的初始化和销毁事件,还要进行一步: 在web.config里面进行配置,<liatener><listener-class>…</listener-class></listener>,一个listener只能添加一个listener-class。如要添加多个监听器,就添加多个<listener></listener>节点。
  14. 对于BlockingQueue,尽量不要使用poll,因为这是线程不安全的(没有阻塞),如果使用,需要加锁;或者使用take,安全方式。poll不安全是因为:可能是你poll之后,才插入,你看poll没有数据就不再处理;除非你再提供一种机制,来定时轮询访问BlockingQueue,以保证后续插入的数据能够被发现但是后来逻辑才发现其实阻塞take()毫无意义,因为现在的逻辑是如果是发现新的任务,那么是不向Queue中放入的,直接下发到传输模块进行传输;白白耽搁了一个线程。
  15. 关于执行脚本:
    Process proc;
    String[] cmds = { "/bin/sh", "-c", command };
    proc = Runtime.getRuntime().exec(cmds);
    调用Runtime的exec函数正确的姿势是定义一个command数组,前两个元素是“/bin/sh"以及”-c”,直接执行指令在执行诸如
    echo "mount -o username=Guest,password= //10.1.108.35/m010 /opt/mapper/11033/m010" >> /opt/mount.sh
    的时候无法执行。
    什么是/bin/sh,又什么是-c?
  16. sun.net.www.protocol.jar.JarURLConnection;报异常Access restriction required library rt.jar,这需要在Build Path中的Library/JDK下面有一个Access Rules,对于Access Rule进行编辑,选择Accessible,Pattern设置为**即可。Access restriction的原因是因为这些JAR默认包含了一系列的代码访问规则(Access Rules),如果代码中引用了这些访问规则所禁止引用类,那么就会提示这个错误信息。
  17. java compiler level does not match the version of the installed java project facet,问题解决:在工作空间.settings/org.eclipse.wst.common.project.facet.core.xml文件中,替换java版本为当前版本。
原文地址:https://www.cnblogs.com/xiashiwendao/p/5827552.html