Hong  Nhung

Hong Nhung

1656693840

Giải Quyết Vấn Đề Đồ Thị Với Go

Trong hướng dẫn này, chúng ta sẽ học cách giải quyết vấn đề về đồ thị với cờ vây. 

Trong vài ngày qua, tôi đã xem trực tiếp các cuộc phỏng vấn chế giễu và mặc dù tôi không tham gia thị trường cho một công việc mới (tôi rất hạnh phúc tại Google), tôi thấy rất thú vị khi có rất nhiều người phải vật lộn với cùng một vấn đề. ẩn sau một số trang điểm phức tạp.

Một trong những câu hỏi mô phỏng ví dụ đã nói điều gì đó như thế này:

Hãy tưởng tượng bạn có hình ảnh và bạn có thể sao chép bất kỳ hình ảnh nào bạn muốn, tạo ra một hình ảnh khác. Hình ảnh mới (bản sao) cũng có thể được sao chép, v.v. Mặc dù hình ảnh mới trông giống nhau, tên khác nhau và bạn cũng có thể theo dõi nó trở lại hình ảnh gốc.

Bây giờ, chúng tôi muốn xóa tất cả các hình ảnh, nhưng chúng tôi không thể xóa một hình ảnh nếu nó có các bản sao. Bạn phải triển khai một hàm trả về thứ tự xóa các hình ảnh.

Hàm để triển khai như sau (chúng tôi đang sử dụng Go cho tất cả mã trong bài đăng này):

func deleteOrder(imgs []*Image, cps []*CPOps) []*Image {...}

type Image struct {
  Name string
}// CPOps represent a copy operation. 
type CPOps struct {
  ParentImage *Image //Original images being copied. 
  CpImages []*Image  //Copies of the original image.
}

Hàm nhận một danh sách các hình ảnh, và các thao tác sao chép giữa chúng, sau đó nó phải trả về thứ tự mà chúng ta phải tuân theo để xóa tất cả các hình ảnh dựa trên quy tắc trên.

Hãy xem một ví dụ:

Images = [A, B, C, D]
CPOps = [
  {ParentImage:A, CPImages:[B, C]},
  {ParentImage:B, CPImages:[D]},
]

Điều này nói rằng A là hình ảnh gốc, và chúng tôi đã tạo hai bản sao, B và C. Sau đó, chúng tôi tạo một bản sao của B thành D. Phần ngoài chức năng của chúng tôi deleteOrderphải là [D, B, C, A] hoặc [D, C, B, A] hoặc [C, D, B, A]. Lưu ý rằng có thể có nhiều giải pháp, nhưng tất cả chúng đều như vậy là mọi hình ảnh chỉ bị xóa sau khi các bản sao của nó bị xóa.

Giải quyết vấn đề.

Bài toán này là một thuật toán sắp xếp theo cấu trúc liên kết cổ điển trong đó một số loại phụ thuộc giữa các đối tượng được thiết lập. Cùng một vấn đề với cách viết khác cũng được đưa ra cho các ứng viên của các cuộc phỏng vấn giả, nhưng trong mọi trường hợp, vấn đề có thể được rút gọn thành Sắp xếp theo cấu trúc liên kết.

Giải pháp mà chúng tôi trình bày trong bài đăng này được viết để mỗi phần có thể được giải thích một cách độc lập. Tuy nhiên, trong một cuộc phỏng vấn được chấp nhận để viết một đoạn mã ít đọc hơn vì lợi ích của thời gian.

Xây dựng đồ thị

Tôi hy vọng rằng bây giờ, người đọc có thể nhận ra đây là một vấn đề về đồ thị, do đó, đây sẽ là tín hiệu đầu tiên cho người phỏng vấn rằng ứng viên hiểu những gì đang diễn ra.

Nếu chúng ta xây dựng biểu đồ bằng cách sử dụng mẫu ở trên, chúng ta sẽ nhận được một cái gì đó như:

A --> B --> D
 \  
  --> C

Bây giờ, hãy tạo một hàm cho đầu vào, chúng ta có thể xây dựng một đồ thị có thể được sử dụng để giải quyết vấn đề.

type Graph map[string][]string

func buildGraph(imgs []*Image, copos []*CPOps) Graph {
	graph := make(Graph)

	// Add all images to the graph.
	for _, img := range imgs {
		if _, ok := graph[img.Name]; !ok {
			graph[img.Name] = []string{}
		}
	}

	// Add dependencies between images.
	for _, cp := range cpops {
		if _, ok := graph[cp.ParentImage.Name]; !ok {
			graph[cp.ParentImage.Name] = []string{}
		}
		for _, child := range cp.CPImages {
			graph[cp.ParentImage.Name] = append(graph[cp.ParentImage.Name], child.Name)
		}
	}

	return graph
}

Xây dựng đồ thị

Lưu ý rằng chúng tôi đang thêm tất cả các nút (hình ảnh) vào biểu đồ trước tiên, điều này rất quan trọng vì có thể có những hình ảnh chưa bao giờ được sao chép, do đó, chúng sẽ không bao giờ nằm ​​trong các quan hệ đã cho. Sau đó, chúng tôi thiết lập sự phụ thuộc giữa các nút.

Bây giờ, chúng ta có thể triển khai phần chính của thuật toán, Sắp xếp theo cấu trúc liên kết.

Sắp xếp theo cấu trúc liên kết

Sắp xếp tôpô là một DFS đơn giản duyệt qua đồ thị bằng cách sử dụng các phụ thuộc là các cạnh có hướng và trả về thứ tự ngược lại. Trong trường hợp của chúng tôi, chúng tôi quan tâm đến thứ tự đảo ngược của các phụ thuộc kể từ A -> B, chúng tôi cần xóa B trước, sau đó A.

func dfs(n string, graph Graph, visited map[string]bool, path []string) []string {
	for _, child := range graph[n] {
		if _, ok := visited[child]; ok {
			continue
		}
		visited[child] = true
		path = dfs(child, graph, visited, path)
	}
	return append(path, n)
}

DFS để duyệt qua đồ thị đã cho một nút ban đầu.

DFS duyệt qua đồ thị đã cho một nút ban đầu và trả về các phụ thuộc theo thứ tự đảo ngược. Biến visitedtheo dõi các nút mà chúng ta đã truy cập trong biểu đồ (để không lặp lại chúng) và biến paththeo dõi các phụ thuộc được đảo ngược.

Bây giờ chúng ta có một cách để xây dựng biểu đồ và duyệt qua nó, chúng ta phải kết hợp mọi thứ lại với nhau cùng một lúc.

// DeletionOrder returns the order the images should be deleted. 
func DeletionOrder((imgs []*Image, cps []*CPOps) []*Image {
	graph := buildGraph(imgs, cps)

	visited := map[string]bool{}
	result := []string{}
	for k := range graph {
		if _, ok := visited[k]; !ok {
			visited[k] = true
			result = dfs(k, graph, visited, result)
		}
	}

	imgsMap := map[string]*Image{}
	for _, img := range imgs {
		imgsMap[img.Name] = img
	}
	imgsOrder := []*Image{}
	for _, name := range result {
		imgsOrder = append(imgsOrder, imgsMap[name])
	}
	return imgsOrder
}

Hàm DeletionOrderxây dựng biểu đồ với đầu vào đã cho, đối với mỗi nút chưa được truy cập, hàm dfssẽ được thực thi. Biến resultsẽ chứa các tên ảnh theo đúng thứ tự xóa.

Phần còn lại của DeleteOrderhàm (dòng 14 trở lên) chỉ là đảm bảo rằng chúng ta chọn ảnh từ tên ảnh (bên ngoài thuật toán đồ thị).

 

Phần lớn thuật toán trông không phức tạp như vậy, nhưng có rất nhiều người không giải được bài toán này, theo ý kiến ​​của tôi là có thể thực hiện được trong một cuộc phỏng vấn 45 phút. Quan sát của tôi là hầu hết mọi người không xác định được vấn đề biểu đồ đó đủ nhanh để có thời gian thực hiện một giải pháp hiệu quả.

Những ý kiến ​​khác

Cùng một vấn đề có thể được đưa ra theo nhiều hướng khác nhau tùy thuộc vào cách người phỏng vấn muốn nhìn nhận vấn đề đó.

Ví dụ, câu hỏi về việc mở rộng thuật toán, khi biểu đồ có hàng nghìn nút, là một câu hỏi thú vị. Mặc dù chúng có thể trông đơn giản, nhưng có một số trường hợp phức tạp cần được xem xét.

Vấn đề phát hiện xem đầu vào đã cho có đúng hay không cũng có thể là một vấn đề thú vị. Để đồ thị có thể sắp xếp được, do đó sắp xếp tôpô hoạt động chính xác, đồ thị không được có chu trình. Việc phát hiện các chu kỳ không phải là một vấn đề đặc biệt phức tạp, nhưng thực hiện nó trên quy mô lớn có thể là một vấn đề khó khăn hơn một chút.

Đây là những câu hỏi thú vị và người đọc nên dành một chút thời gian để suy nghĩ về chúng và ý nghĩa của từng câu hỏi.

Cuối cùng, trong một cuộc phỏng vấn kéo dài 45 phút, chỉ có thời gian trống để giải một vài dấu hỏi trong số này sau khi vấn đề chính đã được mã hóa chính xác. Tuy nhiên, chúng tôi hy vọng rằng sau bài đăng này, người đọc có thể xem xét một số vấn đề và dễ dàng rút gọn chúng thành loại biểu đồ các vấn đề có thể giải được bằng cách sử dụng sắp xếp tôpô.

 

Chúc bạn may mắn khi phỏng vấn.

Nguồn: https://itnext.io/solving-a-graph-problem-with-go-f1049de33856

#go #graph 

What is GEEK

Buddha Community

Giải Quyết Vấn Đề Đồ Thị Với Go
Hong  Nhung

Hong Nhung

1656693840

Giải Quyết Vấn Đề Đồ Thị Với Go

Trong hướng dẫn này, chúng ta sẽ học cách giải quyết vấn đề về đồ thị với cờ vây. 

Trong vài ngày qua, tôi đã xem trực tiếp các cuộc phỏng vấn chế giễu và mặc dù tôi không tham gia thị trường cho một công việc mới (tôi rất hạnh phúc tại Google), tôi thấy rất thú vị khi có rất nhiều người phải vật lộn với cùng một vấn đề. ẩn sau một số trang điểm phức tạp.

Một trong những câu hỏi mô phỏng ví dụ đã nói điều gì đó như thế này:

Hãy tưởng tượng bạn có hình ảnh và bạn có thể sao chép bất kỳ hình ảnh nào bạn muốn, tạo ra một hình ảnh khác. Hình ảnh mới (bản sao) cũng có thể được sao chép, v.v. Mặc dù hình ảnh mới trông giống nhau, tên khác nhau và bạn cũng có thể theo dõi nó trở lại hình ảnh gốc.

Bây giờ, chúng tôi muốn xóa tất cả các hình ảnh, nhưng chúng tôi không thể xóa một hình ảnh nếu nó có các bản sao. Bạn phải triển khai một hàm trả về thứ tự xóa các hình ảnh.

Hàm để triển khai như sau (chúng tôi đang sử dụng Go cho tất cả mã trong bài đăng này):

func deleteOrder(imgs []*Image, cps []*CPOps) []*Image {...}

type Image struct {
  Name string
}// CPOps represent a copy operation. 
type CPOps struct {
  ParentImage *Image //Original images being copied. 
  CpImages []*Image  //Copies of the original image.
}

Hàm nhận một danh sách các hình ảnh, và các thao tác sao chép giữa chúng, sau đó nó phải trả về thứ tự mà chúng ta phải tuân theo để xóa tất cả các hình ảnh dựa trên quy tắc trên.

Hãy xem một ví dụ:

Images = [A, B, C, D]
CPOps = [
  {ParentImage:A, CPImages:[B, C]},
  {ParentImage:B, CPImages:[D]},
]

Điều này nói rằng A là hình ảnh gốc, và chúng tôi đã tạo hai bản sao, B và C. Sau đó, chúng tôi tạo một bản sao của B thành D. Phần ngoài chức năng của chúng tôi deleteOrderphải là [D, B, C, A] hoặc [D, C, B, A] hoặc [C, D, B, A]. Lưu ý rằng có thể có nhiều giải pháp, nhưng tất cả chúng đều như vậy là mọi hình ảnh chỉ bị xóa sau khi các bản sao của nó bị xóa.

Giải quyết vấn đề.

Bài toán này là một thuật toán sắp xếp theo cấu trúc liên kết cổ điển trong đó một số loại phụ thuộc giữa các đối tượng được thiết lập. Cùng một vấn đề với cách viết khác cũng được đưa ra cho các ứng viên của các cuộc phỏng vấn giả, nhưng trong mọi trường hợp, vấn đề có thể được rút gọn thành Sắp xếp theo cấu trúc liên kết.

Giải pháp mà chúng tôi trình bày trong bài đăng này được viết để mỗi phần có thể được giải thích một cách độc lập. Tuy nhiên, trong một cuộc phỏng vấn được chấp nhận để viết một đoạn mã ít đọc hơn vì lợi ích của thời gian.

Xây dựng đồ thị

Tôi hy vọng rằng bây giờ, người đọc có thể nhận ra đây là một vấn đề về đồ thị, do đó, đây sẽ là tín hiệu đầu tiên cho người phỏng vấn rằng ứng viên hiểu những gì đang diễn ra.

Nếu chúng ta xây dựng biểu đồ bằng cách sử dụng mẫu ở trên, chúng ta sẽ nhận được một cái gì đó như:

A --> B --> D
 \  
  --> C

Bây giờ, hãy tạo một hàm cho đầu vào, chúng ta có thể xây dựng một đồ thị có thể được sử dụng để giải quyết vấn đề.

type Graph map[string][]string

func buildGraph(imgs []*Image, copos []*CPOps) Graph {
	graph := make(Graph)

	// Add all images to the graph.
	for _, img := range imgs {
		if _, ok := graph[img.Name]; !ok {
			graph[img.Name] = []string{}
		}
	}

	// Add dependencies between images.
	for _, cp := range cpops {
		if _, ok := graph[cp.ParentImage.Name]; !ok {
			graph[cp.ParentImage.Name] = []string{}
		}
		for _, child := range cp.CPImages {
			graph[cp.ParentImage.Name] = append(graph[cp.ParentImage.Name], child.Name)
		}
	}

	return graph
}

Xây dựng đồ thị

Lưu ý rằng chúng tôi đang thêm tất cả các nút (hình ảnh) vào biểu đồ trước tiên, điều này rất quan trọng vì có thể có những hình ảnh chưa bao giờ được sao chép, do đó, chúng sẽ không bao giờ nằm ​​trong các quan hệ đã cho. Sau đó, chúng tôi thiết lập sự phụ thuộc giữa các nút.

Bây giờ, chúng ta có thể triển khai phần chính của thuật toán, Sắp xếp theo cấu trúc liên kết.

Sắp xếp theo cấu trúc liên kết

Sắp xếp tôpô là một DFS đơn giản duyệt qua đồ thị bằng cách sử dụng các phụ thuộc là các cạnh có hướng và trả về thứ tự ngược lại. Trong trường hợp của chúng tôi, chúng tôi quan tâm đến thứ tự đảo ngược của các phụ thuộc kể từ A -> B, chúng tôi cần xóa B trước, sau đó A.

func dfs(n string, graph Graph, visited map[string]bool, path []string) []string {
	for _, child := range graph[n] {
		if _, ok := visited[child]; ok {
			continue
		}
		visited[child] = true
		path = dfs(child, graph, visited, path)
	}
	return append(path, n)
}

DFS để duyệt qua đồ thị đã cho một nút ban đầu.

DFS duyệt qua đồ thị đã cho một nút ban đầu và trả về các phụ thuộc theo thứ tự đảo ngược. Biến visitedtheo dõi các nút mà chúng ta đã truy cập trong biểu đồ (để không lặp lại chúng) và biến paththeo dõi các phụ thuộc được đảo ngược.

Bây giờ chúng ta có một cách để xây dựng biểu đồ và duyệt qua nó, chúng ta phải kết hợp mọi thứ lại với nhau cùng một lúc.

// DeletionOrder returns the order the images should be deleted. 
func DeletionOrder((imgs []*Image, cps []*CPOps) []*Image {
	graph := buildGraph(imgs, cps)

	visited := map[string]bool{}
	result := []string{}
	for k := range graph {
		if _, ok := visited[k]; !ok {
			visited[k] = true
			result = dfs(k, graph, visited, result)
		}
	}

	imgsMap := map[string]*Image{}
	for _, img := range imgs {
		imgsMap[img.Name] = img
	}
	imgsOrder := []*Image{}
	for _, name := range result {
		imgsOrder = append(imgsOrder, imgsMap[name])
	}
	return imgsOrder
}

Hàm DeletionOrderxây dựng biểu đồ với đầu vào đã cho, đối với mỗi nút chưa được truy cập, hàm dfssẽ được thực thi. Biến resultsẽ chứa các tên ảnh theo đúng thứ tự xóa.

Phần còn lại của DeleteOrderhàm (dòng 14 trở lên) chỉ là đảm bảo rằng chúng ta chọn ảnh từ tên ảnh (bên ngoài thuật toán đồ thị).

 

Phần lớn thuật toán trông không phức tạp như vậy, nhưng có rất nhiều người không giải được bài toán này, theo ý kiến ​​của tôi là có thể thực hiện được trong một cuộc phỏng vấn 45 phút. Quan sát của tôi là hầu hết mọi người không xác định được vấn đề biểu đồ đó đủ nhanh để có thời gian thực hiện một giải pháp hiệu quả.

Những ý kiến ​​khác

Cùng một vấn đề có thể được đưa ra theo nhiều hướng khác nhau tùy thuộc vào cách người phỏng vấn muốn nhìn nhận vấn đề đó.

Ví dụ, câu hỏi về việc mở rộng thuật toán, khi biểu đồ có hàng nghìn nút, là một câu hỏi thú vị. Mặc dù chúng có thể trông đơn giản, nhưng có một số trường hợp phức tạp cần được xem xét.

Vấn đề phát hiện xem đầu vào đã cho có đúng hay không cũng có thể là một vấn đề thú vị. Để đồ thị có thể sắp xếp được, do đó sắp xếp tôpô hoạt động chính xác, đồ thị không được có chu trình. Việc phát hiện các chu kỳ không phải là một vấn đề đặc biệt phức tạp, nhưng thực hiện nó trên quy mô lớn có thể là một vấn đề khó khăn hơn một chút.

Đây là những câu hỏi thú vị và người đọc nên dành một chút thời gian để suy nghĩ về chúng và ý nghĩa của từng câu hỏi.

Cuối cùng, trong một cuộc phỏng vấn kéo dài 45 phút, chỉ có thời gian trống để giải một vài dấu hỏi trong số này sau khi vấn đề chính đã được mã hóa chính xác. Tuy nhiên, chúng tôi hy vọng rằng sau bài đăng này, người đọc có thể xem xét một số vấn đề và dễ dàng rút gọn chúng thành loại biểu đồ các vấn đề có thể giải được bằng cách sử dụng sắp xếp tôpô.

 

Chúc bạn may mắn khi phỏng vấn.

Nguồn: https://itnext.io/solving-a-graph-problem-with-go-f1049de33856

#go #graph 

Fannie  Zemlak

Fannie Zemlak

1599854400

What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features

Zander  Herzog

Zander Herzog

1596793260

Secure HTTPS servers in Go

In this article, we are going to look at some of the basic APIs of the http package to create and initialize HTTPS servers in Go.

Image for post

(source: unsplash.com)

In the “Simple Hello World Server” lesson, we learned about net/http package, how to create routes and how [ServeMux](https://golang.org/pkg/net/http/#ServeMux) works. In the “Running multiple HTTP servers” lesson, we learned about [Server](https://golang.org/pkg/net/http/#Server) structure and how to run multiple HTTP servers concurrently.

In this lesson, we are going to create an HTTPS server using both Go’s standard server configuration and custom configuration (using [_Server_](https://golang.org/pkg/net/http/#Server) structure). But before this, we need to know what HTTPS really is?

HTTPS is a big topic of discussion in itself. Hence while writing this lesson, I published an article just on “How HTTPS works?”. I advise you to read this lesson first before continuing this article. In this article, I’ve also described the encryption paradigm and SSL certificates generation process.


If we recall the simplest HTTP server example from previous lessons, we only need http.``[ListenAndServe](https://golang.org/pkg/net/http/#ListenAndServe) function to start an HTTP server and http.``[HandleFunc](https://golang.org/pkg/net/http/#HandleFunc) to register a response handler for a particular endpoint.

Image for post

(https://play.golang.org/p/t3sOenOYAzS)

In the example above, when we run the command go run server.go , it will start an HTTP server on port 9000. By visiting http://localhost:9000 URL in a browser, you will be able to see a Hello World! message on the screen.

Image for post

(http://localhost:9000)

As we know, the nil argument to ListenAndServe() call invokes Go to use the [DefaultServeMux](https://golang.org/pkg/net/http/#DefaultServeMux) response multiplexer, which is the default instance of ServeMux structure provided globally by the Go. The HandleFunc() call adds a response handler for a specific route on the multiplexer instance.

The http.ListenAndServe() call uses the Go’s standard HTTP server configuration, however, in the previous lesson, how we can customize a server using [Server](https://golang.org/pkg/net/http/#Server) structure type.

To start an HTTPS server, all we need do is to call ServerAndListenTLS method with some configuration. Just like ServeAndListen method, this method is available on both the http package and the Server structure.

The http.``[ServeAndListenTLS](https://golang.org/pkg/net/http/#ListenAndServeTLS) method uses the Go’s standard server implementation, however, both [Server](https://golang.org/pkg/net/http/#Server) instance and Server.``[ServeAndListenTLS](https://golang.org/pkg/net/http/#Server.ListenAndServeTLS) method can be configured for our needs.

#go-programming-language #go #golang-tutorial #go-programming #golang

Go-web-workshop: Build Web Applications with Go on App Engine

Building Web Applications with Go

Welcome, gopher! You're not a gopher? Well, this workshop is for gophers, or people that use the Go programming language. But fear not if you've never written any Go before! I'd recommend you learn the basics for the language first with the Go tour.

This workshop has been run a couple of times with an instructor leading. The goal of this repo is to make it as easy as possible for individuals to follow the content by themselves. If you get stuck at any point, feel free to file issues asking questions.

Setting up your workspace

To go through this you will need the following:

  1. You have installed the Go Programming Language.
  2. You have set up a GOPATH by following the How to Write Go Code tutorial.
  3. You are somewhat familiar with the basics of Go. (The Go Tour is a pretty good place to start)
  4. You have a Google account and you have installed the Google Cloud SDK.

Contents

There's a lot to say about how to build web applications, in Go or any other language. But we only have one day so we won't try to cover too much. Instead we'll cover the basics, so you'll be able to explore other solutions and frameworks later.

The workshops is divided in eleven sections:

Resources

These are places where you can find more information for Go:

My favorite aspect of Go is its community, and you are now part of it too. Welcome!

As a newcomer to the Go community you might have questions or get blocked at some point. This is completely normal, and we're here to help you. Some of the places where gophers tend to hang out are:

Disclaimer

This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

Author: Campoy
Source Code: https://github.com/campoy/go-web-workshop 
License: Apache-2.0 license

#go #golang #web 

Elian  Harber

Elian Harber

1654604760

Go-callvis: Visualize Call Graph Of A Go Program using Graphviz

go-callvis

go-callvis is a development tool to help visualize call graph of a Go program using interactive view.


Introduction

The purpose of this tool is to provide developers with a visual overview of a Go program using data from call graph and its relations with packages and types. This is especially useful in larger projects where the complexity of the code much higher or when you are just simply trying to understand code of somebody else.

Features

  • 🆕 support for Go modules! :boom:
  • focus specific package in the program
  • click on package to quickly switch the focus using interactive viewer
  • group functions by package and/or methods by type
  • filter packages to specific import path prefixes
  • ignore funcs from standard library
  • omit various types of function calls

Output preview

main

Check out the source code for the above image.

How it works

It runs pointer analysis to construct the call graph of the program and uses the data to generate output in dot format, which can be rendered with Graphviz tools.

Reference guide

Here you can find descriptions for various types of output.

Packages / Types

RepresentsStyle
focusedblue color
stdlibgreen color
otheryellow color

Functions / Methods

RepresentsStyle
exportedbold border
unexportednormal border
anonymousdotted border

Calls

RepresentsStyle
internalblack color
externalbrown color
staticsolid line
dynamicdashed line
regularsimple arrow
concurrentarrow with circle
deferredarrow with diamond

Quick start

Requirements

  • Go 1.13+
  • Graphviz (optional, required only with -graphviz flag)

Installation

go get -u github.com/ofabry/go-callvis
# or
git clone https://github.com/ofabry/go-callvis.git
cd go-callvis && make install

Usage

Interactive viewer

To use the interactive view provided by a web server that serves SVG images of focused packages, you can simply run:

go-callvis <target package>

HTTP server is listening on http://localhost:7878/ by default, use option -http="ADDR:PORT" to change HTTP server address.

Render static output

To generate a single output file use option -file=<file path> to choose output file destination.

The output format defaults to svg, use option -format=<svg|png|jpg|...> to pick a different output format.

Options

Usage of go-callvis:
  -debug
        Enable verbose log.
  -file string
        output filename - omit to use server mode
  -cacheDir string
        Enable caching to avoid unnecessary re-rendering.
  -focus string
        Focus specific package using name or import path. (default "main")
  -format string
        output file format [svg | png | jpg | ...] (default "svg")
  -graphviz
        Use Graphviz's dot program to render images.
  -group string
        Grouping functions by packages and/or types [pkg, type] (separated by comma) (default "pkg")
  -http string
        HTTP service address. (default ":7878")
  -ignore string
        Ignore package paths containing given prefixes (separated by comma)
  -include string
        Include package paths with given prefixes (separated by comma)
  -limit string
        Limit package paths to given prefixes (separated by comma)
  -minlen uint
        Minimum edge length (for wider output). (default 2)
  -nodesep float
        Minimum space between two adjacent nodes in the same rank (for taller output). (default 0.35)
  -nointer
        Omit calls to unexported functions.
  -nostd
        Omit calls to/from packages in standard library.
  -rankdir
        Direction of graph layout [LR | RL | TB | BT] (default "LR")
  -skipbrowser
        Skip opening browser.
  -tags build tags
        a list of build tags to consider satisfied during the build. For more information about build tags, see the description of build constraints in the documentation for the go/build package
  -tests
        Include test code.
  -version
        Show version and exit.

Run go-callvis -h to list all supported options.

Examples

Here is an example for the project syncthing.

syncthing example

Check out more examples and used command options.

Community

Join #go-callvis channel at gophers.slack.com. (not a member yet? get invitation)

How to help

Did you find any bugs or have some suggestions?

  • Feel free to open new issue or start discussion in the slack channel.

Do you want to contribute to the project?

  • Fork the repository and open a pull request. Here you can find TODO features.

Roadmap

The interactive tool described below has been published as a separate project called goexplorer!

Ideal goal of this project is to make web app that would locally store the call graph data and then provide quick access of the call graphs for any package of your dependency tree. At first it would show an interactive map of overall dependencies between packages and then by selecting particular package it would show the call graph and provide various options to alter the output dynamically.

Author: Ofabry
Source Code: https://github.com/ofabry/go-callvis 
License: MIT license

#go #golang #visualization