Janice的博客


  • Home

Double checked locking 双重检查锁

Posted on 2020-08-13 | In java

实现单例模式的方法有好几种,例如饿汉式、懒汉式、双重检查。其中双重检查才适用于多线程的情况,其他代码都会造成线程不安全,例如:

1
2
3
4
5
6
7
8
9
10
11
12
public class Singleton{
private static Singleton singleton;
private Singleton(){

}
public Singleton getInstance(){
if(null == singleton){
singleton = new Singleton();
}
return singleton;
}
}

若有两个线程A和B同时访问上述代码,线程A检查到singleton为空,在还没有创建实例前,线程B进来了,它也检查到singleton为空,那么最后会生成两个实例对象,这违背了单例模式的定义。

那么,为了解决上述问题,我们可以对getInstance()方法进行加锁。但是用synchronized直接对方法加锁会导致很大的性能开销。更好的方法是使用双重检查锁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//错误的方法
public class Singleton{
private static Singleton singleton;
private Singleton(){

}
public Singleton getInstance(){
if(null == singleton){
synchronized (Singleton.class){
if(null == singleton){
singleton = new Singleton();
}
}
}
return singleton;
}
}
Read more »

蓄水池采样算法

Posted on 2020-07-18

在不知道数据规模的情况下进行采样,就要用到蓄水池采样算法。

算法过程

假设数据总规模为N,需要采样k个数。那么先构建一个k大小的数组result,将数据的前k个数放进去。然后从第k+1个数开始,产生一个随机数r,如果这个r < k,则将当前遍历到的数替换result[r]。

这个算法保证了数组中的元素被替换的概率是相同的,都为 k/n。证明如下:(图源https://www.cnblogs.com/snowInPluto/p/5996269.html)

code

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
import java.util.*;
public class Solution {

private static int[] pool; // 所有数据
private static final int N = 100000; // 数据规模
private static Random random = new Random();

public static void setUp(){
// 初始化
System.out.println("初始化");
pool = new int[N];
for (int i = 0; i < N; i++) {
pool[i] = i;
}
}
private static int[] sampling(int K) {
int[] result = new int[K];
for (int i = 0; i < K; i++) { // 前 K 个元素直接放入数组中
result[i] = pool[i];
}

for (int i = K; i < N; i++) { // 从第K + 1 个元素开始进行概率采样
int r = random.nextInt(i + 1); //从[0,i]中随机选一个数
if (r < K) {
result[r] = pool[i];
}
}
return result;
}

public static void main(String[] args) {
setUp();
for (int i : sampling(100)) {
System.out.println(i);
}
}
}

hexo搭建博客踩坑记录

Posted on 2020-06-30 | In hexo

npm node的版本

无论是npm还是node.js的版本都要高一些,不然会有很多包安装不上,出现n多问题。我的博客node.js为v12.16.1,npm版本为6.14.2。

root地址要修改

由于觉得github项目名取为***.github.io太长,所以直接取名为blog,最终博客地址为https://janicewuo.github.io/blog/

Read more »

前端和后端的跨域问题——Invalid CORS request解决

Posted on 2020-06-20 | In java

前端部署在http://localhost:8080,而SpringBoot创建的后端部署在http://localhost:9000。即使都是在本地,端口号不一样也是跨域。所以当前端页面点击登陆按钮要访问后端时会产生Invalid CORS request,且Request Method为OPTIONAL。

解决方案:
编写一个CorsConfig:

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
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置你要允许的网站域名,如果全允许则设为 *
config.addAllowedOrigin("http://localhost:8080"); //这里意思是允许端口号为8080的来访问服务器
// 如果要限制 HEADER 或 METHOD 请自行更改
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// 这个顺序很重要哦,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}

编写以上配置类后,能成功访问后端并且Request Method变为了POST。

python3正则表达式总结

Posted on 2020-04-25

1.re.compile(),用于编译正则表达式,生成一个正则表达式对象,供给其他函数使用。

1
2
3
4
import re
pattern = re.compile(r'([a-z]+) ([a-z]+)',re.I) #re.I是忽略大小写
m = pattern.match('Hello World Wide Web')
print(m.group(0)) #返回匹配成功的整个子串 'Hello World'
1
2
3
4
5
# 字符串去重
import re
p = re.compile(r"([a-zA-Z])(\1+)") #在compile的时候就分组
s = "abbbcc"
print(p.sub(r"\1",s)) #abc
1
2
3
4
5
#统计字符串中每个数出现次数
import re
p = re.compile(r"([a-zA-z])(\1+)")
s = "abbbcc"
print(p.sub(lambda m : m.group(1)+str(1+len(m.group(2))),s)) #a1b3c2

group(1)是返回匹配的第一个结果,group(2)是第二个。

2.re.match()只查找头部,如果头部没有匹配的则返回None。

3.re.search()会匹配全部字符串,直到找到一个匹配。

用pandas和sklearn处理数据

Posted on 2020-04-16

1.pandas.get_dummies

是利用pandas实现one hot编码,如果想对全部列都进行one hot,则为data=pd.get_dummies(original_data),如果是指定列,则data=pd.get_dummies(列名)

2.sklearn的LabelEncoder()

以泰坦尼克号数据集举例,里面的性别原本为male,femal离散数值,要把它变为0,1不需要手动遍历进行转换,直接调用sklearn的函数即可,非常方便。

1
2
3
4
5
from sklearn import preprocessing
import pandas as pd
le = preprocessing.LabelEncoder()
titanic_data = pd.read_csv(路径)
titanic_data['Sex']=le.fit_transform(titanic_data['Sex']) #在源数据集上进行改动
Read more »

python列表复制

Posted on 2020-04-08

a = [1,2,3] b = a,则b也为[1,2,3]

这种复制方法,a和b指向同一个list,如果a改动,则b也会变,如下:

1
2
3
4
a = [1,2,3]
b = a
a.append(4)
print(b) #b=[1,2,3,4]

另外一种复制方法为b=a[:],切片式复制,此时b是完全复制了一个列表。和b=list(a)效果一样。

1
2
3
4
a = [1,2,3]
b = a[:]
a.append(4)
print(b) #b=[1,2,3]

深复制和浅复制:(若列表中又有列表,浅复制的子列表还是会变。)

1
2
3
4
5
6
7
8
import copy
a = [[1],2,3]
b = copy.copy(a)
c = copy.deepcopy(a)
a.append(4)
a[0].append(10)
print(b) #[[1,10],2,3]
print(c) #[[1],2,3]

学习心得

Posted on 2020-03-30 | In 心得

从接触NLP开始,用的基本都是深度学习模型。由于之前没有接触过主题模型,今天就去搜了一下LDA(Latent Dirichlet Allocation)介绍,没想到这个机器学习模型涉及那么多数学知识啊,比如伯努利、Gamma函数、共轭先验、狄利克雷函数等等,太深奥了!难怪很多前辈们都推崇机器学习方法,毕竟是实打实的数学堆起来的成果,而且确实有时候机器学习比深度学习跑出来的效果要好。比如我之前拿SVM跑过‘预测学生的返校工具’,结果就比用神经网络效果要好,当然也有可能是因为当时数据集比较小。
接下来准备看看《LDA数学八卦》,是真的长。

【编程题】bit 位数

Posted on 2020-03-28 | In 算法

题目描述

两个int32整数m和n的二进制表达,计算有多少个位(bit)不同?
例如输入15,8 输出3
因为15 = 1111 8 = 1000 有3位不同

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
def main():
line = sys.stdin.readline()
a,b = map(int,line.split())
a = bin(a).replace("0b","")
b = bin(b).replace("0b","")
n = max(len(a),len(b))
a = a.rjust(n,'0')
b = b.rjust(n,'0')
count = 0
for i in range(n):
if a[i]!=b[i]:
count+=1
print(count)

if __name__ == '__main__':
main()

知识点:python中的bin()可以直接将int型转换为2进制,输出格式为0b****,所以这里要把0b去掉。
而且转换后位数不同,这里取最长的位数,用rjust()向右对齐,左边空缺处补0。

python2和python3在除法上的区别

Posted on 2020-03-24 | In python

几年前装上python3之后就没用过python2了,但是刚刚在牛客网刷题时,编辑器只有python2没有python3,于是遇到坑了。我检查一遍代码觉得没有错,又复制到本地sublime上运行一遍也没问题,但是在牛客网上只通过16%的样例。
想了一下可能是python版本问题,最后找到原因。在python2中:

1
3/2=1

在python3中:

1
3/2=1.5

这导致的后果是在执行代码while small<sum/2时,若small=1,sum=3,在python2中会认为不满足条件,导致程序返回结果出错,而在python3中代码是对的。

12<i class="fa fa-angle-right"></i>

Wu Jing

程序媛|软工硕士|NLP

14 posts
7 categories
1 tags
© 2020 Wu Jing
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4