郝 玉华

郝 玉华

1656693720

用 Go 解决图问题

在本教程中,我们将学习如何使用 Go 解决图问题。 

在过去的几天里,我一直在观看现场模拟面试,尽管我没有在市场上寻找新工作(我在 Google 很高兴),但让我很感兴趣的是,有这么多人在同一个问题上苦苦挣扎隐藏在一些复杂的装饰品后面。

一个示例模拟问题是这样说的:

想象一下你有图像,你可以复制任何你想要的图像,创建另一个图像。也可以复制新图像(副本),依此类推。新镜像虽然看起来一样,但名称不同,也可以追溯到父镜像。

现在,我们要删除所有图像,但如果图像有重复,我们无法删除它。您必须实现一个函数,该函数返回可以删除图像的顺序。

要实现的函数如下(我们在这篇文章中的所有代码都使用 Go):

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.
}

该函数接收图像列表,以及它们之间的复制操作,然后它必须返回我们必须遵循的顺序以根据上述规则删除所有图像。

让我们看一个例子:

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

这就是说A是原始图像,我们制作了两个副本,B和C。然后我们将B复制到D中。我们的函数的outdeleteOrder应该是[D,B,C,A]或[D, C、B、A] 或 [C、D、B、A]。请注意,可能有多种解决方案,但所有解决方案都是这样,每个图像只有在其副本被删除后才会被删除。

解决问题。

这个问题是一个经典的拓扑排序算法,其中建立了对象之间的某种依赖关系。向模拟面试的候选人提出了具有不同措辞的相同问题,但在所有情况下,问题都可以简化为拓扑排序。

我们在这篇文章中提出的解决方案是这样编写的,以便可以独立解释每个部分。但是,为了时间的缘故,在面试中编写可读性较差的代码是可以接受的。

构建图表

我希望到现在为止,读者可以意识到这是一个图形问题,这反过来应该是向面试官发出的第一个信号,即候选人了解正在发生的事情。

如果我们使用上面的示例构建图形,我们应该得到如下内容:

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

现在,让我们创建一个给定输入的函数,我们可以构建一个可用于解决问题的图形。

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
}

构建图表

请注意,我们首先将所有节点(图像)添加到图中,这很重要,因为可能存在从未复制过的图像,因此它们永远不会处于给定的关系中。然后,我们建立节点之间的依赖关系。

现在,我们可以实现算法的主要部分,拓扑排序。

拓扑排序

拓扑排序是一个简单的 DFS,它使用依赖项作为有向边遍历图并返回相反的顺序。在我们的例子中,我们对依赖的相反顺序感兴趣,因为 A -> B,我们需要先删除 B,然后是 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 在给定初始节点的情况下遍历图。

DFS 在给定初始节点的情况下遍历图,并以相反的顺序返回依赖关系。visited变量跟踪我们在图中已经访问过的节点(不再重复它们),变量跟踪path反向依赖关系。

现在我们有了构建图并遍历它的方法,我们必须立即将所有内容放在一起。

// 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
}

DeletionOrder函数使用给定的输入构建图形,对于尚未访问的每个节点都将dfs执行。该result变量将以正确的删除顺序包含图像名称。

DeleteOrder函数的其余部分(第 14 行及以后)只是确保我们从图像名称中选择图像(在图形算法之外)。

 

大部分算法看起来并不复杂,但很多人都无法解决这个问题,我认为这在 45 分钟的采访中是可行的。我的观察是,大多数人未能足够快地识别该图形问题,从而有时间实施可行的解决方案。

其他注意事项

取决于面试官希望如何看待相同的问题,可以从不同的方向进行处理。

例如,当图有数千个节点时,放大算法的问题是一个有趣的问题。尽管它们可能看起来很简单,但需要考虑一些棘手的情况。

检测给定输入是否正确的问题也可能是一个有趣的问题。为了使图形可排序,从而使拓扑排序正常工作,图形必须没有循环。检测周期并不是一个特别复杂的问题,但大规模进行可能会有点问题。

这些都是有趣的问题,读者应该花点时间思考它们以及每个问题的含义。

最后,在 45 分钟的面试中,只有在正确编码主要问题后,才有时间解决其中的几个问号。但是,我们希望在这篇文章之后,读者可以看到一些问题,并轻松地将它们简化为可以使用拓扑排序解决的问题的图形类别。

 

祝面试顺利。

来源:https ://itnext.io/solving-a-graph-problem-with-go-f1049de33856

#go #graph 

What is GEEK

Buddha Community

用 Go 解决图问题
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 

郝 玉华

郝 玉华

1656693720

用 Go 解决图问题

在本教程中,我们将学习如何使用 Go 解决图问题。 

在过去的几天里,我一直在观看现场模拟面试,尽管我没有在市场上寻找新工作(我在 Google 很高兴),但让我很感兴趣的是,有这么多人在同一个问题上苦苦挣扎隐藏在一些复杂的装饰品后面。

一个示例模拟问题是这样说的:

想象一下你有图像,你可以复制任何你想要的图像,创建另一个图像。也可以复制新图像(副本),依此类推。新镜像虽然看起来一样,但名称不同,也可以追溯到父镜像。

现在,我们要删除所有图像,但如果图像有重复,我们无法删除它。您必须实现一个函数,该函数返回可以删除图像的顺序。

要实现的函数如下(我们在这篇文章中的所有代码都使用 Go):

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.
}

该函数接收图像列表,以及它们之间的复制操作,然后它必须返回我们必须遵循的顺序以根据上述规则删除所有图像。

让我们看一个例子:

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

这就是说A是原始图像,我们制作了两个副本,B和C。然后我们将B复制到D中。我们的函数的outdeleteOrder应该是[D,B,C,A]或[D, C、B、A] 或 [C、D、B、A]。请注意,可能有多种解决方案,但所有解决方案都是这样,每个图像只有在其副本被删除后才会被删除。

解决问题。

这个问题是一个经典的拓扑排序算法,其中建立了对象之间的某种依赖关系。向模拟面试的候选人提出了具有不同措辞的相同问题,但在所有情况下,问题都可以简化为拓扑排序。

我们在这篇文章中提出的解决方案是这样编写的,以便可以独立解释每个部分。但是,为了时间的缘故,在面试中编写可读性较差的代码是可以接受的。

构建图表

我希望到现在为止,读者可以意识到这是一个图形问题,这反过来应该是向面试官发出的第一个信号,即候选人了解正在发生的事情。

如果我们使用上面的示例构建图形,我们应该得到如下内容:

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

现在,让我们创建一个给定输入的函数,我们可以构建一个可用于解决问题的图形。

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
}

构建图表

请注意,我们首先将所有节点(图像)添加到图中,这很重要,因为可能存在从未复制过的图像,因此它们永远不会处于给定的关系中。然后,我们建立节点之间的依赖关系。

现在,我们可以实现算法的主要部分,拓扑排序。

拓扑排序

拓扑排序是一个简单的 DFS,它使用依赖项作为有向边遍历图并返回相反的顺序。在我们的例子中,我们对依赖的相反顺序感兴趣,因为 A -> B,我们需要先删除 B,然后是 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 在给定初始节点的情况下遍历图。

DFS 在给定初始节点的情况下遍历图,并以相反的顺序返回依赖关系。visited变量跟踪我们在图中已经访问过的节点(不再重复它们),变量跟踪path反向依赖关系。

现在我们有了构建图并遍历它的方法,我们必须立即将所有内容放在一起。

// 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
}

DeletionOrder函数使用给定的输入构建图形,对于尚未访问的每个节点都将dfs执行。该result变量将以正确的删除顺序包含图像名称。

DeleteOrder函数的其余部分(第 14 行及以后)只是确保我们从图像名称中选择图像(在图形算法之外)。

 

大部分算法看起来并不复杂,但很多人都无法解决这个问题,我认为这在 45 分钟的采访中是可行的。我的观察是,大多数人未能足够快地识别该图形问题,从而有时间实施可行的解决方案。

其他注意事项

取决于面试官希望如何看待相同的问题,可以从不同的方向进行处理。

例如,当图有数千个节点时,放大算法的问题是一个有趣的问题。尽管它们可能看起来很简单,但需要考虑一些棘手的情况。

检测给定输入是否正确的问题也可能是一个有趣的问题。为了使图形可排序,从而使拓扑排序正常工作,图形必须没有循环。检测周期并不是一个特别复杂的问题,但大规模进行可能会有点问题。

这些都是有趣的问题,读者应该花点时间思考它们以及每个问题的含义。

最后,在 45 分钟的面试中,只有在正确编码主要问题后,才有时间解决其中的几个问号。但是,我们希望在这篇文章之后,读者可以看到一些问题,并轻松地将它们简化为可以使用拓扑排序解决的问题的图形类别。

 

祝面试顺利。

来源:https ://itnext.io/solving-a-graph-problem-with-go-f1049de33856

#go #graph