
能力说明:
掌握封装、继承和多态设计Java类的方法,能够设计较复杂的Java类结构;能够使用泛型与集合的概念与方法,创建泛型类,使用ArrayList,TreeSet,TreeMap等对象掌握Java I/O原理从控制台读取和写入数据,能够使用BufferedReader,BufferedWriter文件创建输出、输入对象。
暂时未有相关云产品技术能力~
阿里云技能认证
详细说明1.自我介绍 简历开篇就是介绍自己,忌长篇大论,那么点时间,相信你自己作为面试官,也不想去看阅读理解 忌讳 不要写杂事 获得了什么证书之类,像计算机几级或者mysql认证证书什么的 4、6级英语及个别例如acm奖项等,可写 之前见有人写去养老院献爱心之类的,确实,人不错,但是和你的工作联系不是那么大 建议 条理清晰,最好有序号 学历高要写前边,例如硕士,低于本科的话就先不要写,放在整体简历的最后 示例 简要,该体现的基本全都体现了,也可以放上去自己的籍贯,碰上老乡也是一种幸运 2. 技能描述 为何把这一项放在第二处? 因为你的技能,是占比最高的,例如公司想招一个会Spring Cloud和 Docker的,你全都没写,或者写在了后面,这就是重心没放在重点上,因为你做的项目很大概率和新公司的并不相同,甚至跨行业,技术才是通用的,所以建议放在第二处。 建议 做过多久的后端或者前端开发,或是全栈,这个也是面试官最想了解你的 技术栈的先后顺序,例如你想做后端,那就要先写后端的技术,前端的技术你会,那就是锦上添花 不要写精通,除非你自己觉得真的精通了,山外有山 像一些技术,例如Vue、React你只是自己去看博客或者视频,写了一个demo,不要去写熟练,写了解,不然碰到个练家子,基本就会问你生命周期与组件等 写一个框架或者一门技术时,一定一定去看看面试题,不然问到一些稍微深入的地方,你会懵逼 想到哪里先写到哪里,后面的想起来再去写一篇补充 一份Java技术栈示例 上面的技术没什么新鲜的,但是一条一条罗列出来,貌似比写证书什么的有用,当然,如果你熟悉热门的技术,例如 Python 爬虫、K8S、Spark、Oauth等等都是可以自行组装的,再次强调,不要写精通,技术面试官程序猿,或多或少都是心里有点犟的,你写个精通,今天不给你上一课,就不爽 3.工作经历 这个如果有大厂经历,可以替换掉第二处,优先级更上一层 其实也是写写时间点,公司职位,尽量用数字或者比率来写工作内容 反例 上海xxxxx有限公司 送外卖的 20xx.10-20xx.10 送送外卖,一天能送多少单,好评率达99% 上海xxxxx有限公司 Java研发 20xx.3-20xx.3 整理需求文档,设计数据库,搭框架学习,独立负责后端模块 前一个是不要写与你要找工作无关的工作经历,后者是太平常了,大家都这么写了 正常 北京****公司 JAVA 开发工程师 20xx.09-20xx.03 通过自学设计模式与数据库调优参与公司旧项目重构,完成后项目整体性能提升20% 在职期间,新项目的单元测试覆盖率达到80%,文档需求整理明确。 北京****公司 前端开发工程师 20xx.09-20xx.03 通过使用新技术Vue对公司旧项目重构,完成后项目页面流畅度提升20% 在职期间,对新项目的组件模块化,划分明确,文档需求整理明确。 这里你所写的,就要落实了,一般就会问你用到了哪些设计模式,还有数据库调优的解决方案,细化到如设计模式解决了哪些问题,数据库索引等 前端就会涉及到模块的封装与重用,前端页面的缓存与热重载问题 4.项目经历 列出两个常见的且容易直接pass的项目 4.1 商城 不要写仿京东商城、易买网、 xx商城、信用贷,关于商城的还是不要写了,为什么? 除非你有真实的去亲身做过,比如举例一个购物车 写了购物车的后果就是..... 还写么,没做过的就要考虑考虑了,是非能够自圆其说,所以还是自己做过什么就去写什么,真想包装,也请拿一些简单的业务去写,当然了,自己也要去做,亲身体验一个业务,不是看几个文章就能理解的 4.2 进销存 不是说不能写,一定要真的做过才要写,这个业务更为复杂,然后你就在项目模块三言两语给带过了看到这里,估计会有人讲了,这也不让写那也不让写,到底写什么,其实,这个不是我说了算,是你说了算的,总之,如果就是你自己单独下班手撸一个项目,只要你对业务熟悉的很,一样,能做到这个程度的人,一样不一般 简历模板推荐 其实这个写的可以参考格式,格式清晰的话面试官才有看下去的欲望,相信谁也不想去看一个花里胡哨的简历,排版要简洁,简洁而不失优雅 tips:最会问的就是你在项目遇到了什么难点,怎么解决的 ? 可笑的是很多都答不上,或者说没遇到过难点,这就有点厉害了,要么是真的厉害,要么就是没工作经验或者整天用最笨的代码加最狠的班 举个栗子: 项目中使用了try catch未捕捉到操作出错,导致数据库未回滚,从而关联到后续的操作数据不对,后面就直接抛出错误,异常使用全局AOP进行处理,这样还可以统一管理日志,以及监控方法的执行时间 自我评价 不要上来就写活泼开朗,自信阳光,这是个找技术的工作,不是让你去当公关月入三万 ,就平常写,爱好钻研技术不挺好的吗 有的写了爱好看技术书籍,问了也不知道看的哪一本,名字叫什么 Github上最好有点提交记录什么的,或者有点东西在往简历写吧 喜欢锻炼健身,挺好的,不过与工作无关的还是不推荐写 抗压能力强,和同事相处好,接受加班服从上级指挥,你不喜欢加班就不要写了,就写和同事相处好,服从上级指挥就行了 教育经历 没什么好写的,一些技术方面的证书也不要往上面写,目前行业除了事业单位基本不认同这个,技术+业务能力才是重要的 总结:全文字也比较多一点,如果你真的想写好简历,花一点耐心去看,希望能给你提供一点帮助,没有帮助,也不要喷我,我不想和你对线,对以上内容有不同想法的关注公众号《Java Pro》回复找弟弟即可与我对线 模板获取:关注公众号《Java Pro》回复简历模板即可获取上面图示中的模板
最常用的 Java 8 中的 Lambda 函数(项目中实用笔记) 简介 Java 8 中的新特性,虽然现在都出到了Java14版本,不过在日常的开发过程中,8的版本是足够使用了,再说现在的8以上的版本也都面向商业收费了,很多新手,我所接触到的,像我那时候一样,追求船新版本,一上来就去学java14的东西,当成一个爱好还行,重心还是要放在实用上 过滤 需求:我需要过滤高考分数大于500的人 首先,新建一个内部类 static class Student{ private String name; private Integer score; public String getName() { return name; } public void setName(String name) { this.name = name!=null ? name.trim() : null; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } public Student(String name, Integer score) { this.name = name; this.score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", score=" + score + "}\n"; } } 使用IntStream遍历快速初始化一批值 public static void main(String[] args) { List<Student> studentList = IntStream.rangeClosed(0,20) .mapToObj(i -> new Student("Java Pro"+i,490+i)) .collect(Collectors.toList()); } 过滤出分数大于500的并输出 List<Student> studentGiao = studentList.stream() .filter(student -> student.score > 500) .collect(Collectors.toList()); System.out.println(studentGiao.toString()); 输出: [Student{name='Java Pro11', score=501} , Student{name='Java Pro12', score=502} , Student{name='Java Pro13', score=503} , Student{name='Java Pro14', score=504} , Student{name='Java Pro15', score=505} , Student{name='Java Pro16', score=506} , Student{name='Java Pro17', score=507} , Student{name='Java Pro18', score=508} , Student{name='Java Pro19', score=509} , Student{name='Java Pro20', score=510} ] 日常求和 需要考虑到为空和为0的情况 package com.github.gleans; import java.util.Arrays; import java.util.List; import java.util.Objects; public class LambdaLearning { public static void main(String[] args) { List<Double> nums = Arrays.asList(1.01, 2.11, 3.23, 4.222, null, 5.6); double resNum = nums.stream() .map(num -> Objects.isNull(num) ? 0 : num) .mapToDouble(num -> num) .sum(); System.out.println(resNum); } } map是重新指向一个对象,把->右侧的对象赋予,此处判断若num为null则赋予0值 注意,这里不可给null使用filter过滤掉,否则全为null的情况,会报空指针异常 扩展计算 public static void testTwo(){ List<Double> nums = Arrays.asList(1.01, 2.11, 3.23, 4.222, null, 5.6); DoubleSummaryStatistics number = nums.stream() .map(num -> Objects.isNull(num) ? 0 : num) .mapToDouble(num -> num) .summaryStatistics(); System.out.println("最大值:"+number.getMax()); System.out.println("最小值:"+number.getMin()); System.out.println("平均值:"+number.getAverage()); } 输出 最大值:5.6 最小值:0.0 平均值:2.6953333333333336 reduce简单使用 public static void main(String[] args) { testOne(); } public static void testOne(){ List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); // 这里的 10 相当于初始值 int sum = numbers .stream() .reduce(10, Integer::sum); System.out.println(sum); } Collectors.groupingBy 根据年龄分组 package com.github.gleans; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class SumWage { public static void main(String[] args) { List<UserDemo> userDemoList = new ArrayList<UserDemo>() {{ add(new UserDemo(20, "jason", BigDecimal.valueOf(1000000))); add(new UserDemo(22, "yasuo", BigDecimal.valueOf(2000000))); add(new UserDemo(22, "ekko", BigDecimal.valueOf(100))); }}; Map<Integer, List<UserDemo>> UserDemoMapByAge = userDemoList.stream() .collect(Collectors.groupingBy(UserDemo::getAge)); System.out.println(UserDemoMapByAge.toString()); } static class UserDemo { private int age; private String username; private BigDecimal wage; public UserDemo(int age, String username, BigDecimal wage) { this.age = age; this.username = username; this.wage = wage; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public BigDecimal getWage() { return wage; } public void setWage(BigDecimal wage) { this.wage = wage; } @Override public String toString() { return "UserDemo{" + "age=" + age + ", username='" + username + '\'' + ", wage=" + wage + '}'; } } } 输出 {20=[UserDemo{age=20, username='jason', wage=1000000}], 22=[UserDemo{age=22, username='yasuo', wage=2000000}, UserDemo{age=22, username='ekko', wage=100}]} json化观看观看更为直观 { 20:[ { "age":20, "username":"jason", "wage":1000000 } ], 22:[ { "age":22, "username":"yasuo", "wage":2000000 }, { "age":22, "username":"ekko", "wage":100 } ] } 进阶计算 Collectors.summarizingDouble Map<Integer, DoubleSummaryStatistics> userAvgWageByAge = userDemoList.stream() .collect(Collectors.groupingBy(UserDemo::getAge, Collectors.summarizingDouble(s -> s.getWage().doubleValue()))); userAvgWageByAge.forEach((k, v) -> System.out.println(String.format("年龄:%d,平均工资:%f", k, v.getAverage()))); 数组快速转为List Stream.of(1, 2, 3, 4).collect(Collectors.toList()) 结论 后续会学习更多关于Lambda的操作,日积月累...一定会成为一个秃头的程序猿
都2020年了,你还不会写简洁的Java代码! 使用Google Guava依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency> 创建一个list集合并赋值 最原始的办法: List<String> stringList = new ArrayList<>(); stringList.add("jack"); stringList.add("pony"); stringList.add("ekko"); 简单改造: List<String> stringList2 = new ArrayList<String>(4) {{ add("jack"); add("pony"); add("ekko"); }}; 终极改造: List<String> stringList3 = ImmutableList.of("jack", "pony", "ekko"); 去除list中的空值 一般做法: List<String> nameList = new ArrayList<>(); List<String> noNullList = new ArrayList<>(); nameList.add("jack"); nameList.add("pony"); nameList.add("ekko"); nameList.add(null); for (String o : stringList) { if (o != null) { noNullList.add(o); } } 使用lamda简化后的写法: List<String> noNullListFun = nameList .stream() .filter(Objects::nonNull) .collect(Collectors.toList()); list中的值求和 原始做法: List<BigDecimal> numList = new ArrayList<BigDecimal>(10) {{ add(BigDecimal.valueOf(111L)); add(BigDecimal.valueOf(8888.22)); add(BigDecimal.valueOf(333.22)); add(BigDecimal.valueOf(857857.22)); add(BigDecimal.valueOf(5331.22)); }}; BigDecimal total = BigDecimal.ZERO; for (BigDecimal num : numList) { total = total.add(num); } System.out.println(total); 简化一下: List<BigDecimal> numListSimple = ImmutableList.of(BigDecimal.valueOf(111L) , BigDecimal.valueOf(8888.22), BigDecimal.valueOf(333.22) , BigDecimal.valueOf(857857.22), BigDecimal.valueOf(5331.22)); // 求和 BigDecimal totalNum = BigDecimal.valueOf(numListSimple.stream().mapToDouble(BigDecimal::doubleValue).sum()); 判断值是否为空 原始写法: public static String getUserName() { return null; } // 模拟调用服务 String username = getUserName(); String res; if (username != null) { res = username; } else { res = "游客"; } 简化: String userName = Optional.ofNullable(username).orElse("游客"); System.out.println(userName); 从多个集合中取匹配的值 原始方法: package com.github.springtools.test; import com.google.common.collect.ImmutableList; import java.util.HashSet; import java.util.List; import java.util.Set; public class TestFlatMap { public static void main(String[] args) { /* * 匹配到姓马的并去重然后放入一个新的集合中 */ List<String> nameListA = ImmutableList.of("素云云", "马云云", "腾花花", "阿娇娇", "马飞飞", "廖妹妹"); List<String> nameListB = ImmutableList.of("素云涛", "唐三三", "小五五", "马中山", "马僻静", "马肥羊"); List<String> nameListC = ImmutableList.of("张三", "李四", "王二", "麻子", "上官玩儿", "马可菠萝"); Set<String> nameSet = new HashSet<>(); nameListA.forEach(n -> { if (n.startsWith("马")) { nameSet.add(n); } }); nameListB.forEach(n -> { if (n.startsWith("马")) { nameSet.add(n); } }); nameListC.forEach(n -> { if (n.startsWith("马")) { nameSet.add(n); } }); System.out.println(nameSet.toString()); } } 改造后的代码: import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; public class TestFlatMap2 { public static void main(String[] args) { /* * 匹配到姓马的并去重然后放入一个新的集合中 */ List<String> nameListA = ImmutableList.of("素云云", "马云云", "腾花花", "阿娇娇", "马飞飞", "廖妹妹"); List<String> nameListB = ImmutableList.of("素云涛", "唐三三", "小五五", "马中山", "马僻静", "马肥羊"); List<String> nameListC = ImmutableList.of("张三", "李四", "王二", "麻子", "上官玩儿", "马可菠萝"); Set<String> nameSet = Stream.of(nameListA, nameListB, nameListC) .flatMap(list -> list.stream().filter(name -> name.startsWith("马"))) .collect(Collectors.toSet()); System.out.println(nameSet.toString()); } } 总结 Java之道,写的代码第一点是要别人能看的明白,不然你离职了留下一堆像shi一样的代码,接盘的人一定会问候你的亲人,何必呢二是要利用一切可以利用的工具类,不过用的时候看看别人的源码,写的时候考虑的周全与否,这样基本你的代码显性来看会少很多总之,功能一点点实现,大道至简,用最简单的代码实现最强的逻辑~
一文整懂 Java 中静态代码块 / 初始块 / 构造方法的执行顺序 “ 相信,刷过面试题应该都碰到过很多题,关于类继承后 Java 中静态代码块 / 初始块 / 构造方法的执行顺序问题,每每记一下又忘了,那么,今天来用不多的时间复习一下” 01.静态代码块 / 初始块 / 构造方法的执行顺序 package erdan.demo; public class Demo { static { System.out.println("静态代码块 111"); } static { System.out.println("静态代码块 222"); } { System.out.println("初始块 111"); } { System.out.println("初始块 222"); } public Demo() { System.out.println("无参构造方法"); } public Demo(int i) { System.out.println("有参构造方法" + i); } public static void main(String[] args) { new Demo(); } } 输出: 静态代码块 111 静态代码块 222 初始块 111 初始块 222 无参构造方法 上图: 笔记:初始块(非静态代码块)总是和构造方法是一家子,会一块出现 02.测试继承之后的执行顺序 package erdan.demo; public class ChildrenDemo extends Demo{ static { System.out.println("ChildrenDemo:静态代码块 111"); } static { System.out.println("ChildrenDemo:静态代码块 222"); } { System.out.println("ChildrenDemo 初始块 111"); } { System.out.println("ChildrenDemo 初始块 222"); } public ChildrenDemo() { System.out.println("无参构造方法 ChildrenDemo"); } public ChildrenDemo(int i) { System.out.println("有参构造方法 ChildrenDemo:" + i); } public static void main(String[] args) { new ChildrenDemo(); System.out.println("---------------------------------"); new ChildrenDemo(1); } } 输出: 静态代码块 111 静态代码块 222 ChildrenDemo:静态代码块 111 ChildrenDemo:静态代码块 222 初始块 111 初始块 222 无参构造方法 ChildrenDemo 初始块 111 ChildrenDemo 初始块 222 无参构造方法 ChildrenDemo --------------------------------- 初始块 111 初始块 222 无参构造方法 ChildrenDemo 初始块 111 ChildrenDemo 初始块 222 有参构造方法 ChildrenDemo:1 可以看到下面除了调用有参无参的差别外,虚线下比上面少了静态代码块 ps: 类比子类先执行 态代码块只会输出一次,初始块与构造方法是一家子,输出在一块,初始块会在构造前初始化 03.总结 父类比子类先行执行 静态代码块,在类第一次加载的时候,会初始化一次,适合项目中初始化全局参数,常量等 初始块与构造方法是一家子,但是初始块会在构造函数前执行,初始块适合重载构造函数存在相同代码,可以抽出来使用
MongoDB快速入门指南与docker-compose快体验 MongoDB相对于RDBMS的优势 模式少 -MongoDB是一个文档数据库,其中一个集合包含不同的文档。一个文档之间的字段数,内容和文档大小可能会有所不同。 单个对象的结构清晰。 没有复杂的联接。 深入的查询能力。MongoDB支持使用与SQL几乎一样强大的基于文档的查询语言对文档进行动态查询。 sql Tuning(优化) 易于扩展 不需要将应用程序对象转换/映射到数据库对象。 使用内部存储器存储(窗口式)工作集,从而可以更快地访问数据 RDBMS:关系数据库管理系统 为什么要使用MongoDB 面向文档的存储,BSON格式存储,即Binary JSON 单键索引、复合索引、多键索引、地理空间索引、全文本索引和哈希索引 MongoDB实现高可用 主从复制 自动分片 auto sharding 丰富的查询 快速原地更新(fast in-place updates):大部分更新操作无需申请新空间 MongoDB的专业支持map/reduce支持 Gridfs:各种size大小的集群文件支持 在哪里使用MongoDB 大数据 内容管理和交付 移动和社交基础设施 用户数据管理 数据中心 docker-compose 快速启动 MongoDB docker-compose.yml version: '3' services: mongodb: image: mongo:4.2.6 # 镜像:版本 container_name: mongo_db environment: - MONGO_INITDB_DATABASE=默认的数据库 - MONGO_INITDB_ROOT_USERNAME=你的root管理员名称 - MONGO_INITDB_ROOT_PASSWORD=你的root管理员名称密码 volumes: - ./mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro - ./mongo/mongo-volume:/data/db ports: - "27017-27019:27017-27019" restart: always init-mongo.js // db.getSiblingDB() 相当于 use admin; db.getSiblingDB('admin') .createUser({ user: 'user', pwd: 'user', roles: ['readWrite'] }); 然后执行命令 docker-compose up -d Navicat Premium连接 填入上述 docker-compose.yml 对应的参数测试连接,测试成功如果你的不显示,去 navicat ==》 菜单 ==》 显示 ==》钩上显示隐藏的项目 重启navicat就可以了 打开一个集合右下角可以查看 网格视图 树视图 JSON视图 增删改查 1.创建操作 db.collection.insertOne() db.collection.insertMany() // 插入集合名称为products的集合并插入数据 (不存在集合会新建) db.products.insertOne({ item: "card", qty: 15 }); // 批量插入数据 db.products.insertMany([{ item: "card1", qty: 16 }, { item: "card2", qty: 17 }, { item: "envelope", qty: 20 }, { item: "stamps", qty: 30 }]); 2.查询操作 db.collection.find() db.products.find({ qty: 15 }).limit(1) 3.更新操作 db.collection.updateOne() db.collection.updateOne(filter,update,options) 查找与过滤器匹配的第一个文档,并应用指定的更新修改。 db.products.find({ item: "stamps" }).limit(1); // 找到item为stamps的并修改其qty为60 db.products.updateOne( { "item": "stamps" }, { $set: { "qty": 60 } } ); db.products.find({ item: "stamps" }).limit(1); db.collection.updateMany() // 把qty大于15的统统修改为15 db.products.updateMany( { qty: { $gt: 15 } }, { $set: { "qty": 15 } } ); db.collection.replaceOne() 使用替换文档替换集合中与过滤器匹配的第一个匹配文档。 // 把集合products中item为stamps 整个替换掉 db.products.replaceOne( { "item" : "stamps" }, { "item" : "stampss", "Borough" : "Manhattan" } ); 4.删除操作 db.collection.deleteOne() db.collection.deleteMany() // 删除item为stampss的 db.products.deleteOne( { "item" : "stampss" } ); // 批量删除qty小于15的 db.products.deleteMany( { "qty" : {$lt: 15} } ); 持续更新连接
2020年07月