2020-ARTS-打卡第三天

Algorithm 题目描述 反转一个单链表。 Example 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 题目解答 迭代解法 class Solution3 { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode current = head; while (current != null) { ListNode tempNode = current.next; current.next = prev; prev = current; current = tempNode; } return prev; } } 第一次搞链表的题,还真是给难住了。此题的核心就是当前节点的指针要指向前一个节点,处理过程中还要考虑节点的丢失问题,所以要有一个变量保存当前节点的前一个节点,还要有一个变量来保存当前节点的下一个节点,方便后续的指针前移。此解法的时间复杂度为O(n),因其不需要额外的空间,所以空间复杂度为O(1)。 递归解法 class Solution3 { public ListNode reverseList2(ListNode node) { if (node == null || node.next == null) { return node; } ListNode current = reverseList2(node.next); node.next.next = node; node.next = null; return current; } } 此解的核心在于当有一部分是反转时,后续的反转问题,对于node.next.next = node这句,使用A->B两个节点进行示例,A.next为B,A.next.next为B.next,A.next.next = A为B.next = A,这样就实现了A与B两个节点的反转。这个递归看着还是有点懵,多看看就好了。 ...

2020-01-24 · 1 min · 178 words · tomyli

2020-ARTS-打卡第二天

Algorithm 题目描述 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 Example 输入123->true 输入-123->false 输入12->true 题目解答 class Solution2 { public boolean isPalindrome(int x) { if(x < 0) { return false; } if(x % 10 == 0 && x != 0) { return false; } int reverseNumber = 0; while (x > reverseNumber) { reverseNumber = reverseNumber * 10 + x % 10; x /= 10; } return reverseNumber == x || x == reverseNumber / 10; } } 最简单暴力的方法是把int转换成String进行处理,String反转一半再与后续的进行比较,对于溢出的数字一定不是回文字。此方法则可以更快速的解决问题,关键是怎么找到当前数字的一半位置,可以使用当前数字pop与反转数字的push相比较,当push后的值大于pop后的值则说明到达了数字长度的一半了,对于奇数位的数字则可以使用reverseNumber/10来判断,因为中间的单个字默认就是回文字。此算法的时间复杂度为O(log(n)),空间复杂度为O(1)。 ...

2020-01-16 · 1 min · 141 words · tomyli

2020-ARTS-打卡第一天

Algorithm 题目描述 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 Example 输入123->321 输入-123->-321 输入120->21 题目解答 import java.util.*; public class Solution1 { public int[] reverseNumber(int num) { int res = 0; while(num != 0) { int pod = num % 10; if(res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && pod > 7)) { return 0; } if(res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && pod < -8)) { return 0; } res = res * 10 + pod; num = num / 10; } return res; } } 此题主要考察对栈的使用,如果不使用其它辅助类,则要考虑Int的整数溢出问题。时间复杂度O(log(n)),空间复杂度为O(1) ...

2020-01-08 · 1 min · 189 words · tomyli

Maven发布401问题排查

日志问题现象 Caused by: org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException: Failed to deploy artifacts: Could not transfer artifact com.aa.bb:client:jar:1.0.0-20191231.021137-1 from/to company::default (http://test.company.local/nexus/repository/maven-snapshots): Transfer failed for http://test.company.local/nexus/repository/maven-snapshots/com/aa/bb/client/1.0.0-SNAPSHOT/client-1.0.0-20191231.021137-1.jar 401 Unauthorized 根据提示,401未授权,表面来看就是发布的权限未认证 排查步骤 settings文件是否配置了发布的用户名与密码,且用户有deploy的权限 <servers> <server> <id>myid</id> <username>myuser</username> <password>mypasswd</password> </server> </servers> 查看deploy插件的版本 如果是2.X的版本,可以使用以下命令进行发布 mvn -DaltDeploymentRepository=company::default::http://test.compnay.local/nexus/repository/maven-snapshots clean package deploy 如果是3.X的版本,则需要按3.X版本进行指定发布 mvn deploy:deploy-file -Dfile=xxx-1.0.0-SNAPSHOT.jar -Durl=http://test.local/nexus/content/repositories/snapshots -DrepositoryId=test-snapshot Deploy 3.0.0-M1的发布bug 如果配置的deploy的插件为3.0.0-M1,则可参考3.0.0-M1 401 bug 进行修改,具体就是指定depoly版本为2.8,根据插件作者的回复感觉就是3.0.0-M1与altDeploymentRepository参数不能一起用

2019-12-31 · 1 min · 51 words · tomyli

那些有用maven命令

查看当前系统的配置信息 排查问题可以查看当前maven所依赖系统的所有变量(系统变量或者环境变量)信息 mvn help:system 查看当前有效的settings文件 maven的配置文件分为全局配置与个人配置,全局配置在$M2_HOME/conf/下,个人配置一般在~/.m2/下,此时查看当前有效的settings配置可以使用 mvn help:effective-settings 查看Settings配置的值 以下命令可以查看settings文件中的settings->servers的配置 mvn -q -Dexpression=settings.servers -DforceStdout help:evaluate 使用help:evaluate可以查看所有的配置信息 指定发布到其它仓库 Deploy插件2.X版本发布 有时候在pom文件中指定了发布的仓库地址,但是又需要发布到另一个仓库,这时可以指定-DaltDeploymentRepository来实现 mvn -DaltDeploymentRepository=id::layout::url 具体说明参见deploy:deploy Deploy插件3.0.0-M1版本发布 /data/mvn/bin/mvn org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M1:deploy-file -DgroupId=com.qqreader -Dfile=./target/$(/data/mvn/bin/mvn -q -Dexpression=project.build.finalName -DforceStdout help:evaluate).jar -Durl=http://testurl.local/nexus/content/repositories/snapshots -DrepositoryId=snapshot-id

2019-12-31 · 1 min · 33 words · tomyli

JAVA8问题处理回顾-持续更新

金额累加问题 使用Reduce进行累加操作,参考这里 List<BigDecimal> bdList = new ArrayList<>(); //populate list BigDecimal result = bdList.stream().reduce(BigDecimal.ZERO, BigDecimal::add); 查找集合的最后一个元素 JAVA8的Stream只提供了FindFirst功能,没有FindLast功能,可以使用Reduce来实现查找最后一个元素的效果 import java.util.*; import java.util.stream.*; public class GetLastEleFromCollection { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("aaa"); list.add("idddd"); list.add("bbbb"); String lastElement = list.stream() .reduce((first, second) -> second) .orElse(null); System.out.println(lastElement); } } bbbb 比较两个时间是否是同一天 import java.time.*; import java.time.temporal.*; public class CompareDay { public static void main(String[] args) { final LocalDateTime now = LocalDateTime.now(); final LocalDateTime localDateTime = LocalDateTime.of(2019, 9, 29, 0, 0, 0); System.out.println(localDateTime.truncatedTo(ChronoUnit.DAYS).isEqual(now.truncatedTo(ChronoUnit.DAYS))); } } true 实现与Python的zip函数功能 import java.util.*; import java.util.function.*; public class Zip { public static void main(String[] args) { List<List<Integer>> result = handle(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), (i, j) -> Arrays.asList(i, j)); System.out.println(result); } public static <T, U, R> List<R> handle(List<T> list, List<U> list1, BiFunction<T, U, R> biFunction) { List<R> result = new ArrayList<>(); for(int i = 0; i < list.size(); i ++) { result.add(biFunction.apply(list.get(i), list1.get(i))); } return result; } } [[1 (\, 4)] (\, [2 (\, 5)]) (\, [3 (\, 6)])] 多个Predicate链 import java.util.*; import java.util.stream.*; import java.util.function.*; public class MorePredicate { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6); final Predicate<Integer> predicate = i -> i % 2 == 0; final Predicate<Integer> predicate1 = predicate.and(integer -> integer > 5); List<Integer> result = list.stream() .filter(predicate1) .collect(Collectors.toList()); System.out.println(result); } } [6]

2019-08-24 · 2 min · 220 words · tomyli

Apollo Client自定义问题拾遗

由于公司很多服务要接入Apollo配置中心,并且对于项目的接入有网络要求,根据官方说明,需要自定义Client来完成 接入步骤 新建maven项目 在Idea中新建maven项目,基于quickstart构建 增加项目依赖 官方说明的建议在新的client中依赖Apollo官方的client,再根据业务进行扩展,所以maven依赖apollo-client,公司项目的网络访问需要通过L5来进行,所以还要依赖L5的jar,目前这个jar包没有maven坐标,只能以lib方式引入 自定义MetaServer 关键的部分,自定义满足公司网络条件的MetaServer,Apollo官网说明是实现MetaServerProvider且Order值小的Providor被使用,按照说明进行实现 Maven打包Client 执行 mvn clean install 进行打包,解压jar包发现就只有一个Providor的实现类,这样jar运行有问题。需要把新Client所有的依赖都打进jar包,在网上找了半天,需要在POM中增加maven的plugin的配置,如下: <!-- 打包所有的maven依赖到jar包 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <excludes> <exclude>junit:junit</exclude> </excludes> </artifactSet> </configuration> </execution> </executions> </plugin> <!-- 添加依赖的非maven jar包 --> <plugin> <groupId>com.googlecode.addjars-maven-plugin</groupId> <artifactId>addjars-maven-plugin</artifactId> <version>1.0.5</version> <executions> <execution> <goals> <goal>add-jars</goal> </goals> <configuration> <resources> <resource> <directory>${basedir}/lib</directory> </resource> </resources> </configuration> </execution> </executions> </plugin> 由于项目中使用了maven依赖与非maven依赖,所以上述的两个插件都要使用。增加了上面两个插件后再运行打包命令查看生成的jar就发现所有的依赖都在jar中了。 项目中使用Client 选择一个项目在测试环境进行配置调试,自定义的Meta Server一直没有生效,所以查找官方文档,由于自定义Providor是通过SPI方式实现的,所以正确的实现方式是新建resource文件夹,指定MetaServerProvider的真正实现类的带包名类才可以,哎,找了我好久。 后续操作 后续会把client上传到内部maven仓库,完善配置API,使业务方可以零配置来使用配置中心。 总结 Maven的打包机制还是不清晰,处理打包问题费了很多时间,要好好重新学习一下 Apollo的官方文档还需要再仔细阅读,有问题多查issue,因为可能有人已经遇到了 多读读源码,真正的体会大牛的软件设计思想

2019-07-01 · 1 min · 70 words · tomyli

Apollo 配置中心畅游

目前市面上的开源产品 Disconf 2014年7月百度开源的配置管理中心,同样具备配置的管理能力,目前已经不维护了,最近的一次代码提交是两年前了。 Spring Cloud Config 2014年9月开源,Spring Cloud生态组件,与Spring Cloud体系无缝整合。 Apollo 2016年5月,携程框架部开源的配置管理中心,具备规范的权限、流程治理等特性。 Nacos 2018年6月,阿里开源的配置中心,可以做DNS和RPC的服务发现。 为什么选择Apollo 社区活跃 刚刚发布了1.4.0版本,Issue处理速度快 文档齐全 体验,部署,设计文档都齐全 重要的灰度发布 想发布一台机器试试水,可以! 开源协议友好 Apache 2 license Apollo都有哪些重要功能 以下摘自官网说明 统一管理不同环境、不同集群的配置 配置修改实时生效(热发布) 版本发布管理 目前只支持对最近版本的恢复。https://github.com/ctripcorp/apollo/issues/1642 灰度发布 权限管理、发布审核、操作审计 编辑与发布是两个独立的操作。 客户端配置信息监控 提供Java和.Net原生客户端 提供开放平台API 这样可以通过其它方式来查看配置信息,平台API说明 使用方便的后台配置系统Portal 分布式部署相对较复杂,这是缺点 外部依赖少,目前依赖Mysql Apollo的组成 Apollo长什么样? Apollo整体设计 总体架构 代码结构 各模块概要介绍 Apollo Config Service 提供配置获取接口,服务对象为Apollo客户端 Apollo Admin Service 提供配置管理(修改、发布)接口,服务与Portal Apollo Portal 提供WEB界面供用户管理配置 Apollo的重要设计 Admin Service与Config Service的通信方式 Apollo使用Mysql实现消息(ReleaseMessage)的处理,消息内容为AppId+Cluster+Namespace,具体的设计思想可以参考这里 客户端与服务端的通信方式 客户端与服务端保持一个长连接(通过Http Long Polling实现) Client Server 重要的Namespace Namespace是配置项的集合,类似于一个配置文件的概念,获取的权限分为private与public两种权限。 Namespace的类型 私有类型 公有类型 关联类型(继承类型) Cluster能用来做什么? 分机房实例,分任务功能实例,比如在一些实例执行job,需要增加-Dapollo.cluster=配置指定集群名 ...

2019-05-09 · 1 min · 108 words · tomyli

ARTS-打卡第一天

Algorithm LeetCode 第一题 题目描述 给一个int数组,返回数组中两个数字相加的和是目标 数的下标。可以假设每个输入只有一个解决方案,并且不能使用同一个元素两次。 Example 给出nums = [2, 7, 11, 15], 目标数为9,则返回[0, 1] 题目解答 import java.util.*; public class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < nums.length; i ++) { int second = target - nums[i]; if(map.containsKey(second)) { return new int[]{map.get(second), i}; } map.put(nums[i], i); } return new int[]{}; } } 相比两次循环的方式,这种处理的时间复杂度为O(n), 空间复杂度也为O(n). ...

2019-05-09 · 1 min · 129 words · tomyli

Centos7 install issue collect

由于工作需要,使用VMWare虚拟机安装了Centos7系统,遇到了很多问题,现在把这些问题记录下来,以备后用。 解决Centos7 yum could not retrieve mirrorlist错误 刚安装好的VM使用ip add查看局域网的ip没有结果,这个参考https://my.oschina.net/u/2456768/blog/3011881 配置静态ip 安装虚拟机就是模拟多个机器通讯的情况,但是目前的配置是机器ip是动态获取的,老是变,每次都得看ip,所以需要配置一下VMware来支持静态ip。主要机器上的配置信息为: IPADDR=192.168.116.101 NETMASK=255.255.255.0 GATEWAY=192.168.116.2 DNS1=192.168.116.2 这个参考了https://blog.csdn.net/zhishengqianjun/article/details/77046796 Centos7安装后配置国内仓库源 由于国内访问centos的原始源慢,需要换成163的软件源,新安装的系统执行命令都提示not found,只能从物理下载源的配置再上传到VM中,但是首先得知道VM的ip地址,使用ifconfig是不可能了,查了一下可以使用 ip a 来查看VM的ip地址,这样配置源的的问题可以解决了,具体的配置源的方法参考https://blog.csdn.net/inslow/article/details/54177191 Centos7安装VMware Tools 想更好的让VM与物理机协同,则VMware Tools必须要安装,好久不用linux的我连挂载也忘的一干二净了。搜了一下,参考https://blog.csdn.net/WarnerWu/article/details/73718901 完成VMware Tools的安装。这样共享目录的功能就可以正常使用了 安装Jdk8 一句命令搞定: yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel 安装mysql 使用yum安装mysql需要下载安装mysql的源,更新后就可以安装了,这个参考了https://www.linode.com/docs/databases/mysql/how-to-install-mysql-on-centos-7/ 修改mysql的root密码 安装完mysql后登录找不到密码了,其实在使用yum安装时会mysql会自动生成一个随机密码,这个密码可以在安装的日志中找到。此方法参考了https://blog.csdn.net/kuluzs/article/details/51924086 开放3306端口 为了方便mysql工具进行操作,需要开放3306端口。Centos7的防火墙还改了。具体就3个命令: systemctl start firewalld firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload 这个参考了https://www.jianshu.com/p/225a853350d9 安装oh-my-bash 由于一般服务器都自带bash为默认的shell,但是操作起来着实不方便,安装oh-my-bash可以对shell进行一些增强。https://github.com/ohmybash/oh-my-bash Centos自动登录 安装后每次启动VM都要输入密码,这个对于自己测试很麻烦,要使Centos能登录后自动登录需要做以下操作: 移除原来的getty@tty1.service软链接 rm /etc/systemd/system/getty.target.wants/getty@tty1.service 拷贝getty@.service file 并且命名为 getty@tty1.service cp /lib/systemd/system/getty@.service /etc/systemd/system/getty@tty1.service 编辑新拷贝的getty@tty1.service,修改以下内容,最后一行必须加上 [Service] ... ExecStart=-/sbin/agetty --autologin root --noclear %I ... [Install] ... ;Alias=getty@tty1.service 在getty.target.wants目录做一下软链接 ...

2019-05-06 · 1 min · 85 words · tomyli