mirror of
https://github.com/golang/go
synced 2024-11-22 21:00:04 -07:00
396 lines
11 KiB
HTML
396 lines
11 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||
|
<head>
|
||
|
<title>Go Tech Talk</title>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="font-size-adjustment" content="-1" />
|
||
|
<link rel="stylesheet" href="slidy.css"
|
||
|
type="text/css" media="screen, projection, print" />
|
||
|
<script src="slidy.js" type="text/javascript">
|
||
|
</script>
|
||
|
</head>
|
||
|
<body>
|
||
|
<!-- this defines the slide background -->
|
||
|
|
||
|
<div class="background">
|
||
|
|
||
|
<div class="header">
|
||
|
<!-- sized and colored via CSS -->
|
||
|
</div>
|
||
|
|
||
|
<div class="footer"></div>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide titlepage">
|
||
|
<br/>
|
||
|
<br/>
|
||
|
<img src="../go-logo-white.png" width="588px" height="217px">
|
||
|
<br/>
|
||
|
<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1>
|
||
|
<div style="color: #ffcc00;">
|
||
|
<br/>
|
||
|
<h3>Sydney University<br/><br/>March 23, 2010</h3>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Go</h1>
|
||
|
|
||
|
<h2>New</h2>
|
||
|
<h2>Experimental</h2>
|
||
|
<h2>Concurrent</h2>
|
||
|
<h2>Garbage Collected</h2>
|
||
|
<h2>Systems Language</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Hello, world</h1>
|
||
|
<pre>
|
||
|
package main
|
||
|
|
||
|
import "fmt"
|
||
|
|
||
|
func main() {
|
||
|
fmt.Printf("Hello, 世界\n")
|
||
|
}
|
||
|
</pre>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Hello, world 2.0</h1>
|
||
|
|
||
|
<h2>Serving <a href="http://localhost:8080/world">http://localhost:8080/world</a></h2>
|
||
|
<pre>
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"http"
|
||
|
)
|
||
|
|
||
|
func handler(c *http.Conn, r *http.Request) {
|
||
|
fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:])
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
http.ListenAndServe(":8080",
|
||
|
http.HandlerFunc(handler))
|
||
|
}
|
||
|
</pre>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>New</h1>
|
||
|
|
||
|
<h2>It's about two years old:</h2>
|
||
|
<ul>
|
||
|
<li>Design started in late 2007</li>
|
||
|
<li>Implementation starting to work mid-2008</li>
|
||
|
<li>Released as an open source project in November 2009</li>
|
||
|
<li>Development continues with an active community</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Why invent a new language? Older languages weren't designed for concurrency, but modern software needs it:</h2>
|
||
|
<ul>
|
||
|
<li>Large scale, networked computing, such as Google web search</li>
|
||
|
<li>Multi-core hardware</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>New</h1>
|
||
|
|
||
|
<h2>Older languages are also frustrating on a day-to-day basis</h2>
|
||
|
<h2>Statically-typed languages (C, C++, Java) have issues:</h2>
|
||
|
<ul>
|
||
|
<li>Edit-Compile-Run cycle takes far too long</li>
|
||
|
<li>Type hierarchy can hurt as much as it helps</li>
|
||
|
</ul>
|
||
|
<div style="text-align:center">
|
||
|
<img src="java-typing.png" width="800px" height="90px"><br>
|
||
|
</div>
|
||
|
|
||
|
<h2>Dynamic languages (Python, JavaScript) fix some issues but introduce others:</h2>
|
||
|
<ul>
|
||
|
<li>No compilation means slow code</li>
|
||
|
<li>Runtime errors that should be caught statically</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Go has the lighter feel of a scripting language but is compiled</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>New</h1>
|
||
|
|
||
|
<h2>Large C++ programs (e.g. Firefox, OpenOffice, Chromium) have enormous build times:</h2>
|
||
|
<ul>
|
||
|
<li>XKCD's #1 Programmer Excuse for Legitimately Slacking Off: "<a href="http://xkcd.com/303/">My Code's Compiling</a>"</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>On a Mac (OS X 10.5.8, gcc 4.0.1):</h2>
|
||
|
<ul>
|
||
|
<li>C: <code>#include <stdio.h></code> reads 360 lines from 9 files</li>
|
||
|
<li>C++: <code>#include <iostream></code> reads 25,326 lines from 131 files</li>
|
||
|
<li>Objective-C: <code>#include <Carbon/Carbon.h></code> reads 124,730 lines from 689 files</li>
|
||
|
<li>We haven't done any real work yet!</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>In Go: <code>import "fmt"</code> reads <i>one</i> file: 184 lines summarizing 7 packages</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>New</h1>
|
||
|
|
||
|
<h2>Compilation demo</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Experimental</h1>
|
||
|
|
||
|
<h2>Go is still unproven</h2>
|
||
|
<h2>Language is still evolving</h2>
|
||
|
<h2>Package library is incomplete</h2>
|
||
|
<h2>Concurrent garbage collection is an active research problem</h2>
|
||
|
<h2>Reviving forgotten concepts:</h2>
|
||
|
<ul>
|
||
|
<li>Go's concurrency is strongly influenced by <i>Communicating Sequential Processes</i> (Hoare, 1978)</li>
|
||
|
<li>Go has types and interfaces, but no inheritance. It is arguably more object-oriented than previously mentioned languages, being closer to the original Smalltalk meaning (1970s)</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>Unix philosophy: write <i>programs</i> that do one thing and do it well</h2>
|
||
|
<h2>Connect them with <i>pipes</i>:</h2>
|
||
|
<ul>
|
||
|
<li>How many lines of test code are there in the Go standard library?</li>
|
||
|
<li><code>find ~/go/src/pkg | grep _test.go$ | xargs wc -l</code></li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Unlike other languages, Go makes it easy to:</h2>
|
||
|
<ul>
|
||
|
<li>Launch <i>goroutines</i></li>
|
||
|
<li>Connect them with <i>channels</i></li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>Start a new flow of control with the <code>go</code> keyword</h2>
|
||
|
<h2>Parallel computation is easy:</h2>
|
||
|
<pre>
|
||
|
func main() {
|
||
|
go expensiveComputation(x, y, z)
|
||
|
anotherExpensiveComputation(a, b, c)
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<h2>Roughly speaking, a goroutine is like a thread, but lighter weight:</h2>
|
||
|
<ul>
|
||
|
<li>Goroutines have segmented stacks, and typically smaller stacks</li>
|
||
|
<li>This requires compiler support. Goroutines can't just be a C++ library on top of a thread library</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>Consider web servers ("the C10k problem"):</h2>
|
||
|
<ul>
|
||
|
<li>"Thread per connection" approach is conceptually neat, but doesn't scale well in practice</li>
|
||
|
<li>What does scale well (event-driven callbacks, asynchronous APIs) are harder to understand, maintain, and debug</li>
|
||
|
<li>We think "goroutine per connection" can scale well, and is conceptually neat</li>
|
||
|
</ul>
|
||
|
<pre>
|
||
|
for {
|
||
|
rw := socket.Accept()
|
||
|
conn := newConn(rw, handler)
|
||
|
go conn.serve()
|
||
|
}
|
||
|
</pre>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>Let's look again at our simple parallel computation:</h2>
|
||
|
<pre>
|
||
|
func main() {
|
||
|
go expensiveComputation(x, y, z)
|
||
|
anotherExpensiveComputation(a, b, c)
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
<h2>This story is incomplete:</h2>
|
||
|
<ul>
|
||
|
<li>How do we know when the two computations are done?</li>
|
||
|
<li>What are their values?</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>Goroutines communicate with other goroutines via channels</h2>
|
||
|
<pre>
|
||
|
func computeAndSend(ch chan int, x, y, z int) {
|
||
|
ch <- expensiveComputation(x, y, z)
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
ch := make(chan int)
|
||
|
go computeAndSend(ch, x, y, z)
|
||
|
v2 := anotherExpensiveComputation(a, b, c)
|
||
|
v1 := <-ch
|
||
|
fmt.Println(v1, v2)
|
||
|
}
|
||
|
</pre>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Concurrent</h1>
|
||
|
|
||
|
<h2>In traditional concurrent programs, you <i>communicate by sharing memory</i>. In Go, you <i>share memory by communicating</i>:</h2>
|
||
|
<ul>
|
||
|
<li>Communication (the <code><-</code> operator) is sharing and synchronization</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Threads and locks are concurrency primitives; CSP is a concurrency model:</h2>
|
||
|
<ul>
|
||
|
<li>Analogy: "Go To Statement Considered Harmful" (Dijsktra, 1968)</li>
|
||
|
<li><code>goto</code> is a control flow primitive; structured programming (<code>if</code> statements, <code>for</code> loops, function calls) is a control flow model</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Learning CSP changes the way you think about concurrent programming:</h2>
|
||
|
<ul>
|
||
|
<li>Every language has its grain. If your Go program uses mutexes, you're probably working against the grain</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Garbage Collected</h1>
|
||
|
|
||
|
<h2>Automatic memory management makes writing (and maintaining) programs easier</h2>
|
||
|
<h2>Especially in a concurrent world:</h2>
|
||
|
<ul>
|
||
|
<li>Who "owns" a shared piece of memory, and is responsible for destroying it?</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Large C++ programs usually end up with semi-automatic memory management anyway, via "smart pointers"</h2>
|
||
|
<h2>Mixing the two models can be problematic:</h2>
|
||
|
<ul>
|
||
|
<li>Browsers can leak memory easily; DOM elements are C++ objects, but JavaScript is garbage collected</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Garbage Collected</h1>
|
||
|
|
||
|
<h2>Go is also a safer language:</h2>
|
||
|
<ul>
|
||
|
<li>Pointers but no pointer arithmetic</li>
|
||
|
<li>No dangling pointers</li>
|
||
|
<li>Variables are zero-initialized</li>
|
||
|
<li>Array access is bounds-checked</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>No buffer overflow exploits</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Systems Language</h1>
|
||
|
|
||
|
<h2>This just means you could write decently large programs in Go:</h2>
|
||
|
<ul>
|
||
|
<li>Web servers</li>
|
||
|
<li>Web browsers</li>
|
||
|
<li>Web crawlers</li>
|
||
|
<li>Search indexers</li>
|
||
|
<li>Databases</li>
|
||
|
<li>Word processors</li>
|
||
|
<li>Integrated Development Environments (IDEs)</li>
|
||
|
<li>Operating systems</li>
|
||
|
<li>...</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Systems Language</h1>
|
||
|
|
||
|
<h2>Garbage collection has a reputation for being "slower"</h2>
|
||
|
<h2>We're expecting Go to be slightly slower than optimized C, but faster than Java, depending on the task. Nonetheless:</h2>
|
||
|
<ul>
|
||
|
<li>Fast and buggy is worse than almost-as-fast and correct</li>
|
||
|
<li>It is easier to optimize a correct program than to correct an optimized program</li>
|
||
|
<li>Fundamentally, it's simply a trade-off we're willing to make</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Memory layout can drastically affect performance. These two designs are equivalent in Go, but significantly different in Java:</h2>
|
||
|
<pre>
|
||
|
type Point struct { X, Y int }
|
||
|
type Rect struct { P0, P1 Point }
|
||
|
|
||
|
// or ...
|
||
|
|
||
|
type Rect struct { X0, Y0, X1, Y1 int }
|
||
|
</pre>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Systems Language</h1>
|
||
|
|
||
|
<h2>Quote from http://loadcode.blogspot.com/2009/12/go-vs-java.html</h2>
|
||
|
|
||
|
<h2>
|
||
|
"[Git] is known to be very fast. It is written in C. A Java version
|
||
|
JGit was made. It was considerably slower. Handling of memory and lack
|
||
|
of unsigned types was some of the important reasons.
|
||
|
</h2>
|
||
|
|
||
|
<h2>Shawn O. Pearce wrote on the git mailinglist:</h2>
|
||
|
<ul><li>"JGit struggles with not
|
||
|
having an efficient way to represent a SHA-1. C can just say "unsigned
|
||
|
char[20]" and have it inline into the container's memory allocation. A
|
||
|
byte[20] in Java will cost an *additional* 16 bytes of memory, and be
|
||
|
slower to access because the bytes themselves are in a different area
|
||
|
of memory from the container object. We try to work around it by
|
||
|
converting from a byte[20] to 5 ints, but that costs us machine
|
||
|
instructions"
|
||
|
</li></ul>
|
||
|
|
||
|
<h2>
|
||
|
Like C, Go does allow unsigned types and defining data structures
|
||
|
containing other data structures as continuous blocks of memory."
|
||
|
</h2>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide">
|
||
|
<h1>Go</h1>
|
||
|
|
||
|
<h2>New</h2>
|
||
|
<h2>Experimental</h2>
|
||
|
<h2>Concurrent</h2>
|
||
|
<h2>Garbage Collected</h2>
|
||
|
<h2>Systems Language</h2>
|
||
|
|
||
|
<h2>And more:</h2>
|
||
|
<ul>
|
||
|
<li>I haven't talked about the type system, interfaces, slices, closures, selects, ...</li>
|
||
|
<li>Tutorial, documentation, mailing list, source code all online</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="slide titlepage">
|
||
|
<h1>Questions?</h1>
|
||
|
<br><br>
|
||
|
<center>
|
||
|
<img src="../gordon/bumper640x360.png" width="640px" height="360px">
|
||
|
</center>
|
||
|
</div>
|
||
|
|
||
|
</body></html>
|