0%

首先看一段代码:

1
2
3
4
String[] splitArr = "1|23242|3|4".split("|");
for (String s : splitArr) {
System.out.println(s);
}

输出结果是:

1
2
3
4
5
6
7
8
9
10
11
1
|
2
3
2
4
2
|
3
|
4

在Java中有三个特殊字符:.,\,|,这几个字符分割的时候,需要用\\进行转义.

正确的代码如下:

1
2
3
4
String[] splitArr = "1|23242|3|4".split("\\|");
for (String s : splitArr) {
System.out.println(s);
}
阅读全文 »

今天学习了python的list和tuple的使用,python中的数组类型的结构比其他语言更为灵活,下面我们说说他们的用法:

list使用

  1. 定义一个list

    1
    2
    3
    >>> arr=[1,2,3,4,5,6]
    >>> arr
    [1, 2, 3, 4, 5, 6]

    arr就是定义的数组,使用索引来获得数组里面的数据如:arr[0],arr[1]等等,在python数组有一个特殊的用法,使用-1,-2可以取倒数第一或第二的值。

    1
    2
    3
    4
    >>> arr[0]
    1
    >>> arr[-1]
    6

    如果超出界限,会抛出异常:

    1
    2
    3
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    IndexError: list index out of range

    由于python是弱类型的语言,所以数组里面可以存储不同类型的数据:

    1
    2
    3
    >>> arr=[1,2,"hello",[1,2,34]]
    >>> arr
    [1, 2, 'hello', [1, 2, 34]]

    如果想拿到34这个值,可以类似二维数组那样arr[3][2]

    可以使用range函数快速定义个有序的数组:

    1
    2
    3
    >>> list(range(10))
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>>

    range的具体的使用方法range(start, stop[, step])
    range(1,10,2)代表的从1-10每次长度的2

  1. 数组的相关的函数

    • len 获得数组的长度

      1
      2
      >>> len(arr)
      4
    • append 增加一个元素

      1
      2
      3
      4
      >>> arr.append("1111")
      >>> arr
      [1, 2, 'hello', [1, 2, 34], '1111']
      >>>
    • insert插入数据

      1
      2
      3
      >>> arr.insert(1,213)
      >>> arr
      [1, 213, 2, 'hello', [1, 2, 34], '1111']

      insert(1,213)代表在1位置,插入一个213的数字

 - `pop`删除元素  

     `pop`是`python`中删除元素的方法,`arr.pop()`默认删除最后一个元素,`arr.pop(i)`代表可以删除指定位置的元素:  

      
1
2
3
4
5
>>> arr.pop()
'1111'
>>> arr
[1, 213, 2, 'hello', [1, 2, 34]]
>>>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
          >>> arr.pop(1)
213
>>> arr
[1, 2, 'hello', [1, 2, 34]]
```

#### tuple的使用

`tuple`是一个有序的数组,和`list`类似,`tuple`的特点是定义后不能在被修改,这样可以让代码中的数据更加安全。

定义`tuple`使用`()`,例如定义一个`tuple`如下:

```python
>>> tup=(1,2,3)
>>> tup
(1, 2, 3)

由于tuple不可修改,所以不能使用append,insert等修改元祖的方法。

如果定义一个只有一个元素的tuple:

1
2
3
>>> tup=(1)
>>> tup
1

这样我们发现,tup不是一个元祖,而是一个数字。原来是只用一个元素的时候,tuple中的()与数学运算中的括号冲突了,所以当定义只有一个元素的tuple的时候,需要在最后加一个,,方法如下:

1
2
3
>>> tup=(1,)
>>> tup
(1,)
阅读全文 »

在多线程的使用中,有时会碰到死锁,死锁会造成应用程序阻塞,浪费系统资源。下面探讨如何发现和解决死锁:

产生死锁

首先先写一段能够产生死锁的代码:

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
private static Object lock1=new Object();
private static Object lock2=new Object();
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
synchronized (lock1){
System.out.println("线程1获得 lock1");
SleepUtils.Sleep(1);
synchronized (lock2){
System.out.println("线程1获得 lock2");
}
}
System.out.println("线程1结束 ");
}
}.start();
new Thread() {
@Override
public void run() {
synchronized (lock2){
System.out.println("线程2获得 lock2");
SleepUtils.Sleep(1);
synchronized (lock1){
System.out.println("线程2获得 lock1");
}
}
System.out.println("线程2结束 ");
}
}.start();
}

运行上面的结果,线程会各自阻塞在同步锁的那个地方,产生了死锁,运行结果如下:

1
2
线程1获得 lock1
线程2获得 lock2

我们使用jps命令, 查询Java的线程,如下:

jps

使用jstack 16071命令查看堆栈信息

jps

阅读全文 »

deepin中idea乱码

在deepin中使用idea中文乱码,是缺少字体的原因,所以需要安装字体:

1
aptitude search uming 

如果正确安装会显示如下信息:

deepin

如果没有正确安装,使用下面命令安装:

1
aptitude install fonts-arphic-uming

安装完成后重启下idea就可以了。

阅读全文 »

实现功能点

  1. 小球出生有一个等级和收入
  2. 小球每次随机获得一个目标点,在一定的时间范围内,然后移动到目标点,超时和到达则重新获取目标点。
  3. 小球在移动的过程中,碰到相同的size的球,会自动融合,成为一个新的球,size和gain是原来的两倍。
  4. 利用本地的存储对数据进行存储和恢复,利用平均收益和离线时间,计算离线收益。
  5. 增加出生速度,运动速度的属性的时候都需要对应的收益,玩家控制好金钱分配,把收益最大化。
阅读全文 »

nested 类型是一个特殊object数据类型,允许数组的object的字段可以被独立的查询出来。

数据类型是如何被封装的

在lucene中没有嵌套object的概念,所以ES的用一个简单的数据数据列表来表示一个复杂的层次数据实体,例如一个博客和评论的实体:

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
33
34
PUT  nesttest/_doc
{
"blog_title": "开篇-es的nest的使用",
"blog_content": "从本篇文章开始,我会分享给大家canvas绘制的各种基础图形和酷炫的图形",
"tags": [
"Java",
"es"
],
"hit_count": 5,
"commet": [
{
"commet_user": "tom",
"commet_content": "good Job",
"commet_time": "2019-02-26",
"commet_location": "beijing"
},
{
"commet_user": "john",
"commet_content": "clearly,tks",
"commet_time": "2019-02-23"
,
"commet_location": "shanghai"
},
{
"commet_user": "lily",
"commet_content": "it's too hard ",
"commet_time": "2019-02-22"
,
"commet_location": "shenzhen"
}
],
"create_time": "2019-02-26"
}

其中commet类型会被转化成一个数组的形式如下:

1
2
3
4
5
6
{
...
"commet.commet_user":["tom","john","lily"],
...
"commet.commet_location":["beijing","shanghai","shenzhen"],
}

而当执行查询的时候:

1
2
3
4
5
6
7
8
9
10
11
12
GET nesttest/_search
{
"query": {
"bool": {
"must": [
{ "match": { "commet.commet_user": "john" }},
{ "match": { "commet.commet_location": "shenzhen" }}
]
}
}
}

发现查询结果如下:

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
33
34
35
36
37
38
39
40
41
42
43
44
{
...

"hits" : [
{
"_index" : "nest",
"_type" : "_doc",
"_id" : "pe0iKWkBulkJdQfMSgyV",
"_score" : 0.5753642,
"_source" : {
"blog_title" : "2019-01-05",
"blog_content" : "从本篇文章开始,我会分享给大家canvas绘制的各种基础图形和酷炫的图形",
"tags" : [
"Java",
"es"
],
"hit_count" : 5,
"commet" : [
{
"commet_user" : "tom",
"commet_content" : "good Job",
"commet_time" : "2019-02-26",
"commet_location" : "beijing"
},
{
"commet_user" : "john",
"commet_content" : "clearly,tks",
"commet_time" : "2019-02-23",
"commet_location" : "shanghai"
},
{
"commet_user" : "lily",
"commet_content" : "it's too hard ",
"commet_time" : "2019-02-22",
"commet_location" : "shenzhen"
}
],
"create_time" : "2019-02-26"
}
}
]
}
}

阅读全文 »

现象问题

最近看到线上的项目线程数过大的报警,开始还是不知道什么原因,因为很多项目都使用同样的线程池管理代码,认为那个项目是偶然的因素造成的,后来经过分析,发现线程数每天都在增加。其他的项目由于发布导致线程会从零开始计算,所以没有那么快达到报警值。 触发报警的代码大概如下:

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
boolean start=true;
public void doSomeThing(){
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
Thread thread = new Thread(() -> {
while (start) {
try {
if(.//判断能否执行){
Thread.sleep(100);
return;
}
executorService.execute(() -> {
try {
//....your code
} catch (Exception e) {

} finally {

}
});
} catch (Exception e) {
}
}
});
thread.start();
}

public int getMaxThreadCount(){
return ....;
}
public void stop(){
this.start=false;
}

上面的代码存在两个问题:

  1. start是个主线程的变量,在主线程修改值,子线程的while循环不会停止

    上述代码能够停止,因为在内部调用`Thread.sleep方法,导致线程内的变量刷新

  2. newFixedThreadPool 线程池没有调用shutdown方法,导致线程不会被回收。

改正方法:

  1. start 设置成线程共享变量volatile类型

  2. 在最后调用停止的时候,让线程池进行回收

修改后代码如下:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46

volatile boolean start=true;
ExecutorService executorService;
Thread thread ;
public void doSomeThing(){
executorService = Executors.newFixedThreadPool(nThreads);
thread = new Thread(() -> {
while (start) {
try {
if(.//判断能否执行){
Thread.sleep(100);
return;
}
executorService.execute(() -> {
try {
//....your code
} catch (Exception e) {

} finally {

}
});
} catch (Exception e) {
}
}
});
thread.start();
}

public int getMaxThreadCount(){
return ....;
}
public void stop(){
this.start=false;
if (executorService != null) {
executorService.shutdown();
executorService.awaitTermination(MaxConcurrency() * 3, TimeUnit.SECONDS);
for (int i = 0; i < 10 && !executorService.isTerminated(); i++) {
Thread.sleep(1000);
}
}
if (thread != null && thread.isAlive()) {
thread.interrupt();
thread.join(2000);
}
}

最后的疑问

阅读全文 »

引出问题

在mysql中,可以使用join来实现表与表之间的数据连接,在es中如何实现这个问题?

相对于mysql来说,es有几个不同的地方

  1. 不支持跨index的join
  2. 一个index只能包含一个类型
  3. 分布式的存储方式,对于数据的搜寻造成障碍

对于上面的几个问题,es的解决方案是**在一个索引下,借助父子关系,实现类似Mysql中多表关联的操作**

定义类型和join索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PUT myorder
{
"mappings": {
"_doc": {
"properties": {
"order_join": {
"type": "join",
"relations": {
"order": "suborder"
}
}
}
}
}
}

定义join关系为order_join,其中order是父文档,suborder是子文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
put  myorder/_mapping/_doc
{
"properties": {
"orderId": {
"type": "keyword"
},
"shortTime": {
"type": "date"
},
"name": {
"type": "keyword"
},
"amount": {
"type": "double"
},
"desc": {
"type": "text"
}
}
}

插入主单数据

阅读全文 »

  1. 安装和升级pip工具 python.exe -m pip install --upgrade pip

  2. 安装tensorflow pip install --upgrade tensorflow

  3. 安装openvc: pip install opencv-python

阅读全文 »

在python3中多线程出现了很多变化,原来的thread 变成_thread,官方更推荐使用threading.

创建线程使用Thread方法,使用方法和传递参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# coding: utf-8
import time
import threading

def print_str(i):
while(True):
print ('thread',str(i),time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
time.sleep(1)

ths=[];
for x in range(0,10):
th=threading.Thread(target=print_str,args=(x,))
th.start()
ths.append(th)

for t in ths:
t.join()

阅读全文 »