图片和文字同时上传解析问题(关键在于数据在body体里面)

回复

有问必答小张的烦恼 发起了问题 • 1 人关注 • 0 个回复 • 69 次浏览 • 2 天前 • 来自相关话题

markdown

站点反馈suc 发表了文章 • 0 个评论 • 65 次浏览 • 3 天前 • 来自相关话题

mark

mark

mark


mark

济南活动

线下活动suc 发表了文章 • 0 个评论 • 52 次浏览 • 3 天前 • 来自相关话题

济南 4.30

济南
4.30

beego orm 中 表字段怎么设置 字段注释???

回复

有问必答hlj2722 发起了问题 • 1 人关注 • 0 个回复 • 111 次浏览 • 6 天前 • 来自相关话题

惊奇发现,[个性网址]变成只接受4~20位的了,那我现在3位的岂不是得好好珍惜

回复

站点反馈Thomas 发起了问题 • 1 人关注 • 0 个回复 • 117 次浏览 • 2017-04-17 12:01 • 来自相关话题

beego orm.insertMulti插入后,对象id没有像insert那样给对象加上

回复

有问必答luischan 发起了问题 • 1 人关注 • 0 个回复 • 107 次浏览 • 2017-04-12 12:09 • 来自相关话题

Go之旅-for循环

文章分享frankphper 发表了文章 • 0 个评论 • 184 次浏览 • 2017-04-09 22:51 • 来自相关话题

Go语言仅有for一种循环语句,但常用方式都能支持。其中初始化表达式支持函数调用或定义局部变量,需要注意的是初始化语句中的函数仅执行一次,条件表达式中的函数重复执行,规避方式就是在初始化表达式中定义局部变量保存函数返回结果。Go语言中也有goto语句,使... 查看全部

Go语言仅有for一种循环语句,但常用方式都能支持。其中初始化表达式支持函数调用或定义局部变量,需要注意的是初始化语句中的函数仅执行一次,条件表达式中的函数重复执行,规避方式就是在初始化表达式中定义局部变量保存函数返回结果。Go语言中也有goto语句,使用goto语句前,必须先定义标签,标签区分大小写,并且未使用的标签会引发编译错误。和goto定点跳转不同,break、continue用于中断代码块执行。break用于switch、for、select语句,终止整个语句块执行,continue仅用于for循环,终止后续逻辑,立即进入下一轮循环。break和continue配合标签使用,可以在多层嵌套中指定目标层级。



package main

import (
"fmt"
)

// count函数
func count() int {
fmt.Println("count.") // 打印字符串用来查看count函数执行次数
return 3
}

// main函数
func main() {
// for循环
// 初始化表达式,支持函数调用或定义局部变量
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// 类似while循环
i := 0
for i < 10 {
fmt.Println(i)
i++
}
// 类似无限循环
for {
break
}
// 初始化语句中的count函数仅执行一次
for i, c := 0, count(); i < c; i++ {
fmt.Println("a", i)
}

c := 0
// 条件表达式中的count函数重复执行
for c < count() {
fmt.Println("b", c)
c++
}
// 规避条件表达式中的count函数重复执行,在初始化表达式中定义局部变量保存count函数返回结果
count := count()
d := 0
for d < count {
fmt.Println("c", d)
d++
}
// goto定点跳转
// 须先定义标签,并且未用到的标签会引发编译错误
// 不能跳转到其它函数,或内层代码块内
for i := 0; i < 10; i++ {
fmt.Println(i)
if i > 5 {
goto exit
}
}
exit:
fmt.Println("exit.")

// break 用户switch、for、select语句,终止整个语句块执行。continue 仅用于for循环,终止后续逻辑,立即进入下一轮循环
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // 立即进入下一轮循环
}
if i > 5 {
break // 立即终止整个for循环
}
fmt.Println(i)
}
// 配合标签,break和continue可在多层嵌套中指定目标层级
outer:
for i := 0; i < 5; i++ {
for j := 0; j < 10; j++ {
if j > 2 {
fmt.Println()
continue outer
}

if i > 2 {
break outer
}
fmt.Print(i, ":", j, " ")
}
}

}

nsq 源码中的疑问

回复

有问必答fzbing 发起了问题 • 2 人关注 • 0 个回复 • 214 次浏览 • 2017-03-31 17:24 • 来自相关话题

分享一个小工具 Boast:如何从服务端跟踪所有 HTTP 请求,并方便回放?

开源程序dcb9 发表了文章 • 0 个评论 • 183 次浏览 • 2017-03-31 16:17 • 来自相关话题

原文链接:http://blog.phpor.me/note/2017/03/31/track-and-replay-http-request.html
客户端工程师:“xxx 接口坏了,我的程序都没动过”,后端经常会收到这样的质问,但是我们现在如何重现这个问题?有以下几种情况:


一、后端测试了一下发现没有问题


“我这里测试了是好的啊”,就只能让客户端工程师再操作一遍,亲眼看到错误之后就肯定是有问题了,就得去找问题,这时候这台手机,以及这台手机里面的数据都非常重要,因为这些数据可以让 Bug 重现。


二、测试了也有问题


这时候后端就去修改程序了,但是每一次的测试是否有问题都需要在客户端中操作,有时候的操作非常的复杂,在这上面花的时间会比较多。最后使了各种神通才终于找到问题,原来是这个用户的某某数据有异常才会出现这种情况。


以上这种情况屡见不鲜,最麻烦的点就在于,每次都要以出现 Bug 的相同参数去请求,有时候你知道这些请求的参数,可以把它们放到 Postman 这种工具里面,但大部分时候你并不知道它对应的参数 (token)


如果我们可以在服务端跟踪所有的请求:接口地址,Header,Body,后端返回的 Header、Body,这样我们就能查到对应的请求参数和返回值,可以直接填到 Postman 里面,要是还能一键重新请求就好了,因为我们不想修改请求的参数,只是想再以相同的参数请求一遍,这样我们来调试对应的程序。


正好以前用过 ngrok,发现它有一个非常好的 debug 界面,可以达到以上的要求,但现在不需要它的内网穿透功能,于是只能自己写一个程序,只包含以下功能:



  • 记录接口所有的 Request 和 Response

  • 可以一键重新请求某个 Request


基本工作原理


HTTP 客户端                   Boast                       Web 服务器
| GET http://localhost:8080/ | 记录请求并进行反向代理 | Response 200 OK
| ---------------------------> | --------------------------> | ------┐
| | | |
| | 记录返回信息并转发给客户端 | <----┘
| <--------------------------- | <-------------------------- |

┌----------------------------------------------------------------------------┐
| url: http://localhost:8081 |
| ---------------------------------------------------------------------------|
| All Transactions ┌ - - - - - - - - - - - - - - - - - - - - - - - ┐ |
| ---------------------- | time: 10 hours ago Client: 127.0.0.1 | |
| |GET / 200 OK 100 ms | | | |
| ---------------------- | Request [ Replay ] | |
| | - - - - - - - - - - - - | |
| | GET http://localhost/ HTTP/1.1 | |
| | User-Agent: curl/7.51.0 | |
| | Accept: */* | |
| | | |
| | Response | |
| | - - - - - - - - - - - - | |
| | HTTP/1.1 200 OK | |
| | X-Server: HTTPLab | |
| | Date: Thu, 02 Mar 2017 02:25:27 GMT | |
| | Content-Length: 13 | |
| | Content-Type: text/plain; charset=utf-8 | |
| | | |
| | Hello, World | |
| └ - - - - - - - - - - - - - - - - - - - - - - - ┘ |
| |
└----------------------------------------------------------------------------┘

最近正在学习 Go,正好拿它来完成这个小程序,取名为 Boast 为了让我们在重现 Bug 上更为主动和方便,以及更快地修复,好多花点时间来造轮子!


Boast 项目地址


Go 和前端都是现学现卖,欢迎大家拍砖。

聊天服务器玩具

文章分享elvin5 发表了文章 • 0 个评论 • 195 次浏览 • 2017-03-31 12:49 • 来自相关话题

Server

文件:main.go
package main

import (
    "log"
)

func init() {
    log.SetFl... 			查看全部
					

Server


文件:main.go
package main

import (
"log"
)

func init() {
log.SetFlags(log.Lshortfile)
}

var (
addr = ":7001"
)

func main() {
log.Println("running on:", addr)
err := NewServer(addr).Listen()
if nil != err {
log.Fatal(err)
}
}

文件:server.go
package main

import (
"bufio"
"log"
"net"
"strings"
)

type Server struct {
addr string
}

func NewServer(addr string) *Server {
return &Server{addr}
}

func (s *Server) Listen() error {
l, err := net.Listen("tcp", s.addr)
if nil != err {
log.Fatalln(err)
}

for {
conn, err := l.Accept()
if nil != err {
log.Println(err)
return err
}
log.Println("one client came")

session, err := s.handleLogin(conn)
if nil != err {
log.Println(err)
return err
}
session.Start()
}

return nil
}

func (s *Server) handleLogin(conn net.Conn) (*Session, error) {
userName, err := bufio.NewReader(conn).ReadString('\n')
if nil != err {
log.Println(err)
return nil, err
}

_, err = conn.Write([]byte("hi " + userName))
if nil != err {
log.Println(err)
return nil, err
}

session := &Session{
UserName: strings.TrimRight(userName, "\n"),
Conn: conn,
}

defaultSessionManager.AddSession(session)

return session, nil
}

文件:session_manager.go
package main

var (
defaultSessionManager = &SessionManager{
Sessions: map[string]*Session{},
}
)

type SessionManager struct {
Sessions map[string]*Session
}

func (sm *SessionManager) AddSession(s *Session) {
sm.Sessions[s.UserName] = s
}

func (sm *SessionManager) GetSession(userName string) *Session {
return sm.Sessions[userName]
}

文件:session.go
package main

import (
"bufio"
"log"
"net"
"strings"
)

type Session struct {
Conn net.Conn
UserName string
}

func NewSession(name string, conn net.Conn) *Session {
return &Session{
Conn: conn,
UserName: name,
}
}

func (s *Session) Start() {
go s.readloop()
}

func (s *Session) Send(b []byte) (int, error) {
return s.Conn.Write(b)
}

func (s *Session) Read(b []byte) (int, error) {
return s.Conn.Read(b)
}

func (s *Session) readloop() {
reader := bufio.NewReader(s.Conn)
for {
rec, err := reader.ReadString('\n')
if nil != err {
log.Println(err)
return
}
baz := strings.Split(rec, "#")
if 2 != len(baz) {
log.Println("wrong msg format")
return
}

userName := baz[0]
msg := baz[1]

_, err = defaultSessionManager.GetSession(userName).Send([]byte(s.UserName + ": " + msg))
if nil != err {
log.Println(err)
return
}
}
}

Client


文件:client.go

package main

import (
"bufio"
"fmt"
"log"
"net"
"os"
)

func init() {
log.SetFlags(log.Lshortfile)
}

type Client struct {
addr string
Conn net.Conn
}

func NewClient(addr string) *Client {
return &Client{addr: addr}
}

func (s *Client) Run() {
conn, err := net.Dial("tcp", s.addr)
if nil != err {
log.Fatalln(err)
}
s.Conn = conn

err = s.login()
if nil != err {
log.Fatal(err)
}

go s.writeloop()
s.readloop()
}

func (s *Client) login() error {
_, err := s.Conn.Write([]byte(*userName + "\n"))
if nil != err {
log.Println(err)
return err
}

return nil
}
func (s *Client) readloop() error {
for {
bin := make([]byte, 10, 10)
n, err := s.Conn.Read(bin)
if nil != err {
log.Println(err)

err = s.Conn.Close()
if nil != err {
log.Println(err)
return err
}

return err
}
fmt.Print(string(bin[:n]))
}

return nil
}
func (s *Client) writeloop() error {
reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if nil != err {
log.Println(err)
return err
}

_, err = s.Conn.Write([]byte(input))
if nil != err {
log.Println(err)
err = s.Conn.Close()
if nil != err {
log.Println(err)
return err
}

return err
}
}

return nil
}

文件:main.go

package main

import (
"flag"
"log"
)

var (
addr = ":7001"
)

var (
userName = flag.String("name", "", "user name")
)

func init() {
flag.Parse()
}

func main() {
if "" == *userName {
log.Fatal("input your name")
}
NewClient(addr).Run()
}

https://github.com/elvin-du/dim

GopherChina大会门票多了一张,早鸟票, 原价转手, 要的联系

回复

技术讨论wanghe4096 发起了问题 • 1 人关注 • 0 个回复 • 194 次浏览 • 2017-03-30 14:40 • 来自相关话题

golang interface浅谈

技术讨论themoonstone 发表了文章 • 0 个评论 • 256 次浏览 • 2017-03-30 09:16 • 来自相关话题

golang 的接口设计是这门编程语言的两大亮点之一,本文仅浅谈golang接口和其它语言(以C++为例)的区别。 引用《Go语言编程》作者在书中的话,go语言中的接口是“非侵入式”的,而其它语言中的接口是“侵入式”的。因此,需要对非侵入式和侵入式分别理... 查看全部

golang 的接口设计是这门编程语言的两大亮点之一,本文仅浅谈golang接口和其它语言(以C++为例)的区别。
引用《Go语言编程》作者在书中的话,go语言中的接口是“非侵入式”的,而其它语言中的接口是“侵入式”的。因此,需要对非侵入式和侵入式分别理解才能理解清楚golang 接口的优点
首先 让我们看看C++中的接口:
在C++中,接口的实现必须要通过继承


interface IFoo{
void Bar();
}

class Foo: public IFoo
{}

IFoo *Foo=new IFoo;

在此类语言中 即使另外有一个接口IFoo2实现了与IFoo完全一样的接口方法,甚至名字相同只不过位于不同的名字空间下,编译器也会认为上面的类Foo只实现了IFoo的接口,而没有实现IFoo2的接口
此类接口称为侵入式接口。“侵入式”的主要表现是实现类必须明确表示自己实现了某个接口。在C++里面表示为需要继承。
举一个具体的实例:


#include <iostream>
using namespace std;

class Person
{
public:
Person():m_strName("###"){};
virtual void SetName(const string name)=0;
private:
string m_strName;
};

class Person2
{
public:
Person2():m_strName("###"){};
virtual void SetName(const string name)=0;
private:
string m_strName;
};

class Student:public Person
{
public:
Student():m_strName("***"){};
void SetName(const string name);
private:
string m_strName;
};

void Student::SetName(const string name){
std::cout << m_strName << std::endl;
m_strName=name;
std::cout << m_strName << std::endl;
}

int main() {
Student s;
Person *p;
p=&s;
Person2 *p2;
p2=&s;
return 0;
}

在这里 因为Student没有声明继承Person2 所以 针对 p2=$s;这段代码 会出现:“cannot convert Struden* to Person2 in assignment”这样的错误。
而在GO语言中,一个类只要实现了该接口所有的函数,就代表这个类实现了该接口


type file struct{}
func(f *File) Read(buf []byte)(n int, err error)
func(f *File) Write(buf []byte)(n int, err error)
func(f *File) Seek(off int64, err eror)(pos int, err error)
func(f *File) Close() err error

type IFile interface{
Read(buf []byte)(n int, err error)
Write(buf []byte)(n int, err error)
Seek(off int64, err eror)(pos int, err error)
Close() err error
}

type IReader interface
{
Read(buf []byte)(n int, err error)
}
type IWriter interface
{
Write(buf []byte)(n int, err error)
}
type ICloser interface
{
Close() err error
}

尽管file类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是file实现了这些接口的所有方法,就可以说file类实现了这些接口,可以进行赋值
其实我们可以用一个通俗的例子来进行一下说明:
对于侵入式接口,假设你在参加高考,但不是全国统考,而是高校自主命题,此时有X大学和Y大学两所学校,他们的考试题目是完全相同的,录取分数也是完全相同的,但就算你参加了X大学的考试,达到了X大学的分数线,你也不能申请就读Y大学,要想申请Y大学,你必须再次参加Y大学的考试并达到Y大学的分数线,这里的参加考试并达到分数线就相当于C++中的继承,如果没有声明继承,就不能说明实现了某个接口
而对于非侵入式接口,同样是高考,但这次是全国统考,你考过了分数线,这个时候 你既能申请X大学,又能申请Y大学,因为你达到了这两所大学所要求的统一分数,相当于你实现了X和Y两个接口里的所有方法,所以既能调用X 又能调用Y
综上,侵入式接口和非侵入式接口区别的关键在于是否需要明确声明你的类实现了某个接口。
以上仅代表个人理解,对于不对的或者不恰当的地方,欢迎批评和指正。

升级 mac os 10.12.4 后 beego 跑不起来了

回复

有问必答uuapp 发起了问题 • 1 人关注 • 0 个回复 • 262 次浏览 • 2017-03-28 17:09 • 来自相关话题

北京/10年老厂招聘GO高级工程师(营销大数据企业,年内上市)

回复

招聘应聘mikerr 发起了问题 • 2 人关注 • 0 个回复 • 357 次浏览 • 2017-03-23 14:27 • 来自相关话题

beego1.8的文档还没更新么?

回复

开源程序kaixinmao 发起了问题 • 1 人关注 • 0 个回复 • 260 次浏览 • 2017-03-23 10:31 • 来自相关话题