V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  index90  ›  全部回复第 9 页 / 共 26 页
回复总数  520
1 ... 5  6  7  8  9  10  11  12  13  14 ... 26  
2020-03-04 18:53:16 +08:00
回复了 yujianwjj 创建的主题 Go 编程语言 go slice 的一个疑问
你把 slice 类型看作是一个大概这样子的 struct
type Slice struct {
len int
mem *unsafe.Pointer
... other info
}
函数参数是值传递,就是把 s 复制了一遍到 a
其实 a 和 s 只是用了同一个内存指针,其他都是独立的
2020-02-27 11:22:15 +08:00
回复了 v2410117 创建的主题 程序员 被小公司培养成了"全栈"工程师,不好找工作了.
背题+1
2020-02-09 12:16:43 +08:00
回复了 hcyg 创建的主题 Go 编程语言 Go map[int]转[]string 的问题 很神奇
Make 的时候你只设了容量,没有设长度
KPI 和 OKR 其实都是目标管理工具,最直观的区别是,前者和工资挂钩,后者只是和你“谈谈人生谈谈理想”。
“KPI 督促每个人快速解决问题”
这是对的,帮助大家专注于目标
“不考虑问题的深度以及重复性和潜在的风险“
这锅不应该由 KPI 来背,KPI 只是工具,KPI 的内容是人定的
“怎么破才好”
制定 KPI 的时候和管理者谈谈,或者坚定按照 KPI 字面执行
2020-01-21 11:13:44 +08:00
回复了 zhangH258 创建的主题 程序员 过年想给 70 多岁的外婆买个智能机方便视频,求推荐
昨晚给奶奶买了台 note8
#6 的代码不对,send header 应该在 send body 之前。
http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) {
var reader io.Reader
//{
// file, err := os.Open("")
// if err != nil {
// writer.WriteHeader( http.StatusNotFound)
// return
// }
// reader = file
// defer file.Close()
//}
{
resp, err := http.Client{}.Get("")
if err != nil {
writer.WriteHeader( http.StatusNotFound)
return
}
reader = resp.Body
}
writer.Header().Set("content-type", "text/plain")
_, _ = io.Copy(writer, reader)
return
})
如果你不是读取本地文件,而是从别人的请求中转发数据,你留意一下 http.Response 的 body 是已经实现了 reader interface,只需要从 reader copy 数据到 writer 就可以了。

面向接口编程,你需要什么接口,去找对应的实现就可以了。
http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) {
file, err := os.Open("")
if err != nil {
writer.WriteHeader(404)
return
}
defer file.Close()
if _, err := io.Copy(writer, file); err != nil {
writer.WriteHeader(500)
return
}
writer.Header().Set("content-type", "text/plain")
writer.WriteHeader(200)
})
我猜,这是 LZ 看到的:
jsonObject -> sendRequest(jsonObject) -> client -> server -> handleRequest(jsonObject)

LZ 对 request body 签名的理解:
jsonObject -> sign(encode(jsonObject)) -> sendRequest(jsonObject) -> client -> server -> handleRequest(jsonObject) -> verify(encode(jsonObject), sign)

但实际上是:
jsonObject -> sendRequest(jsonObject) -> body = encode(jsonObject) -> post(body) -> client -> server -> recv(body) -> jsonObject = decode(body) -> handleRequest(jsonObject)

对 request body 签名的正确理解:
jsonObject -> sign(encode(jsonObject)) -> sendRequest(encode(jsonObject)) -> client -> server -> handleRequest(jsonString) -> verify(jsonString, sign)

@LinJunzhu 我尽力了
既然你上来是找答案的,别人已经给了你经过实践验证的答案,那就先实践,遇到问题再提问。你都没解决方案了,你还没试过别人给的方案就忙于反驳,这是真的如你提问中所说,想看看别人怎么做的么?
@chenqh 对,有些地方叫 appid,有些地方叫 clientid
@LinJunzhu
注意这一行:“Content-MD5: ……, 等同于对 body 数据的 md5sum”(简单理解,payload 实际上时一个 byte 数组,可以直接求 md5 )

劝你先忘掉微信 API 那个方案,它那个场景很有可能是因为安全原因,网关过滤了 header 和 query 的自定义字段,导致 signature 只能放在 body 中。

如果你还是坚持按照微信 API 那种模式,有个笨方法,就是把你要传递的 content 对象序列化后,当作字符串参数看待,即在原来的 body 上再包多一层:
{
content: string // "{\"key\":\"value\"}"
appid: string
sign: string
}
@fkdog lz 的需求其实是身份认证,是想知道这个请求是谁发出的,并且要有数字签名证明。
https 解决不了 C 公司冒充 A 公司向 B 公司发起转账申请,除非你启用 tls 的双向验证,这时候需要给每个请求方发放 client 证书,服务端还需要实现从证书中提取请求方 ID,才知道是谁发起的请求,实现难度比数字签名大一点。
给一个我正在使用的方案:

Signature = HMAC-SHA1( '您的 SecretKey', UTF-8-Encoding-Of( $StringToSign ) ) );

StringToSign = $HTTP-Verb + "\n" +
$URL + "\n" +
$Query + "\n" +
$Content-Type + "\n" +
$Content-MD5 + "\n" +
$Date + "\n" +
$AccessKey;

HTTP-Verb: 指 HTTP 请求方法如, GET, POST, PUT, DELETE
URL: 指所访问的资源路径如, /your/resource/path
Query: 指请求中的 Query 参数, 其构成规则如下:
对参数 key 进行升序排序
对于所有参数以 key+value 方式串联
Content-Type: 请求 Header 中的 Content-Type 值
Content-MD5: 请求 Header 中的 Content-MD5 值, 等同于对 body 数据的 md5sum
Date: 整形, 请求发生时的时间戳(用于防重放的,不需要可省略)
AccessKey: 用户自己的 AccessKey

最后在 request header 中增加:
x-singnature: $Signature
x-accesskey: $AccessKey
x-date: $Date
@LinJunzhu 你发的那个是链接我看了,人家之所以这样做,是因为把 signature 放在了 body 中传送,可能由于他们协议的要求不能在 query 参数或者 header 中存放额外字段。

如果你们没有这种限制,最好的办法是把 signature 放在 header 中( aws 就是这样做),签名时针对 body 进行签名。这样做得好处是,api 网关做签名校验时,不需要反序列化,性能更高,更通用,无论什么 content 类型都支持。
你签名的目的是保证 request 的 body 不被篡改,至于 body 的 content-type 是什么没有关系。
直接对 request 的 body 进行签名就好了。

我猜 lz 主要是把 json 字符串和 json 对象搞混了,json 对象是具体语言对 json 字符串的面向对象表达方式。
http request 的 payload 实际上只能是一个 byte 数组,你之所以觉得会有 json value,other value 之分,是因为你所使用的库抽象封装了。查看源码你会发现,json 对象是需要 encode 成 json 字符串,才放进 request payload 里面。

回到问题,lz 应该自行对 json 对象进行 encode,并对 json 字符串进行签名,你所使用的库应该提供 set raw payload 的方法。
引申问题,lz 你对 http 协议的理解可能还只停留在你所使用的库层面上,建议你还是更仔细学一下 http 协议。
2020-01-16 20:10:18 +08:00
回复了 Renco 创建的主题 Java 关于分布式系统中的并发问题
跟分布式系统没多大关系吧
即使你是单点的也会有并发问题啊
例如,我用同一个账号同时下了两个单
例如,我消费的同时对账号进行充值
对共享数据(余额)进行并发读写,要注意的是脏读脏写问题
2020-01-16 18:08:24 +08:00
回复了 PixelMage 创建的主题 程序员 [讨论] 在业务系统中写了 e2e 测试,还需要写单元测试吗?
@PixelMage sorry,我看了前半句没看后半句,误解了你的意思。

感觉我们的讨论有点跑偏,e2e 测试和单元测试其实是处在不同维度,解决的具体问题是不一样的,不能用来直接比较,不是一个非零即一的问题。

单元测试是验证代码逻辑问题,而不是验证业务逻辑问题。
相反,e2e 测试只能保证业务逻辑正确,但无法保证代码或软件是健壮的。(或者需要很大代价)
2020-01-16 17:17:25 +08:00
回复了 PixelMage 创建的主题 程序员 [讨论] 在业务系统中写了 e2e 测试,还需要写单元测试吗?
@PixelMage 要找 repo 的话,可以上 github 上找,我看得比较多是 dgraph 和 k8s 的 repo (跟工作有关)。
哦对了,我是 Gopher,Java 不是很熟,不过根据经验,标准库里面的例子就足够学了,我相信 Java 的标准库应该也有单元测试的。

关于你最后一点“但是在日常的业务系统开发中,而不是伟大软件开发中,经常会出现为了开发速度牺牲质量的 tradeoff”,我想还是分享一下我的经历。(这里的质量,我理解的是程序是否有 bug,而不是代码优不优雅的问题)

其实刚开始我们也是觉得写单元测试浪费时间,如果把开发活动框在从研发到打包这段过程的话,单元测试的确是影响了开发进度的。但是如果你把软件的发布,运营,bug 反馈,定位,修复,再发布这些环节考虑进来,你会崩溃掉的。

“为了开发速度牺牲质量”,其实到了最后我们发现这是个伪命题来的,因为软件质量是第一位的。如果软件万一真的有 bug,即使不考虑业务损失,当这个 bug 出现的时候,你需要马上放下手上正在开发的特性,去排查定位,重建环境,代码修复,测试,打包,发布等,这一系列的工作牵扯到的不只是写出这个 bug 的那一位研发人员,而是牵扯到运维,测试等一系列人员。将人力成本,时间成本,沟通成本等考虑进来之后,其实整个团队的研发效能非常低的。

当然,如果一个研发人员和一个测试人员合作无间,测试能够在出现 bug 的时候,就直接告诉研发人员是哪个模块甚至哪一行出问题了,这种分工也是没问题的,但是我没见过。语言沟通有效率本来就够低了,更何况现在研发和测试都不在一个办公室里,用 IM 发着文字沟通,又或者在看板上发评论来沟通 bug。

“为了开发速度牺牲质量”这种观念很普遍,我猜是因为大部分研发人员都是个体在工作,容易把自己的职责框在写代码到代码提交之间。但当你开始关心整个研发团队的效能上时,你很容易发现问题。
1 ... 5  6  7  8  9  10  11  12  13  14 ... 26  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2403 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 30ms · UTC 16:06 · PVG 00:06 · LAX 09:06 · JFK 12:06
Developed with CodeLauncher
♥ Do have faith in what you're doing.