HiSEN

Personal Technology Blog


  • 归档

  • 分类

  • 标签

  • 书单

  • 关于

  • 搜索
close
HiSEN

数组中只有一个数出现奇数次 | 利用异或最高效

发表于 2019-04-04 | 分类于 java

一、背景

题意:一个数组有奇数个元素,其中只有一个元素出现一次,其它都出现了2次

方案A:利用hashMap存储出现的次数,然后遍历,复杂度O(3/2N)=O(N);
方案B:利用bitmap,根据数组元素的大小确定位置,做取反(0->1->0);
方案C:利用异或的特性快速找出,最简单,高效;

二、异或

a^a=0
0^a=a
异或支持:交换率、结合率
因此:
a^b^c^b^c=a^(b^b)^(c^c)=a

三、代码

阅读全文 »
HiSEN

Agent CGlib VS JDK | 动态代理比较

发表于 2019-03-30 | 分类于 java

一、代理简介

1.1 代理是什么

举个例子:快到吃饭的点了,你有两种选择:1)自己做,2)叫外卖
1.1.1 自己做你嫌麻烦,那就叫外卖,只管收外卖其它不关注(解耦);
1.1.2 自己做的不好吃,那厨师上门,厨师给你增强菜的味道(增强);

官方定义:对其他对象提供一种代理以控制对这个对象的访问。

1.2 使用场景是什么

1.2.1 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。

1.2.2 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。

1.2.3 Spring的AOP机制就是采用动态代理的机制来实现切面编程。

二、CGlib VS JDK 两种方式实现代理

2.1 差异

2.1.1 JDK:只能代理接口
2.1.2 CGlib:直接代理类

2.2 简单demo

阅读全文 »
HiSEN

计算长度最大的子串长度(按空格分割) - 多种方式

发表于 2019-03-26 | 分类于 java

一、背景

今天中午一个朋友问我一个问题没来得及回,现在折腾一下;
问题:有一个包含以N个空格分割的字符串,求最大子串的长度,要求时间空间复杂度最优;

二、方案:

  1. 朋友给人方案:直接split分割遍历数组,找出最大值;
  2. 面试官的方案:使用StringTokenizer,找出最大值;
  3. 我想到的方案:indexOf计算index差值,找出最大值;

三、结果:

封装的代码比较复杂,目前来看不在么好分析时间复杂度和空间复杂度;
于是就直观得对比了一下时间;

1
2
3
4
//        output
// use(nano): 15486049, by 方案3
// use(nano): 66060102, by 方案2
// use(nano): 80844275, by 方案1

有时间再深入了解下StringTokenizer的源码

四、代码对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
String oriStr = "aa aa aaaa aaa a a a aa aa a";
int times = 100000;
// 自定义实现
final long start1 = System.nanoTime();
for (int i = 0; i < times; i++) {
String splitStr = " ";
findMaxLength(oriStr, splitStr);
}
final long end1 = System.nanoTime();

// 利用 StringTokenizer
final long start2 = System.nanoTime();
for (int i = 0; i < times; i++) {
findMaxLength4StringTokenizer(oriStr);
}
final long end2 = System.nanoTime();

// 利用 Split
final long start3 = System.nanoTime();
for (int i = 0; i < times; i++) {
String splitStr = " ";
findMaxLength4Split(oriStr, splitStr);
}
final long end3 = System.nanoTime();

System.out.println("use(nano): " + (end1 - start1) + ", by findMaxLength");
System.out.println("use(nano): " + (end2 - start2) + ", by findMaxLength4StringTokenizer");
System.out.println("use(nano): " + (end3 - start3) + ", by findMaxLength4Split");
// output
// use(nano): 15486049, by findMaxLength
// use(nano): 66060102, by findMaxLength4StringTokenizer
// use(nano): 80844275, by findMaxLength4Split

五、完整代码

阅读全文 »
HiSEN

Dubbo官方中文文档|用户文档|开发者指南|源码导读|运维管理

发表于 2019-03-25 | 分类于 java

一、为什么要学Dubbo

近几年一直在使用dubbo进行支付系统的开发;
作为国内比较受欢迎的一个SOA框架,Dubbo使用简单设计优雅;
里面用到的思想和技术,基本上涵盖大部分互联网公司用到的技术;
记得直属领导说过一句话,看完Dubbo他觉得设计者简直就是天才;
而且看完dubbo的源码,对他的影响很大,处处模仿dubbo的思想;

二、文档地址

中文文档:用户文档、开发者指南、源码导读、运维管理
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
用户手册(比较完整):
https://dubbo.gitbooks.io/dubbo-user-book/demos/routing-rule.html
官方博客:
http://dubbo.apache.org/zh-cn/blog/index.html

三、Dubbo创始人博客

最后更新于2014年
https://javatar.iteye.com/

HiSEN

WeightAlgorithm - 权重算法 - Random、HashCode对比

发表于 2019-03-22 | 分类于 java

一、权重算法

权重算法一般在路由里面用的比较多,分布式环境下对等的服务有多个,加权随机选出一个服务来调用;

可能还有其他方面的用途,下面的代码简单的实现了这个权重,本质上就用到了数组,随机下标;

二、代码概览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
String[] weight = {"A", "A", "A", "A", "A", "B", "B", "B", "C", "C"};
final int times = 500000;
final long hashStart = System.currentTimeMillis();
List<String> hashRes = getList4Hash(weight, times);
printRes("Hash", hashStart, hashRes);

final long randomStart = System.currentTimeMillis();
List<String> randomRes = getList4Random(weight, times);
printRes("Random", randomStart, randomRes);
// Hash use millis: 931
// A:49.92%
// B:29.99%
// C:20.09%
// Random use millis: 50
// A:50.08%
// B:29.93%
// C:19.99%
}

三、完整代码

阅读全文 »
HiSEN

git版本差异报告 - git difftool分支对比 - gitLab compare

发表于 2019-03-09 | 分类于 java

一、初衷

有时候上线会出现合错代码,比如功能,或者maven的pom文件;

人都不是十全十美的人,只要是人就会犯错
关键是要想办法去避免,只有工具才不犯错

所以尽量想办法利用工具来防止我们犯错,git来说有很多办法;
简单的命令,或者gitlab的compare报告;
每次上线之前,开发自己看一遍当前版本与线上版本的区别,确认每一个点都是正确的改动;

二、gitlab compare功能(推荐)

2.1 入口:工程首页 -> Repository -> Compare
2.2 选择:上一个版本,当前版本,点击Compare
2.2 结果:一次能看到两个版本的所有commit、改动点

三、git命令

1
2
3
4
5
# 显示版本之间改动的文件名
git difftool master 1.2.4 --stat

# 在命令行挨个显示版本某个文件具体差异
git difftool master 1.2.4
HiSEN

dubbo transport Data length too large-14277263-max payload-8388608 channel-NettyChannel

发表于 2019-03-07 | 分类于 java

一、报错信息

1
com.alibaba.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 14277263, max payload: 8388608, channel: NettyChannel [channel=[id: 0x12a13c8f, /172.0.0.1:49402 => /172.0.0.2:23888]]

二、报错原因

dubbo默认使用Netty传输协议
并且默认的大小限制为:默认为8M,即8388608

三、解决办法

  1. 修改接口
    出现这种情况是因为一个接口查某个表的所有数据(几万条)
    一般这种接口肯定是需要分页的

  2. 更改配置信息
    在dubbo.properties 中增加如下

    1
    dubbo.protocol.dubbo.payload=11557050
HiSEN

java.lang.NoClassDefFoundError错误解决

发表于 2019-02-23 | 分类于 java

maven项目昨天遇到的一个错误:java.lang.NoClassDefFoundError

理论原因:JVM在编译的时候能找到调用方法或静态变量所在的类,但在运行的时候找不到此类而引发的错误。

真实原因:(仅针对当前问题)
项目A依赖公共服务C-1.0.1版本
项目B依赖项目A,B中dependencyManagement强制指定C-1.0.0

此时编译可以通过,运行时如果有用的C的新版本功能就会会出现上述问题

解决办法:对项目B中C的版本升级,使用1.0.1

扩展阅读:
https://blog.csdn.net/qq_27576335/article/details/77102385
https://blog.csdn.net/jamesjxin/article/details/46606307

HiSEN

MySQL统计成功率等 - 利用case when

发表于 2019-02-18 | 分类于 sql

CONCAT:连接字符串,CONCAT(55.00,’%’)->55.00%
truncate:处理小数点位数,truncate(10.1111,2)->10.11

统计sql

1
2
3
4
5
6
7
8
9
10
11
select res.*, CONCAT(truncate((res.succ / res.`all`) * 100, 2), '%') as 'success rate'
from (select tpc.USER_NO,
tpc.TYPE,
count(*) as 'all',
sum(case when tpc.STATUS = 0 then 1 else 0 end) as 'succ',
sum(case when tpc.STATUS = 1 then 1 else 0 end) as 'fail',
sum(case when tpc.STATUS != 1 && tpc.STATUS != 0 then 1 else 0 end) as 'other'
from t_hisen tpc
where tpc.DATE between '20190216' and '20190217'
group by tpc.USER_NO, tpc.TYPE
order by tpc.USER_NO) res

统计结果

USER_NOTYPEallsuccfailothersuccess rate
4561010010.00%
1231029230679.31%
HiSEN

MySQL - Data truncation:Incorrect datetime value

发表于 2019-02-01 | 分类于 sql

一、问题

1
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '2039-01-07 12:58:20.625' for column

二、原因

由于程序没有控制好,计算下一次更新时间失误,造成数值过大。

1
2
3
update table_a
SET UPDATE_TIME = '2039-01-07 12:58:20.625'
WHERE ID = 6241

以下是MySQL官方的说法,就是时间超过了范围。

1
2
The TIMESTAMP data type is used for values that contain both date and time parts.
TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

1…8910…27
hisenyuan

hisenyuan

Java R & D

266 日志
33 分类
112 标签
GitHub Weibo
Links
  • 科技爱好者周刊
  • 美团技术团队
  • duanple(老师木)
  • 当然我在扯淡(王垠)
  • 段永平的博客
  • 梦殇国际
© 2016 - 2024 hisenyuan
由 Hexo 强力驱动
您是第  个访问者    |   
主题 - NexT.Mist