V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  wqlin  ›  全部回复第 2 页 / 共 13 页
回复总数  257
1  2  3  4  5  6  7  8  9  10 ... 13  
2020-07-02 13:57:53 +08:00
回复了 phpcyy 创建的主题 程序员 一个关于 Raft 协议的疑问
我觉得大前提不对,需要日志 committed + apply 才会返回给 client 。
第一个问题的话可能会保存成功,也有可能不会(取决于 B/C 是否成功当选)
第二个问题的话比较难了。
Raft 中只有 committed 的日志才是安全不丢的( index <= committed index ),其他情况下都是不安全的。
一家之言,仅供参考
2020-03-22 19:26:13 +08:00
回复了 pczhang 创建的主题 程序员 一个 29 岁大龄猿的自我剖析
卧槽,老哥可以去做地理位置相关方向的呀。比如华为地图,腾讯地图等等,也算利用自己的专业优势。或者来我们字节试试,我们这是个做地址位置方向的中台
2019-03-05 22:30:06 +08:00
回复了 digitalwater 创建的主题 职场话题 帝都年薪 50W 还是肉翻美帝读 PhD
@digitalwater 😃谢谢楼主,楼主强啊,两年 50w。方便透露下在哪个公司或者加个 wc 聊一下?
2019-03-05 18:56:31 +08:00
回复了 digitalwater 创建的主题 职场话题 帝都年薪 50W 还是肉翻美帝读 PhD
楼主申请到了 phd ?能分享下流程和经历吗
2018-12-24 12:19:00 +08:00
回复了 kaxi 创建的主题 程序员 在微服务架构中是否可用 redis 代替 etcd?
@wqlin #9 服务的注册和发现,etcd 利用了其租约特性。这句话怎么理解?租约不是加快读性能吗
2018-12-24 12:17:15 +08:00
回复了 kaxi 创建的主题 程序员 在微服务架构中是否可用 redis 代替 etcd?
服务注册和发现 自身要保证高可用、数据不丢吧。这些 redis 做不了保证,etcd 可以保证。
不过既然考虑 etcd,为啥不考虑 consul,直接支持服务注册和发现
@lhx2008 我到没怎么用过 Collections 中的 get 函数,只是表达下 T 和 ? super T 区别。不过为啥是第一个参数而不是第二个参数?
@lhx2008 有区别啊。比如说 T 是 Number,你的 copy 只能将 List<Integer> 拷贝到 List<Number> 中。那如果我想将
List<Integer> 拷贝到 List<Object> 就要用第一种写法了
@lhx2008 #12 第二个参数 extends T 是不能调用 add 方法的,会报编译错误的。
比如申明了
```
List<? extends Number> myNums = new ArrayList<Integer>();
```
只能从 myNums 中读取元素,赋值给 Number 类型(还不能是其他类型):
```
Number n = myNums.get(0);
```
如果调用 add 会直接报编译错误:
```
myNums.add(45L); //compiler error
```
类似的,super 只能写不能读:

```
List<? super Number> myNums = new ArrayList<>();
myNums.add(1L); // legal
myNums.add(0.1); // legal
```
读会报错:
```
Number myNum = myNums.get(0); //compiler-error
```
谈一下我的理解。
Java 类型系统中 数组 和 集合 是会让人迷惑的。比如有两个类型,A 和 B,其中 A 是 B 的子类。那么 []A 也是 []B 的子类,可以这么写

```
[]A a = {...};
[]B b = a;
```

但是使用集合时,比如 List。List<A> 和 List<B> 没有半毛钱关系,这两个类型完全没有联系。
那么如何在集合中表达类型的上下限呢?就需要用到 ? 占位符、extends 和 super。
? 是类型占位符,表示这是一个类型,但是具体什么类型未知。比如 List<?> 表示一个未知类型的 List,但是这不是 raw List。
? 通常和 extends、super 一起使用。作为方法参数时,比如 List<T>,那么 List<? extends T> 可以接受任何 List<E>,其中 E 是 T 的子类,类型上限为 T ; List<? super T> 可以接受任何 List<E>,E 是 T 的超类,类型下线为 T。
一个例子是实现 泛型 Number 相加
```
static long sum(List<? extends Number> numbers) {
long summation = 0;
for (Number number : numbers) {
summation += number.longValue();
}
return summation;
}
```
那么 List<Integer>、List<Double> 等,传入 sum 中:
```
List<Integer> myInts = asList(1, 2, 3, 4, 5);
List<Long> myLongs = asList(1L, 2L, 3L, 4L, 5L);
List<Double> myDoubles = asList(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println(sum(myInts));
System.out.println(sum(myLongs));
System.out.println(sum(myDoubles));
```
如果单纯定义为:
```
static long sum(List<Number> numbers) {
long summation = 0;
for (Number number : numbers) {
summation += number.longValue();
}
return summation;
}
```
是没有什么意义的,这时传入 myInts 和 myLongs 会产生编译错误。


```
public static <T> void copy(List<? super T> dest, List<? extends T> src)
```
那么实例化时,比如说 T 是 Number。那么可以将 List<Integer> 拷贝到 List<Number> 甚至 List<Object> 中:
```
List<Integer> myInts = asList(1,2,3,4);
List<Double> myDoubles = asList(3.14, 6.28);
List<Object> myObjs = newArrayList<Object>();
copy(myInts, myObjs);
copy(myDoubles, myObjs);
```

最后谈一下 PECS 原则。如果我们只想从集合中读取元素,那么应该使用协变;如果我们只想向集合中加入元素,那么应该使用逆变,这也被称为 PECS 原则 (Produer Extends, Consumer Super)。
楼主如果感兴趣的话,还可以搜一下 Java 类型系统的协变、逆变看一下
2018-11-17 11:23:33 +08:00
回复了 wqlin 创建的主题 深圳 从上海转战到深圳了
@BangBang #3 好嘞,谢谢哈
2018-11-17 10:57:38 +08:00
回复了 wqlin 创建的主题 深圳 从上海转战到深圳了
@BangBang #1 谢谢哈,就是我走的时候最后一个月工资还没发,应该是等发了之后再去办理吗?
直接交给 HR 吗?缴费明细要自己打印吧
2018-10-28 17:13:58 +08:00
回复了 wqlin 创建的主题 编程 写完了今年(2018)的 6.824 lab 了
@AIdiot 没有碰到过。你可以把那几个文件删了
2018-10-28 15:39:22 +08:00
回复了 wqlin 创建的主题 编程 写完了今年(2018)的 6.824 lab 了
@AIdiot #11 做的是哪一年的? diskvd 和 lockservice 是 15 年的 lab ;
2018-10-27 12:18:47 +08:00
回复了 mayowwwww 创建的主题 Java 请教一个关于数据库事务的问题
@wqlin #7 补一下,mysql 不能处理 lost update 的问题,所以一个办法是使用 #1 提到的 for update 显式的锁住行; PostgreSQL,Oracle 这些可以检查到 Lost update。楼主可以参考下 Designing Data Intensive Application 的 第七章 transaction
2018-10-27 10:42:21 +08:00
回复了 mayowwwww 创建的主题 Java 请教一个关于数据库事务的问题
@mayowwwww #3
抱歉看错了,用 this 也可以。
不过为啥楼主你更新不成功,我试了一下,最后 T1 和 T2 都是 377。这应该算是 Lost Update 吧,一个 transaction 覆盖了另一个 transaction 更新的值。
如果要输出 447,我觉得可以用线程互斥+ Read Committed,一个线程先 commit,然后另一个线程再开启一个 transaction,代码见: https://gist.github.com/wqlin/e957e01fcb40986996b71831a4c45404
在我的电脑上输出为:
```
T1:连接数据库...
T2:连接数据库...
T2:Amount=400
T2:更新成功...|500
T1:Amount=500
T1:更新成功...|600
```
2018-10-26 21:07:18 +08:00
回复了 mayowwwww 创建的主题 Java 请教一个关于数据库事务的问题
RP 保证一个事务读不到另一个事务已经提交的修改。
可以试下 Read Commit,可以读到另一个事务已经提交的修改(没有试过)
另外,楼主的代码应该是:

```
synchronized (MyRunner.class) {
....
}
```
如果用 this,其实两个线程并没有互斥执行
2018-10-26 21:00:48 +08:00
回复了 IsaacYoung 创建的主题 Go 编程语言 菜鸟问一个关于 goroutine 和闭包的问题
@wqlin #1
TestClosure1 也可以改成:
```
func TestClosure1() {

data := []field{{"one"}, {"two"}, {"three"}}

for i := range data {
go data[i].print()
}

time.Sleep(3 * time.Second)
}
```
实现同样的效果
2018-10-26 20:52:58 +08:00
回复了 IsaacYoung 创建的主题 Go 编程语言 菜鸟问一个关于 goroutine 和闭包的问题
首先看 TestClosure2 ; 犯了常见错误,可以参考: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
应该改成:
```
func TestClosure2() {

data := []*field{{"one"}, {"two"}, {"three"}}

for _, v := range data {
go func(v *field){
v.print()
}(v)
}

time.Sleep(3 * time.Second)
}
```
理解了 TestClosure2 之后来看 TestClose1。这里要理解 function receiver ;可以参考: https://tour.golang.org/methods/4。关键是这句话
>
With a value receiver, the Scale method operates on a copy of the original Vertex value. (This is the same behavior as for any other function argument.)
>
所以要实现同样的效果,可以改成:
```
func TestClosure1() {

data := []field{{"one"}, {"two"}, {"three"}}

for _, v := range data {
go func(v field){
v.print()
}(v)
}

time.Sleep(3 * time.Second)
}
```

最后放 playground: https://play.golang.org/p/2C71XfJm2SI
1  2  3  4  5  6  7  8  9  10 ... 13  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5403 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 40ms · UTC 05:58 · PVG 13:58 · LAX 22:58 · JFK 01:58
Developed with CodeLauncher
♥ Do have faith in what you're doing.