首页
留言板
友链
关于
Search
1
内测“合金弹头”嘿嘿
1,197 阅读
2
Nginx搭建一个简易的图床
1,086 阅读
3
Kettle循环遍历结果集作为参数传入转换
1,085 阅读
4
Maven3.3.9的安装与配置
617 阅读
5
Maven打包插件与idea
580 阅读
知识库
好奇猫
日常说
笔记本
登录
/
注册
Search
标签搜索
maven
Spring
vue
Java
Java代码
前端
idea
帆软
MySQL
git
CSS
游戏
Bootstrap
生活
网上冲浪
邮件配置
说说
Nginx
Excel
数据库调优
龙流
累计撰写
61
篇文章
累计收到
34
条评论
首页
栏目
知识库
好奇猫
日常说
笔记本
页面
留言板
友链
关于
搜索到
3
篇与
Java
的结果
2022-11-09
JavaWeb前端技术细节记录
1、关于ajax技术? ajax的优点有: 1、提高了性能和速度减少客户端和服务器之间的流量传输,同时减少了双方响应的时间,响应更快,因此提高了性能和速度。 2、交互性能好可以异步与后台服务器发送数据,并返回数据到前台 3、异步调用客户端浏览器在开始渲染之前避免等待所有数据到达 4、节省带宽基于Ajax的应用程序使用较少的服务器带宽,因为无需重新加载完整的页面。 5、使用XMLHttpRequestXMLHttpRequest在Ajax Web开发技术中起着重要作用。XMLHttpRequest是由Microsoft设计的特殊JavaScript对象。XMLHttpRequest对象调用作为异步HTTP请求到服务器以传输数据。它用于向非Ajax页面发出请求。 6、拥有开源JavaScript库 : JQuery,Prototype,Scriptaculous等。 7、AJAX通过HTTP协议进行通信。 ajax的缺点有: 1、不安全,因为所有的文件都是从客户端进行下载 2、网络延迟影响用户体验 3、禁用JavaScript的浏览器无法使用 4、由于安全限制,产生的跨域问题,相较传统经典web应用程序更复杂2、ajax内部的主要参数有哪些?① async:要求为boolean类型,异步为true(默认),同步为false。 ② url:要求为string类型的参数,发送请求的地址。 ③ type:要求为Stirng类型,请求方式post或get。 ④ data:要求为object或stirng类型,发送到服务器的数据。 ⑤ dataType:要求为String 类型,预期服务器返回的数据类型。 ⑥ beforeSend:要求为function类型的参数。例如添加自定义HTTP头 ⑦ timeout:要求为number类型,设置请求超时时间(毫秒)。 ⑧ cache:要求为boolean类型,默认为true,是否从浏览器缓存中加载信息。 3、cookie和session关系,原理cookie是存储在客户端的, session是存储在服务的的,cookie相比session不安全些session原理: 客户端a访问服务器时,服务器生成进行session对象生成然后保存在服务器中,同时会产生一个sessionid返回给客户端cookie中。 session会话有声明周期,可以通过设置session属性,设置session过期时间或者是关闭浏览器结束一次会话session也会失效Jquery的常用选择器有哪些?首先,Jquery选择器主要分为基本选择器,层级选择器,过滤选择器和表单选择器具体的: 基本选择器:具体示例见手册文档或百度 层级选择器: 过滤选择器: 表单选择器:
2022年11月09日
128 阅读
1 评论
0 点赞
2022-03-24
java.lang.String的substring、split方法引起的内存问题
项目运行遇到了OutOfMemoryError异常.内存溢出?觉得是不是MaxPermSize设置小了,又给了1个G的大小,试下还是不行,然后使用Java heap分析工具,找出内存占用超出预期的嫌疑对象dump heapHeap Dump也叫堆转储文件,是一个Java进程在某个时间点上的内存快照。Heap Dump是有着多种类型的。不过总体上heap dump在触发快照的时候都保存了java对象和类的信息。通常在写heap dump文件前会触发一次FullGC,所以heap dump文件中保存的是FullGC后留下的对象信息。关于Heap Dump使用jconsole获取dump heap:建立连接后,选择页签MBean,执行com.sun.management. HotSpotDiagnostic下的操作dumpHeap。第一个参数p0是要获取的dump文件的完整路径名,记得文件要以.hprof作为扩展名(要在Memory AnalysisPerspective下打开扩展名必须是这个)。如果我们只想获取live的对象,第二个参数p1需要保持为true。JDK自带的jmap工具:Java代码jmap -dump:format=b,file=heap.bin <pid> format=b的含义是,dump出来的文件时二进制格式。 file-heap.bin的含义是,dump出来的文件名是heap.bin。 <pid>就是JVM的进程号。 (在linux下)先执行ps aux | grep java,找到JVM的pid;然后再执行jmap -dump:format=b,file=heap.bin <pid>,得到heap dump文件。analyze heap将二进制的heap dump文件解析成human-readable的信息,自然是需要专业工具的帮助,Memory Analyzer Memory Analyzer,简称MAT,是Eclipse基金会的开源项目,由SAP和IBM捐助。巨头公司出品的软件还是很中用的,MAT可以分析包含数亿级对 象的heap、快速计算每个对象占用的内存大小、对象之间的引用关系、自动检测内存泄露的嫌疑对象,功能强大,而且界面友好易用。 MAT的界面基于Eclipse开发,以两种形式发布:Eclipse插件和Eclipe RCP。MAT的分析结果以图片和报表的形式提供,一目了然。{gird column="2" gap="15"}{gird-item}{/gird-item}{gird-item}{/gird-item}{/gird}最后发现到这里内存突然就爆增看到这里我就觉得是不是split()使用的有什么问题于是就上网查了一下split学习了一下。原文连接:https://blog.csdn.net/caihaijiang/article/details/7748560先用一个极端例子说明String的substring方法引起的OutOfMemoryError问题:public class TestGC { private String large = new String(new char[100000]); public String getSubString() { return this.large.substring(0,2); } public static void main(String[] args) { ArrayList<String> subStrings = new ArrayList<String>(); for (int i = 0; i <1000000; i++) { TestGC testGC = new TestGC(); subStrings.add(testGC.getSubString()); } } }:对一个很长的字符串,使用substring循环保留该字符串里面的一小部分,保存到HashMap中运行该程序,结果出现:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space为什么会出现这个情况?查看一下JDK String类substring方法的源码,可以找到原因,源码如下: public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > count) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); }该方法最后一行,调用了String的一个私有的构造方法,如下: // Package private constructor which shares value array for speed. String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count; }该方法为了避免内存拷贝,提高性能,并没有重新创建char数组,而是直接复用了原String对象的char[],通过改变偏移量和长度来标识不同的字符串内容。也就是说,substring出的来String小对象,仍然会指向原String大对象的char[],所以就导致了OutOfMemoryError问题。找到问题之后,将上面代码中,getSubString的方法修改一下,如下: public String getSubString() { return new String(this.large.substring(0,2)); }将substring的结果,重新new一个String出来。再运行该程序,则没有出现OutOfMemoryError的问题。为什么?因为此时调用的是String类的public的构造方法,该方法源码如下: public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. int off = original.offset; v = Arrays.copyOfRange(originalValue, off, off+size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; }从代码可以看出,在String对象中value的length大于count的情况下,会重新创建一个char[],并进行内存拷贝。除了substring方法之后,String的split方法,也存在同样的问题,split的源码如下: public String[] split(String regex, int limit) { return Pattern.compile(regex).split(this, limit); }可以看出,String的split方法通过Pattern的split方法来实现,Pattern的split方法源码如下:public String[] split(CharSequence input, int limit) { int index = 0; boolean matchLimited = limit > 0; ArrayList<String> matchList = new ArrayList<String>(); Matcher m = matcher(input); // Add segments before each match found while(m.find()) { if (!matchLimited || matchList.size() < limit - 1) { String match = input.subSequence(index, m.start()).toString(); matchList.add(match); index = m.end(); } else if (matchList.size() == limit - 1) { // last one String match = input.subSequence(index, input.length()).toString(); matchList.add(match); index = m.end(); } } // If no match was found, return this if (index == 0) return new String[] {input.toString()}; // Add remaining segment if (!matchLimited || matchList.size() < limit) matchList.add(input.subSequence(index, input.length()).toString()); // Construct result int resultSize = matchList.size(); if (limit == 0) while (resultSize > 0 && matchList.get(resultSize-1).equals("")) resultSize--; String[] result = new String[resultSize]; return matchList.subList(0, resultSize).toArray(result); }方法中的第9行: Stirng match = input.subSequence(intdex, m.start()).toString();调用了String类的subSequence方法,该方法源码如下: public CharSequence subSequence(int beginIndex, int endIndex) { return this.substring(beginIndex, endIndex); }通过代码可以看出,最终调用的是String类的substring方法,因此存在同样的问题。split出来的小对象,直接使用原String对象的char[]。看了一下StringBuilder和StringBuffer的substring方法,则不存在这样的问题。其源码如下: public String substring(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) throw new StringIndexOutOfBoundsException(end); if (start > end) throw new StringIndexOutOfBoundsException(end - start); return new String(value, start, end - start); }最后一行,调用了String类的public构造方法,方法源码如下: public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.offset = 0; this.count = count; this.value = Arrays.copyOfRange(value, offset, offset+count); }方法不是直接使用原String对象的char[],而是重新进行了内存拷贝。
2022年03月24日
254 阅读
0 评论
0 点赞
2021-10-18
Java关于文件和目录的操作
{collapse}{collapse-item label="判断文件大小是否变化" open} 通过持续判断文件大大小有没有变化,在网络传输过程中,稳定的传输文件大小肯定会不断变大;当文件一段时间文件大小不变,不考虑其他情况(如断网),说明文件传输完成注意点:1、等待文件(非目录)读写完毕,费时的操作,不要放在主线程2、判断文件长度的方法不适用于粘贴复制操作的判断,粘贴复制一般file.length()时固定的不会有写入写出(test)public static boolean checkFileWritingOn(String fileName) throws Exception{ long oldLen = 0; long newLen = 0; File file = new File(fileName); while(true){ newLen = file.length(); if ((newLen - oldLen) > 0) { oldLen = newLen; System.out.println(file.length()); Thread.sleep(10000); } else { System.out.println("done"); return true; } } }{/collapse-item}{collapse-item label="获取文件创建时间、最后更新时间等" open} /** * 获取文件的创建时间 * @param file * @return */ public static Date getCreationTime(File file) throws IOException { if (file == null) { return null; }else { Path path = file.toPath(); BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); // 创建时间 Instant instant = attr.creationTime().toInstant(); Date fordate = Date.from(instant); return fordate; } // 更新时间 //Instant instant = attr.lastModifiedTime().toInstant(); // 上次访问时间 //Instant instant = attr.lastAccessTime().toInstant(); //String format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.systemDefault()).format(instant); //return format; }{/collapse-item}{collapse-item label="获取某路径下的所有文件/文件夹" open} /** * 获取路径下的所有文件/文件夹 * @param rootDir 需要遍历的文件夹路径 * @param isAddDirectory 是否将子文件夹的路径也添加到list集合中 * @return */ public static List<String> getAllFile(String rootDir, boolean isAddDirectory){ List<String> list = new ArrayList<String>(); File baseFile = new File(rootDir); if (baseFile.isFile() || !baseFile.exists()) { return list; } File[] files = baseFile.listFiles(); for (File file : files) { if (file.isDirectory()) { if(isAddDirectory){ list.add(file.getAbsolutePath()); } list.addAll(getAllFile(file.getAbsolutePath(),isAddDirectory)); } else { list.add(file.getAbsolutePath()); } } return list; }{/collapse-item}{collapse-item label="复制文件到指定目录" open} /** * @param filePath * @param targetPath * @throws IOException */ public static void fileCope(String filePath, String targetPath) throws IOException { //获得流 FileInputStream fileInputStream = new FileInputStream(filePath); File targetFile = new File(targetPath); //获取父目录 File parentFile = targetFile.getParentFile(); //判断是否存在 if (!parentFile.exists()) { // 创建父目录文件夹 parentFile.mkdirs(); } //判断文件是否存在 if (!targetFile.exists()) { //创建文件 targetFile.createNewFile(); } //新文件输出流 FileOutputStream fileOutputStream = new FileOutputStream (targetFile); byte[] buffer= new byte[1024]; int len; //将文件流信息读取文件缓存区,如果读取结果不为-1就代表文件没有读取完毕,反之已经读取完毕 while ((len=fileInputStream.read(buffer))!=-1) { fileOutputStream.write(buffer, 0, len); fileOutputStream.flush(); } fileInputStream.close(); fileOutputStream.close(); }{/collapse-item}{/collapse}
2021年10月18日
199 阅读
0 评论
0 点赞