• [技术干货] 2020-09-15:java里的wait()和sleep()的区别有哪些?
    2020-09-15:java里的wait()和sleep()的区别有哪些?#福大大架构师每日一题#
  • [技术干货] Java基础之文件操作(IO流)
    特意写一章关于IO流的知识,不为别的,是因为IO流实在太重要了文件文件对象File 就是文件对象,我们电脑上的文件和文件夹都可以用这个File实例化public class Test{     public static void main(String[] args){         // 获取绝对路径D盘的hello文件夹         File f1 = new File("D:/hello");         // 获取相对路径的hello.txt文件         File f2 = new File("hello.txt");         // 获取D盘的hello文件夹下hello.txt文件的实例         File f3 = new File(f1,"hello.txt");                  // 输出三个文件或者文件夹的绝对路径         System.out.println(f1.getAbsolutePath());         System.out.println(f2.getAbsolutePath());         System.out.println(f3.getAbsolutePath());     }}123456789101112131415上面代码注释讲的已经非常的详细了,用三种方式创建一个文件对象,怎么获取文件的绝对路径文件常用方法假设我们已经实例化了一个File对象f判断是否存在 f.exists()判断是否是文件夹 f.isDirectory()判断是否是文件 f.isFile()获取文件的长度 f.length()文件最后修改的时间 f.lastModified()设置文件最后修改时间 f.setLastModified(0) 这里的0代表的是时间戳 也就是1970.1.1 08:00:00文件重命名 f.renameTo(“newName”)以字符串数组的形式,返回当前文件夹下面的所有文件 f.list()以文件数组的形式,返回当前文件夹下面的所有文件 f.listFiles()以字符串形式返回所在文件夹 f.getParent()以字符串形式返回获取所在文件夹 f.getParentFile()创建一个文件夹 f.mkdir() 如果说f所在的父文件夹不存在就会抛出异常创建一个文件夹 f.mkdirs() 如果说f所在的父文件夹不存在就会自动给你创建一个父文件夹删除文件 f.delete()JVM结束的时候删除文件 f.deleteOnExit()遍历C:\WINDOWS下面所有文件public class Test{     public static void main(StringP[] args){         File f = new File("C:/WINDOWS");         File[] files;         int k=0;         long max = 0;         if(f.exists){             // 把文件夹下面的所有文件都取出来             files = f.listFiles();             // 遍历所有的文件取出体积最大的文件             for(int i=0;i<files.length();i++){                 if(files[i].length()>max){                     //如果比最大的文件还大就把他的下标记下来                     k = i;                     max = files[i].length();                 }             }         }else{             System.out.println("文件夹不存在");         }                  // 输出找到的最大的文件路径和它体积         System.out.println("最大文件路径: "+files[k]);         System.out.println("最大文件体积: "+files[k].length()+" 字节");     }}1234567891011121314151617181920212223242526编码编码是信息从一种形式或格式转换为另一种形式的过程常见的编码常见的编码方式有如下几种:ISO-8859-1 ASCII 数字和西欧字母GBK GB2312 BIG5 中文UNICODE (统一码,万国码)看样子,我们的中文就是属于这个GBK这种编码了,也就是说中文只能用GBK编码来存储嘛?这个肯定是错的,UNICODE称为万国码,也就是全世界任何国家的字符都是可以储存的,只不过,他占用的空间是最大的,比入英文字母只需要1字节的空间,汉字需要3字节的空间,但是Unicode它不管你是英文字母还是汉字,都统一给你4个字节,这样的话是比较浪费空间的,所以就诞生了UTF-8这种基于Unicode减肥版本的编码方式。UTF-8它可以对英文或者数字使用一个字节,对汉字使用三个字节,这样的话就避免了空间的浪费。Java源代码中的汉字在执行之后,都会变成JVM中的字符,而这些中文字符采用的编码方式,都是Unicode流什么流?流就是一系列的数据。当不同的介质之间有数据交互的时候,Java就是使用流来实现比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流。文件输入流如何创建文件输入流,看以下代码:public class Test{     public static void main(String[] args){         try{             File f = new File("D:/hello.txt");             // 通过这个文件输入流可以将硬盘上文件中的数据读取到java程序内存中来             FileInputStream fis = new FileInputStream(f);         }catch(IOException e){             e.printStackTrace();         }     }}1234567891011字节流字节输入流InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。FileInputStream是InputStream的子类,我们下面就用FileInputStream来实现读取文件的内容public class Test{     public static void main(String[] args){         try{             // 准备一个文本文件,里面内容是AB             File f = new File("D:/test.txt");             // 创建文件输入流             FileInputStream fis = new FileInputStream(f);             // 创建一个字节数组,它的长度就是文件的长度             byte[] all = new byte[(int)f.length()];             // 以字节流的形式读取文件中的所有内容到字节数组             fis.read(all);             for(byte b : all){                 System.out.println(b);            }             fis.close();                      }catch(IOException e){             e.printStackTrace();         }     }}123456789101112131415161718192021结果是65和66 也就是A和B对应的ASCII码字节输出流OutputStream 是字节输出流,更InputStream也是一样的,抽象类。所以我们用FileOutputStream为例往文件中写入数据public class Test{     public static void main(String[] args){         try{             // 准备一个文本文件,里面内容是空的             File f = new File("D:/test.txt");             // 创建文件输出流             FileOutputStream fis = new FileOutputStream(f);             // 创建一个字节数组,里面写上A和B的ASCII码             byte[] data = {65,66};             // 以字节流的形式将data里的数据写入到输出流             fis.write(all);             fis.close();          }catch(IOException e){             e.printStackTrace();         }     }}1234567891011121314151617我们打开对应的文件,发现数据就已经写在里面了,但是输出流跟输入流有一个区别,就是输出流的时候不一定要求文件存在,当文件不存在的时候,会自动给我们创建一个新的文件,而输入流则会抛出异常字符流字符流:就是在字节流的基础上,加上编码,形成的数据流字符流分为字符输入流Reader 和 字符输出流 Writer他们常用的子类就是FileReader 和 FileWriter字符输入流在之前我们使用了字节输入流读取文件中的内容,读取的AB打印出来是65和66现在我们来看一下使用字符输入流读取文件是什么样的结果public class Test {       public static void main(String[] args) {         // 准备文件hello.txt其中的内容是AB         File f = new File("d:/hello.txt");         // 创建基于文件的Reader         try (FileReader fr = new FileReader(f)) {             // 创建字符数组,其长度就是文件的长度             char[] all = new char[(int) f.length()];             // 以字符流的形式读取文件所有内容             fr.read(all);             for (char b : all) {                 // 打印出来是A B                 System.out.println(b);             }         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }       }}12345678910111213141516171819202122字符输入流可以直接读取文件中的字符字符输出流我们可以直接将一串字符存储到文件中,代码如下:public class Test{     public static void main(String[] args){         // 创建文件对象,文件内容是空的         File f = new File("D:/hello.txt");         // 要写入的字符串         String str = "hello";        char[] cs = str.toCharArray();         try(FileWrter fw = new FileWriter(f)){             fw.write(cs)         }catch(IOException e){             e.printStackTrace();         }     }}1234567891011121314文件中的内容就会变称hello中文读取上面我们学习了字节流和字符流,那么我们分别用两种流来从文件中读取汉字内容。用字节流读取中文内容首先你得了解文本是以哪种编码方式进行保存的使用字节流读取文本后,再使用对应的编码方式去识别这些文字public class Test{     File f = new File("D:/hello.txt");     try(FileInputStream fis = new FileInputStream(f)){         byte[] all = new byte[(int) f.length()];         fis.read(all);         //将读到的字节进行编码输出         String str = new String(all,"GBK");         System.out.println(str);     }catch(IOException e){         e.printStackTrace();     }}123456789101112用字符流读取中文内容FileReader得到的字符,肯定是已经把字节根据某种编码方式识别成的字符。FIleReader的编码方式可以用Charset.defaultCharset()获取,如果是中文的操作系统那么就是GBK假设现在我们的文件是用UTF-8编码方式保存的,那么我们该如何使用字符流读取文字呢?答案就是使用InputStreamReader,这个是字节流到字符流的桥接器,它可以按照指定的字符集读取字节并将它们转换为字符。public class TestStream {     public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException {         File f = new File("D:/hello.txt");         System.out.println("默认编码方式:"+Charset.defaultCharset());         //FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了         //而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK         try (FileReader fr = new FileReader(f)) {             char[] cs = new char[(int) f.length()];             fr.read(cs);             System.out.printf("FileReader会使用默认的编码方式%s,识别出来的字符是:%n",Charset.defaultCharset());             System.out.println(new String(cs));         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }         //FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替         //并且使用new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")); 这样的形式         try (InputStreamReader isr = new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"))) {             char[] cs = new char[(int) f.length()];             isr.read(cs);             System.out.printf("InputStreamReader 指定编码方式UTF-8,识别出来的字符是:%n");             System.out.println(new String(cs));         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }               }}1234567891011121314151617181920212223242526272829为什么中字的前面有一个?,如果你是用记事本另存为UTF-8的字符集编码的话,那么在第一个字节有一个标识,叫做BOM,用来标识这个文件是使用UTF-8编码的缓存流以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。为了解决以上弊端,采用缓存流。缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。就好比吃饭,不用缓存就是每吃一口都到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作缓存字符输入流BufferedReader可以一次性读取一行数据public class Test{     public static void main(String[] args){         /**         准备一个文件,里面的内容是         hello         world         你好         */         File f = new File("d:/hello.txt");         // 缓存字符输入流必须在一个存在的流的基础上创建         try(         FileReader fr = new FileReader(f);         BufferedReader br = new BufferedReader(fr);             ){             while(true){                 // 一次读取一行                 String line = br.readLine();                 if(line == null){                     break;                 }                 System.out.println(line);             }catch(IOException e){                 e.printStackTrace();             }         }     }}123456789101112131415161718192021222324252627缓存字符输出流PrintWrite,可以一次写出一行数据public class TestStream {         public static void main(String[] args) {         // 向文件lol2.txt中写入三行语句         File f = new File("d:/hello.txt");                    try (                           PrintWriter pw = new PrintWriter(f);                       ) {             pw.println("hello");             pw.println("world");             pw.println("你好");         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }         }}12345678910111213141516171819这里需要注意的是,缓存字符输入流的构造方法的参数是一个Reader,也就是一个字符流,而PrintWriter的构造参数可以是文件对象也可以是字节流或者字符流对象!缓存字节输入流和输出流分别是BufferedInputStream 和 BufferedOutputStream下面代码演示的是通过缓存字节输入流和输出流实现文件的复制public class Test{     public static void main(String[] args){         File file = new File("E:/我的文档/临时文件/视屏文件.ts");         File file1 = new File("E:/我的文档/临时文件/视屏文件(副本).ts");         try (                 FileInputStream fis = new FileInputStream(f);                 FileOutputStream fos = new FileOutputStream(f1);                 BufferedInputStream bis = new BufferedInputStream(fis);                 BufferedOutputStream bos = new BufferedOutputStream(fos);         ){             byte[] bytes = new byte[1024];             int len;             while(true){                 len = bis.read(bytes);                 if(len == -1){                     break;                 }                 bos.write(bytes,0,len);             }         }catch (IOException e){             e.printStackTrace();         }     }     }}
  • [技术干货] 2020-09-10:java里Object类有哪些方法?
    2020-09-10:java里Object类有哪些方法?
  • [大赛专区] 【中奖公示】【心得分享幸运奖】【求职训练营·Java实践排位赛来】11月中奖名单公布,12月赛程继续,分享学习心得感悟即可抽奖
    求职训练营·Java实践排位赛来啦华为专家手把手教你企业级Java编程规范迈出入职名企第一步现在起加入训练营,完成作业,在本帖内分享心得有机会获得华为耳机或精美周边一、中奖名单公布*抽奖公示视频请见本帖下方请12月期的获奖学员在1月10日前扫描下方二维码,用报名训练营的华为云账号登录,完成信息核对和邮寄信息填写,未在限定时间内反馈视为放弃。二、心得分享幸运奖规则1. 活动时间:即日起到2020年12月31日。2. 参与规则:报名训练营并完成作业题,在本帖下方回复心得的同学,即可参与抽奖。3. 奖品:华为手环4e篮球精灵(椰子灰)、华为mini蓝牙音箱、华为10000mAh移动电源SuperCharge快充版、华为周边(棒球帽、渔夫帽)。4. 中奖名单公布:每月抽奖并公示1次,当月公示上个月的心得分享幸运奖。5. 大赛官方会在本帖及官方QQ群内进行公示,请大家现在入群,第一时间收到中奖名单提醒。6. 领奖方式:请获奖学员在名单公布后的一周内内扫描下方二维码,用报名训练营的华为云账号登录,完成信息核对和邮寄信息填写,未在限定时间内反馈视为放弃。7. 发奖方式:奖品将在中奖名单公布后20个工作日内发放完成。*活动最终解释权归华为所有。三、心得分享幸运奖参与规则1. 报名训练营,报名链接>>>求职训练营·Java实践排位赛2. 进入大赛官网平台,页面左侧【训练营入口】加入课堂。进入课堂后,点击【作业】并完成。3. 进入答题页面,完成题目内容,点击“提交作业”即完成一题。4. 在本帖下方按以下格式回复心得内容:(1)我的华为云账号:XXX(必须提供,不然无法参与抽奖)(2)我的心得:XXX(3)心得内容:可以围绕课程内容、作业题和Java自由展开,比如:学习笔记分享(学霸、课代表们赶快来给同学们划重点,目前已有28位满分同学了哦,不来分享分享嘛);学习过程中遇到的困惑点,可以提出来,寻求其他同学和社区大神帮忙解答;学习过程中遇到的困惑点,并且自己找到解决思路的,也可以跟大家分享解决过程;学习过程中的感想感悟等等等等(纯自由发挥,心有多大,贴有多长)……【友情链接】学霸奖名单公布https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76258&page=1&extra=#pid340680学习激励奖名单公布https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76218&page=1&extra=#pid340451四、抽奖视频公示处【11月心得分享幸运奖】【12月心得分享幸运奖】
  • [大赛专区] 【中奖公示】【学霸奖】【求职训练营 · Java实践排位赛学霸奖】11月中奖名单公布,12月赛程继续,参与答题即可抽奖
    求职训练营·Java实践排位赛来啦华为专家手把手教你企业级Java编程规范迈出入职名企第一步现在起加入训练营,完成作业。得高分赢超值奖励你学习,我发奖,赶紧来呀!一、中奖名单公布1、满分学霸奖截止11月,前30位满分学霸学员已经全部诞生,学员们可以继续参加1600分高分抽奖、学习激励和心得分享奖的活动!2、高分抽奖奖励(1600分以上学员即可参与抽奖)*抽奖视频请见本帖下方3、奖品领取请12月期的获奖学员在1月10日前扫描下方二维码,用报名训练营的华为云账号登录,完成信息核对和邮寄信息填写,未在限定时间内反馈视为放弃。二、学霸奖规则活动时间:即日起到2020年12月31日【满分学霸奖励】:达到满分的同学可获得学霸奖,奖励华为华为手环 4 Pro,数量共30台,先完成先得。【高分抽奖奖励】:分数在1600分以上(含1600分)的同学,可获得抽奖机会1次。有机会获得华为AI音箱2(太空黑)HUAWEI Sound,第一期(9月、10月)每次抽奖送出8台。第二期(11月、12月)每次抽奖送出7台。*每人只能领奖1次1.训练营作业分值统计:共26个作业题,分为选择题和实践题两类。每题分值100分,总分值为2600分。系统以最后一次答题成绩为准(答题截止前可最多提交5次)。2.本次学霸奖分为【满分学霸奖励】和【高分抽奖奖励】两种。在活动期间,报名训练营,完成作业并取得满分或高分的学员,都有机会获得学霸奖品,数量有限,先完成先得。3.名单公布:每月公示获奖名单1次,将在当月的前5个工作日内,公示前一个月的学霸奖名单及抽奖名单。大赛官方会在本帖及官方QQ群内进行公示,请大家现在入群,第一时间收到中奖名单提醒。4.领奖方式:请获奖学员在名单公布后的一周内内扫描下方二维码,用报名训练营的华为云账号登录,完成信息核对和邮寄信息填写,未在限定时间内反馈视为放弃。5. 发奖方式:奖品将在中奖名单公布后20个工作日内发放完成。*活动最终解释权归华为所有。三、学霸奖参与方式 报名训练营,报名链接>>>求职训练营·Java实践排位赛            2. 进入大赛官网平台,页面左侧【训练营入口】加入课堂。进入课堂后,点击【作业】完成所有26个作业。           3. 进入答题页面,完成题目内容,点击“提交作业”即完成一题。26个作业均提交后,算最终完成作业。      在答题截止时间前可以多次修改(最多5次),系统以最后一次答题成绩为准。        【友情链接】学习激励奖名单公布https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76218&page=1&extra=#pid340451心得分享幸运奖名单公布https://bbs.huaweicloud.com/forum/thread-76417-1-1.html四、抽奖视频公示处:【9月高分抽奖奖励抽奖视频】【10月高分抽奖奖励抽奖视频】【11月高分抽奖奖励抽奖视频】【12月高分抽奖奖励抽奖视频】
  • [大赛专区] 【分享推荐奖】【活动规则】求职训练营·Java实践排位赛邀请激励,华为音箱、耳机、移动电源等价值万元豪礼等你拿!
    参加求职训练营·Java实践排位赛华为专家手把手教你企业级Java编程规范迈出入职名企第一步不仅完成作业有机会获奖邀请好友参加还可以收获华为音箱、手环、移动电源等价值万元豪礼!带着你的小伙伴一起参加吧!一、活动公告求职训练营·Java实践排位赛自上线以来,选手们的参与热情一直很高,尤其是分享推荐,但同时我们也发现学习激励奖还没有开奖。为了把所有奖品都发放到选手们手中,从第二期开始,将暂停分享推荐奖,同时加大了其他活动的奖励,希望已报名的同学多多完成课程作业并分享学习心得,一起瓜分学习激励奖和心得分享幸运奖。学霸奖 https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76258&page=1&extra=#pid340680学习激励奖 https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76218&page=1&extra=#pid340451心得分享幸运奖 https://bbs.huaweicloud.com/forum/thread-76417-1-1.html#学习不停 发奖不止#一起冲鸭!二、第二中奖名单(截止11月6日活动结束)三、第一期中奖名单四、分享推荐方式1. 点击右侧链接报名训练营>>> 求职训练营·Java实践排位赛,左上角点击【立刻报名】2. 报名成功后,页面会多出一个【分享大赛】按钮(在之前立刻报名按钮右侧)。点击【分享大赛】,即可生成你的专属链接和二维码海报。*被邀请账号必须真实有效,活动期间大赛组委会将核实账号有效性,非有效账号将取消获奖资格。*活动最终解释权归华为所有。五、分享推荐奖励如何加入课堂?1.前往大赛报名页面>>>求职训练营·Java实践排位赛,完成报名2.点击左侧菜单栏【训练营入口】3.点击页面中【加入课堂】按钮。六、分享推荐公布规则1. 活动时间:即日起到2020年10月31日2. 中奖名单公布方式:邀请人数由系统后台统一,每周公示1次。名单在本帖及QQ群公示,建议立刻入群,以便收取第一手中奖提醒3. 领奖方式:中奖学生请在名单公布后的7个工作日内,扫描下方二维码填写邮寄信息,逾期视为自动放弃。奖品将于10月31日后的10个工作日内发放完毕。领取奖品请在此处扫码登记!4.训练营报名链接>>>求职训练营·Java实践排位赛活动解释权归华为所有。
  • [大赛专区] 【中奖公示】【学习激励奖】参加求职训练营·Java实践排位赛,赢蓝牙音箱
    求职训练营·Java实践排位赛来啦华为专家手把手教你企业级Java编程规范迈出入职名企第一步 现在起加入训练营,听课完成作业,就有机会获得多重学习激励你学习,我发奖,赶紧来呀!一、中奖名单公布1、学习激励奖中奖名单*抽奖公示视频请见本帖下方2、电子证书名单3、奖品领取请12月期的获奖学员在1月10日前扫描下方二维码,用报名训练营的华为云账号登录,(1)学习激励奖中奖学员请填写奖品邮寄信息,(2)电子证书学员请填**实姓名及邮箱。未在限定时间内反馈视为放弃。二、学习激励奖规则活动时间:即日起到2020年12月31日1. 训练营作业分值统计:共26个作业题,分为选择题和实践题两类。每题分值100分,总分值为2600分。2. 获得【学习激励奖】条件:自9月10日起,报名训练营,加入课堂并完成作业的选手,都有机会获得学习激励奖品,数量有限,先完成先得。3. 抽奖频次:大赛累积100人完成作业之后,开始抽奖。之后每2周抽奖并公示1次。4. 奖品:在原有结业证书、华为蓝牙音箱的奖励基础上,新增了华为10000mAh移动电源SuperCharge快充版(Max 22.5W)和AM115半入耳式耳机。5. 注意事项:(1)作业分数为0分的选手无抽奖资格。(2)需26个题目全部完成才有抽奖资格。每人限中奖1次。(3)答题截止时间前可以多次修改(最多5次),系统以最后一次答题成绩为准。6. 名单公布:大赛官方会在本帖及官方QQ群内进行公示,请大家现在入群,第一时间收到中奖名单提醒。7. 领奖方式:请获奖学员在名单公布后的【5个工作日内】扫描下方二维码,用报名大赛的华为云账号登录,完成信息核对和邮寄信息填写,未在限定时间内反馈视为放弃。8. 结业证书颁布规则:(1)作业累积分值在1600分以上(包含1600分)的选手,将获得电子结业证书1张。(2)证书将统一在12月31日后公布并颁发。最终解释权归华为所有。三、学习激励奖参与方式   1. 点击右侧蓝字:加入课堂,或者进入大赛官网平台,页面左侧【训练营入口】加入课堂。   2. 进入课堂后,点击【作业】进入答题页面,完成所有26个作业。      3. 进入答题页面,完成题目内容,点击“提交作业”即完成一题。26个作业均完成后,算最终完成作业。在答题截止时间前可以多次修改(最多5次),系统以最后一次答题成绩为准。    【友情链接】学霸奖名单公布https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=76258&page=1&extra=#pid340680心得分享幸运奖名单公布https://bbs.huaweicloud.com/forum/thread-76417-1-1.html四、抽奖视频公示处:【12月学习激励奖抽奖视频】
  • [技术干货] Java中JDBC的使用详解(四)
    五、使用数据库连接池  1、原因       1.传统连接方法缺点:用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。2.数据库连接池 2、开源连接池         1.DBCP 数据库连接池 工具类如下:JdbcUtils_DBCPimport java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;   import javax.sql.DataSource;   import org.apache.commons.dbcp.BasicDataSourceFactory;     public class JdbcUtils_DBCP { private static DataSource ds = null; static{ try{ InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"); Properties prop = new Properties(); prop.load(in); BasicDataSourceFactory factory = new BasicDataSourceFactory(); ds = factory.createDataSource(prop); System.out.println(ds); }catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException{ return ds.getConnection(); } public static void release(Connection conn,Statement st,ResultSet rs){ if(rs!=null){ try{ rs.close(); }catch (Exception e) { e.printStackTrace(); } rs = null;   } if(st!=null){ try{ st.close(); }catch (Exception e) { e.printStackTrace(); } } if(conn!=null){ try{ conn.close(); }catch (Exception e) { e.printStackTrace(); } } } }    2.C3P0 数据库连接池连接工具类:JdbcUtils_C3p0(自己在这里更改)import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;   import javax.sql.DataSource;   import org.apache.commons.dbcp.BasicDataSourceFactory;   import com.mchange.v2.c3p0.ComboPooledDataSource;     public class JdbcUtils_C3P0 { private static ComboPooledDataSource ds = null; static{ try{ ds = new ComboPooledDataSource(); ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/day16"); ds.setUser("root"); ds.setPassword("root"); ds.setInitialPoolSize(10);//最初连接数 ds.setMinPoolSize(5);//最小连接数 ds.setMaxPoolSize(20);//最大连接数 }catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException{ return ds.getConnection(); } public static void release(Connection conn,Statement st,ResultSet rs){ if(rs!=null){ try{ rs.close(); }catch (Exception e) { e.printStackTrace(); } rs = null;   } if(st!=null){ try{ st.close(); }catch (Exception e) { e.printStackTrace(); } } if(conn!=null){ try{ conn.close(); }catch (Exception e) { e.printStackTrace(); } } } }也可以将配置信息放在xml文件中(src下):c3p0-config.xml<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property> <property name="user">root</property> <property name="password">root</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </default-config> <named-config name="mysql"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property> <property name="user">root</property> <property name="password">root</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </named-config> <named-config name="oracle"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property> <property name="user">root</property> <property name="password">root</property> <property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property> </named-config> </c3p0-config>这样JdbcUtils_C3p0可以改为: /*             ds = new ComboPooledDataSource(); ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/day16"); ds.setUser("root"); ds.setPassword("root"); ds.setInitialPoolSize(10);//最初连接数 ds.setMinPoolSize(5);//最小连接数 ds.setMaxPoolSize(20);//最大连接数             */              ds = new ComboPooledDataSource(""mysql"");//如果默认()
  • [技术干货] Java中JDBC的使用详解(二)
    接着上面的说:4、获取结果         Jdbc程序中的ResultSet用于代表Sql语句的执行结果。        Resultset封装执行结果时,采用的类似于表格的方式,        ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,        游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,        进行调用方法获取该行的数据。1、获取行ResultSet提供了对结果集进行滚动的方法:next():移动到下一行Previous():移动到前一行absolute(int row):移动到指定行beforeFirst():移动resultSet的最前面。afterLast() :移动到resultSet的最后面。2、获取值ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:            获取任意类型的数据                        getObject(int index)                        getObject(string columnName)    获取指定类型的数据,例如                            getString(int index)                    getString(String columnName)    常用数据类型转换:            SQL类型Jdbc对应方法返回类型tinyintgetByte()getByte()getByte()getShort()Short()intgetintintbigintbigintLongchar,varchar,longvarchargetStringStringtext(clob) blobgetClob()Clob  bolbdategetDatajava.sql.DatetimegetTimejava.sql.TimetimestampgetTimestampjava.sql.TimestampResultSet rs = null; //4.向数据库发sql,并获取代表结果集的resultset String sql = "select id,name,password,email,birthday from users"; rs = st.executeQuery(sql); //5.取出结果集的数据 rs.afterLast(); rs.previous(); System.out.println("id=" + rs.getObject("id")); System.out.println("name=" + rs.getObject("name")); System.out.println("password=" + rs.getObject("password")); System.out.println("email=" + rs.getObject("email")); System.out.println("birthday=" + rs.getObject("birthday"));或者://循环取出(id) while(rs.next()) { String id=rs.getString(1);//1代表数据库中表的列数,id在第一列也可以("id")!!! System.out.println(id+" "); }5、释放资源     Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,    这些对象通常是ResultSet, Statement和Connection对象。注意:为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。//6.关闭链接,释放资源 if(rs!=null){ try{ rs.close(); }catch (Exception e) { e.printStackTrace(); } rs = null; } if(st!=null){ try{ st.close(); }catch (Exception e) { e.printStackTrace(); } } if(conn!=null){ try{ conn.close(); }catch (Exception e) { e.printStackTrace(); } }
  • [技术干货] Java中JDBC的使用详解(一)
    一、环境介绍mysql中创建一个库shen,并创建user表和插入表的数据。新建一个Java工程jdbc,并导入数据驱动。二、详细步骤 1、加载数据库驱动//1.加载驱动(开发推荐的方式) Class.forName("com.mysql.jdbc.Driver");注意:如果连接的是SQL server//1.加载驱动 Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");2、建立连接  1、数据库URL  URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:  jdbc:mysql:[]//localhost:3306/shen ?参数名:参数值  常用数据库URL地址的写法:       Oracle:jdbc:oracle:thin:@localhost:1521:shen       SqlServer:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=shen       MySql:jdbc:mysql://localhost:3306/shen注意:如果是localhost:3306,mysql可以简写为jdbc:mysql:///sid(尽量不这样)2、Connection  Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,创建方法为:Connection conn = DriverManager.getConnection(url,user,pass); 这个对象的常用方法:String url = "jdbc:mysql://localhost:3306/shen"; String username = "shen"; String password = "Anxin062039"; Connection conn = null; //2.获取与数据库的链接 conn = DriverManager.getConnection(url, username, password);3、执行SQL语句1、Statement        Jdbc程序中的Statement对象用于向数据库发送SQL语句,创建方法为:                                     Statement st = conn.createStatement();Statement对象常用方法:Statement st = null; //3.获取用于向数据库发送sql语句的statement st = conn.createStatement(); //4.向数据库发sql String sql = "select id,name,password,email,birthday from users"; st.executeQuery(sql);2、PreperedStatement         PreperedStatement是Statement的孩子,它的实例对象可以通过调用:                                 PreperedStatement st =  conn.preparedStatement()PreperedStatement st = null; String sql = "select * from users where name=? and password=?";   //3.获取用于向数据库发送sql语句的Preperedstatement st = conn.preparedStatement(sql);//在此次传入,进行预编译 st.setString(1, username); st.setString(2, password); //4.向数据库发sql st.executeQuery();//在这里不需要传入sql比较:相对于Statement对象而言PreperedStatement可以避免SQL注入的问题如:String sql="select * from admin where loginname='"+loginName+"' and loginpwd='"+loginPwd+"'";                  在应用中:                            -》请输入账号:                                 333                            -》请输入密码:                                  wer'or'1'='1    实际上发送:select * from admin where loginname='333' and loginpwd='wer'or'1'='1',登录成功! Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。                 
  • [技术干货] 【转载】一篇文章带你学习 MongoDB 中各种类型的索引(_id索引/复合索引/过期索引/全文索引/地理空间索引/复合地理空间
    一、_id 索引我们介绍过,我们往集合中添加文档时,默认情况下MongoDB都会帮助我们创建一个名为_id的字段,这个字段就是一个索引。默认情况下,一般的集合都会帮我们创建这个字段作为索引,但也有一些集合不会将_id默认作为索引,比如固定集合,这个我们后面会详细说到这个问题。二、复合索引如果我们的查询条件有多个的话,我们可以对这多个查询条件都建立索引,比如我们可以对文档中的x和y字段都建立索引,如下:db.sang_collect.ensureIndex({x:1,y:-1})1此时执行如下查询语句时就会用到这个复合索引:db.sang_collect.find({x:1,y:999})1小伙伴们也可以通过查看查询计划来确定确实使用到了上文创建好的索引。三、过期索引顾名思义,过期索引就是一种会过期的索引,在索引过期之后,索引对应的数据会被删除,创建方式如下:db.sang_collect.ensureIndex({time:1},{expireAfterSeconds:30})1expireAfterSeconds表示索引的过期时间,单位为秒。time表示索引的字段,time的数据类型必须是ISODate或者ISODate数组,否则的话,当索引过期之后,time的数据就不会被删除。四、全文索引全文索引虽然好用,可惜不支持中文,我们这里就先做一个简单的了解。比如,我的数据集如下:{    "_id" : ObjectId("59f5a3da1f9e8e181ffc3189"),    "x" : "Java C# Python PHP"}{    "_id" : ObjectId("59f5a3da1f9e8e181ffc318a"),    "x" : "Java C#"}{    "_id" : ObjectId("59f5a3da1f9e8e181ffc318b"),    "x" : "Java Python"}{    "_id" : ObjectId("59f5a3da1f9e8e181ffc318c"),    "x" : "PHP Python"}{    "_id" : ObjectId("59f5a4541f9e8e181ffc318d"),    "x" : "C C++"}1234567891011121314151617181920我们可以给x字段建立一个全文索引,创建方式如下:db.sang_collect.ensureIndex({x:"text"})1MongoDB会自动对x字段的数据进行分词,然后我们就可以通过如下语句进行查询:db.sang_collect.find({$text:{$search:"Java"}})1此时x中包含Java的文档都会被查询出来。如果想查询既包含Java又包含C#的文档,操作如下:db.sang_collect.find({$text:{$search:"\"Java C#\""}})1用一对双引号将查询条件括起来,如果想查询包含PHP或者Python的文档,操作如下:db.sang_collect.find({$text:{$search:"PHP Python"}})1如果想查询既有PHP,又有Python,但是又不包括Java的文档,如下:db.sang_collect.find({$text:{$search:"PHP Python -Java"}})1建立了全文索引之后,我们也可以查看查询结果的相似度,使用$meta,如下:db.sang_collect.find({$text:{$search:"PHP Python"}},{score:{$meta:"textScore"}})1此时查询结果中会多出一个score字段,该字段的值越大,表示相似度越高,我们可以根据score利用sort来对其进行排序,如下:db.sang_collect.find({$text:{$search:"PHP Python"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})1全文索引目前看起来功能还是很强大,可惜暂时不支持中文,不过网上对此也有很多解决方案,小伙伴们可以自行搜索查看。五、地理空间索引1. 2d 索引2d索引,可以用来存储和查找平面上的点。,2d索引一般我们可以用在游戏地图中向集合中插入一条记录点的数据:db.sang_collect.insert({x:[90,0]})1插入数据的格式为[经度,纬度],取值范围,经度[-180,180],纬度[-90,90]。数据插入成功之后,我们先通过如下命令创建索引:db.sang_collect.ensureIndex({x:"2d"})1然后通过$near我们可以查询某一个点附近的点,如下:db.sang_collect.find({x:{$near:[90,0]}})1默认情况下返回该点附近100个点,我们可以通过$maxDistance来设置返回的最远距离:db.sang_collect.find({x:{$near:[90,0],$maxDistance:99}})1我们也可以通过$geoWithin查询某个形状内的点,比如查询矩形中的点:db.sang_collect.find({x:{$geoWithin:{$box:[[0,0],[91,1]]}}})1两个坐标点用来确定矩形的位置。查询圆中的点:db.sang_collect.find({x:{$geoWithin:{$center:[[0,0],90]}}})1参数分别表示圆的圆心和半径。查询多边形中的点:db.sang_collect.find({x:{$geoWithin:{$polygon:[[0,0],[100,0],[100,1],[0,1]]}}})1这里可以填入任意多个点,表示多边形中的各个点。2. 2d sphere 索引2dsphere适用于球面类型的地图,它的数据类型是GeoJSON格式的,我们可以在http://geojson.org/地址上查看GeoJSON格式的样式,比如我们描述一个点,GeoJSON如下:{    "_id" : ObjectId("59f5e0571f9e8e181ffc3196"),    "name" : "shenzhen",    "location" : {        "type" : "Point",        "coordinates" : [            90.0,            0.0        ]    }}1234567891011描述线,GeoJSON格式如下:{    "_id" : ObjectId("59f5e0d01f9e8e181ffc3199"),    "name" : "shenzhen",    "location" : {        "type" : "LineString",        "coordinates" : [            [                90.0,                0.0            ],            [                90.0,                1.0            ],            [                90.0,                2.0            ]        ]    }}123456789101112131415161718192021描述多边形,GeoJSON格式如下:{    "_id" : ObjectId("59f5e3f91f9e8e181ffc31d0"),    "name" : "beijing",    "location" : {        "type" : "Polygon",        "coordinates" : [            [                [                    0.0,                    1.0                ],                [                    0.0,                    2.0                ],                [                    1.0,                    2.0                ],                [                    0.0,                    1.0                ]            ]        ]    }}123456789101112131415161718192021222324252627还有其他的类型,具体小伙伴们可以参考http://geojson.org/。有了数据之后,我们可以通过如下操作来创建地理空间索引了:db.sang_collect.ensureIndex({location:"2dsphere"})1比如我想查询和深圳这个区域有交集的文档,如下:var shenzhen = db.sang_collect.findOne({name:"shenzhen"})db.sang_collect.find({location:{$geoIntersects:{$geometry:shenzhen.location}}})12这里的查询结果是和深圳这个区域有交集的都会查到(比如经过深圳的高速公路、铁路等),我们也可以只查询深圳市内的区域(比如深圳市内所有的学校),如下:var shenzhen = db.sang_collect.findOne({name:"shenzhen"})db.sang_collect.find({location:{$within:{$geometry:shenzhen.location}}})12也可以查询腾讯附近的其他位置,如下:var QQ = db.sang_collect.findOne({name:"QQ"})db.sang_collect.find({location:{$near:{$geometry:QQ.location}}})12六、复合地理空间索引位置往往只是我们查询的一个条件,比如我要查询深圳市内所有的学校,那我得再增加一个查询条件,如下:var shenzhen = db.sang_collect.findOne({name:"shenzhen"})db.sang_collect.find({location:{$within:{$geometry:shenzhen.location}},name:"QQ"})12其他的查询条件跟在后面就行了。
  • [技术干货] 数据库设计的三大范式(通俗易懂)
            关系数据库中的关系必须满足一定的要求。满足不同程度要求的为不同范式。数据库的设计范式是数据库设计所需要满足的规范。只有理解数据库的设计范式,才能设计出高效率、优雅的数据库,否则可能会设计出错误的数据库.                目前,主要有六种范式:第一范式、第二范式、第三范式、BC范式、第四范式和第五范式。满足最低要求的叫第一范式,简称1NF。在第一范式基础上进一步满足一些要求的为第二范式,简称2NF。其余依此类推。                范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦,但是操作困难,因为需要联系多个表才能得到所需要数据,而且范式越高性能就会越差。要权衡是否使用更高范式是比较麻烦的,一般在项目中,用得最多的也就是第三范式,我认为使用到第三范式也就足够了,性能好而且方便管理数据。                函数依赖,如果一个表中某一个字段Y的值是由另外一个字段或一组字段X的值来确定的,就称为Y函数依赖于X。                第一范式(1NF)             定义:如果关系模式R的每个关系r的属性都是不可分的数据项,那么就称R是第一范式的模式。             简单的说,每一个属性都是原子项,不可分割。             1NF是关系模式应具备的最起码的条件,如果数据库设计不能满足第一范式,就不称为关系型数据库。关系数据库设计研究的关系规范化是在1NF之上               进行的。                例如(学生信息表):            学生编号  姓名  性别  联系方式            20080901  张三  男   email:zs@126.com,phone:88886666            20080902  李四  女   email:ls@126.com,phone:66668888                以上的表就不符合,第一范式:联系方式字段可以再分,所以变更为正确的是:               学生编号  姓名  性别  电子邮件   电话            20080901  张三  男   zs@126.com 88886666            20080902  李四  女   ls@126.com  66668888      第二范式(2NF)        定义:如果关系模式R是1NF,且每个非主属性完全函数依赖于候选键,那么就称R是第二范式。简单的说,第二范式要满足以下的条件:首先要满足第一范式,其次每个非主属性要完全函数依赖与候选键,或者是主键。也就是说,每个非主属性是由整个主键函数决定的,而不能由主键的一部分来决定。                例如(学生选课表):            学生    课程   教师    教师职称  教材          教室    上课时间            李四    Spring  张老师   java讲师   《Spring深入浅出》    301   08:00            张三    Struts  杨老师   java讲师  《Struts in Action》     302   13:30                这里通过(学生,课程)可以确定教师、教师职称,教材,教室和上课时间,所以可以把(学生,课程)作为主键。但是,教材并不完全依赖于(学生,课程),只拿出课程就可以确定教材,因为一个课程,一定指定了某个教材。这就叫不完全依赖,或者部分依赖。出现这种情况,就不满足第二范式。                修改后,选课表:            学生    课程    教师    教师职称  教室  上课时间             李四    Spring  张老师   java讲师  301  08:00             张三    Struts   杨老师   java讲师  302  13:30                课程表:        课程           教材                Spring      《Spring深入浅出》         Struts       《Struts in Action》                所以,第二范式可以说是消除部分依赖。第二范式可以减少插入异常,删除异常和修改异常。                第三范式(3NF)            定义:如果关系模式R是2NF,且关系模式R(U,F)中的所有非主属性对任何候选关键字都不存在传递依赖,则称关系R是属于第三范式。            简单的说,第三范式要满足以下的条件:首先要满足第二范式,其次非主属性之间不存在函数依赖。由于满足了第二范式,表示每个非主属性都函数依            赖于主键。如果非主属性之间存在了函数依赖,就会存在传递依赖,这样就不满足第三范式。                上例中修改后的选课表中,一个教师能确定一个教师职称。这样,教师依赖于(学生,课程),而教师职称又依赖于教师,这叫传递依赖。第三范式就是要消除传递依赖。                修改后,选课表:           学生    课程   教师    教室  上课时间            李四    Spring  张老师   301 08:00            张三    Struts  杨老师   302 13:30                教师表:             教师    教师职称             张老师   java讲师            杨老师   java讲师                这样,新教师的职称在没被选课的时候也有地方存了,没人选这个教师的课的时候教师的职称也不至于被删除,修改教师职称时只修改教师表就可以了。        简单的说,             第一范式就是原子性,字段不可再分割;             第二范式就是完全依赖,没有部分依赖;             第三范式就是没有传递依赖。
  • [全栈开发者] 【JAVA开发全栈成长计划】基础班•最终考核打卡帖
    华为云ID:hw67578428  姓名:刘晓冬
  • [问题求助] 输入echo $JAVA_HOME命令显示空白的一行
    为啥echo $JAVA_HOME命令显示空白的一行?Tuning Kit的系统性能优化工具第一次安装在鲲鹏服务器上,鲲鹏服务器安装的centos7.6系统,鲲鹏服务器上暂时还未安装其它软件系统。
  • [技术干货] 【转载】年近而立,Java何去何从?
    摘要:各种新需求新应用层出不尽,各路新生代编程语言异军突起等等,Java未来会不会继续受欢迎?曾经备受关注的Java是否能紧跟时代步伐?新基建时代破茧重生引领云端未来潮流?1995年第一个Java版本诞生到现在已经25年,它成功的建立了一个开放、成熟、稳定的开源生态。但现在也有各种争议,如版权限制,授权收费,社区投入减少,各种新需求新应用层出不尽,各路新生代编程语言异军突起等等,Java未来会不会继续受欢迎?曾经备受关注的Java是否能紧跟时代步伐?新基建时代破茧重生引领云端未来潮流?日前华为云DevRun直播间特邀请华为莫斯科研究所系统编程实验室主任Yegor Bugayenko,开源中国创始人兼CTO&码云开发平台负责人红薯,禧天龙科技发展有限公司CTO郭曦三位嘉宾,并由华为云DevCloud首席技术布道师徐毅引导,嘉宾们围绕中俄社区现状和当前Java热点话题进行了讨论。中俄Java社区知多少通过红薯和 Yegor Bugayenko两位大咖的介绍,我们对中俄Java社区有了初步的了解。开源中国成立到现在已经有12年的发展历史,对开发者的数量有很大的关注,当前国内业界比较认可的一个数字中国开发者人群规模大约 1000 万,从正常一个公司的技术人员配比来看,直接参与编程的人员比例在 80%左右 。同时根据码云目前超过1000万的仓库推算,国内有大约 200 万的 Java 开发者。在俄罗斯其实从事编程工作的人员不是很多,根据Yegor Bugayenko的初步估计应该在10万左右,由于编程语言的多样性,使用Java的开发者数量不好评估,但也在大多数。两国开发者都有“自嘲”文化,在中国就比较突出比如技术男,理工男,程序猿,攻城狮,搬砖,大牛等等,比较有争议性,但是随着互联网、高科技、新兴产业的发展,程序员也越来越受欢迎。俄罗斯很多程序员会认为自己是哲学家甚至艺术家,编程和代码帮助人们更深刻的理解这个世界的哲学,数学,宗教,艺术和文化,并以前所未有的效率将思想转化为生产力,随着科技发展,教育普及,现在编程工作越来越像一种普通的工作,但是可以肯定的是从事编程是一个很有“钱”途的工作。从Java数次历史变更看影响1991年,Sun公司的James Gosling等人开始开发名称为 Oak (橡树)的语言。希望用于控制嵌入在有线电视交换盒、PDA等的微处理器。1994年,将Oak语言更名为Java1998年,JDK1.2时,更名为Java 2 Platform,分为标准版J2SE,企业版J2EE,微型版J2ME,这是 Java 一个重大的版本,修复了早先的一些重要 Bug2004年,J2SE 5.0 (1.5.0) Tiger老虎2006年,J2SE 6.0 (1.6.0) Mustang野马2009年,Oracle 74亿美元收购 Sun2014年,Java 8 发布,Lambda 表达式支持,而且兼容老版本,堪称奇迹再以后 Java 调整版本发布策略2018年, Oracle 发布Java 10 并决定每 6 个月发布一个新版本2019 年1月, Oracle 宣布 Oracle JDK 不再提供免费支持,一些大互联网公司开始推出自己的 JDK,并宣布提供免费技术支持红薯老师经历Java的多次变化并对其有亲身体会,他认为从整个变更过程看,Java 更多用来开发具体的应用,每次变更对国内影响有限,Java仍然是很受欢迎的语言。未来Java会不会被取代?哪些语言最有可能取代JavaJava私有化之后, Oracle对社区投入的逐渐减少,出现版权问题、收费问题、企业对Java的依赖等一些问题,这引来了开源社区更多的担忧和猜忌,未来Java会不会被取代?哪些语言最有可能取代Java?收费、版权等问题是未来各个技术发展必然面对的问题,比较具备争议性。Java会不会被替代?其实并不是语言本身,而是Java搭建的生态系统,其中有各种各样的组件元素,如Java基础、WEB开发架构、负载均衡、分布式服务框架等,以及对应的应用虚拟机、安卓系统等等。Java从诞生起就有无数的缺陷,但这些并没有阻止Java的成功。开放就是Java 成功的核心,拥有跨平台、面向对象、泛型编程的特性保证其可运行性、可扩展性和可连接性,并保障了其在Web开发、大数据开发、Android开发和各种后端服务开发等领域都有大量的应用,同时,Java凭借其稳定的性能和较强的扩展性得到了广泛的应用,并且互联网的行业备受认可,未来仍然存在很大的发展空间。该次活动中我们对“未来最可能取代Java的语言”进行了一轮投票活动,根据参与者的反馈来看,大家认为最有可能取代Java语言的Top3分别是Python(34.99%),JavaScript(23.24%),Go(13.05%),其实每种语言都有自己擅长的领域和方向。Python主要的领域是大数据和人工智能,在Web开发、大数据开发、人工智能开发、后端服务开发和嵌入式开发等应用比较广泛。主要是因为语言语法简单,调整方便,但是Python在运行性能上与Java还有一定的差距。JavaScript主要是从事前端任务开发的场景,解决服务器端语言遗留的速度问题,但是随着Node.js的兴起给JavaScript从前端走向后端的机会,未来JavaScript会得到进一步的发展。Go语言主打性能,特别是在当下的大数据环境下,对性能要求越来越高,Go语言应该能够发挥出更大作用。企业基于Java开发商业软件有没有比较好的最佳业务实践或者方法嘉宾郭曦分享了如下的一个真实案例。最早的三层架构是没有集成层的,IBM/BEA/SAP甚至开源社区很多优秀的产品进入了继承领域,在这一层级以Java为主要开发语言开发的企业服务总线已经占据着企业继承市场90%以上的份额。应用公有云微服务架构+SAP企业服务总线无缝整合面向互联网的SaaS/PaaS平台,比如多家国内知名电商,是通过公有云+私有云对接的形式,利用云端应用服务器构建自己面向互联网应用后台。通过云端代码托管和自动化构建设施建立自己的代码仓库和配合敏捷开发理论形成企业的应用开发体系,利用云端项目/任务管理软件进行任务分配/质量控制/成本预算核算,利用云端运维管理应用构建企业自己基于ITIL管理体系的运维框架。最佳实践带来了不错的效果标准研发流程和经验,研发数据集中存储,防止流失配置管理改为Git,效率提升30%减少构建依赖错误,构建效率提高70%发布部署的出错率降低90%未来变成语言会是百花齐放的方式往前发展。Java语言生态体系比较健全,开发者数量上占据优势,其自身开放、跨平台、面向对象、泛编程性等特性其他语言也很难取代,未来在其最擅长细分领域如:Web开发、移动互联网开发和大数据(云计算)开发等领域,未来还是会继续保持其优势。Java 已经25年,历经磨难,却历久弥新,其构建的应用生态也越来越丰富,未来的发展应用会越来越多。文章仅介绍了大咖们在本场直播中的部分精彩观点,欲知详情,请至该活动的华为云社区页面及预告视频和直播回放。请点击链接查看直播回放:https://bbs.huaweicloud.com/forum/thread-65920-1-1.htm
总条数:2301 到第 页
上滑加载中