Go语言学习系列文章目录
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
此系列文章记录我的go语言学习之旅,如果有什么不对之处,还请指出来一起学习。
本系列主要参考学习来源于:
Ultimate go study----------------https://github.com/ardanlabs/gotraining-studyguide
提示:以下是本篇文章正文内容,下面案例可供参考
一、编程语言思想
学习语言最重要的是思想。
- Technology changes quickly but people's minds change slowly.
- Easy to adopt new technology but hard to adopt new ways of thinking.
因此,这五点需要自己反思
- Is it a good program?
- Is it an efficient program?
- Is it correct?
- Was it done on time?
- What did it cost?
另外 :"Code is read many more times than it is written." - Dave Cheney
这个说得太在理了,时刻铭记,养成良好的编码习惯!!!(重要事情说三遍)
思维模式:必须对项目的编程思想了解,否则的话,重构其思想。
coder reviewers:
Integrity : 1. write less code 2.Error Handing
Readability: We must structure our systems to be more comprehensible.
Simplicity
Performance
二、Guidelines
1.Data-Oriented Design
- If you don't understand the data, you don't understand the problem.
- All problems are unique and specific to the data you are working with.
- Data transformations are at the heart of solving problems. Each function, method and work-flow must focus on implementing the specific data transformations required to solve the problems.
- If your data is changing, your problems are changing. When your problems are changing, the data transformations needs to change with it.
- Uncertainty about the data is not a license to guess but a directive to STOP and learn more.
- Solving problems you don't have, creates more problems you now do.
- If performance matters, you must have mechanical sympathy for how the hardware and operating system work.
- Minimize, simplify and REDUCE the amount of code required to solve each problem. Do less work by not wasting effort.
- Code that can be reasoned about and does not hide execution costs can be better understood, debugged and performance tuned.
- Coupling data together and writing code that produces predictable access patterns to the data will be the most performant.
- Changing data layouts can yield more significant performance improvements than changing just the algorithms.
- Efficiency is obtained through algorithms but performance is obtained through data structures and layouts.
2.Interface And Composition Design
- Interfaces give programs structure.
- Interfaces encourage design by composition.
- Interfaces enable and enforce clean divisions between components.
- The standardization of interfaces can set clear and consistent expectations.
- Decoupling means reducing the dependencies between components and the types they use.
- This leads to correctness, quality and performance.
- Interfaces allow you to group concrete types by what they do.
- Don't group types by a common DNA but by a common behavior.
- Everyone can work together when we focus on what we do and not who we are.
- Interfaces help your code decouple itself from change.
- You must do your best to understand what could change and use interfaces to decouple.
- Interfaces with more than one method have more than one reason to change.
- Uncertainty about change is not a license to guess but a directive to STOP and learn more.
- You must distinguish between code that:
- defends against fraud vs protects against accidents
Validation:
Use an interface when:
- users of the API need to provide an implementation detail.
- API’s have multiple implementations they need to maintain internally.
- parts of the API that can change have been identified and require decoupling.
Don't use an interface:
- for the sake of using an interface.
- to generalize an algorithm.
- when users can declare their own interfaces.
- if it's not clear how the interface makes the code better.
3. Package-Oriented Design
Package Oriented Design allows a developer to identify where a package belongs inside a Go project and the design guidelines the package must respect. It defines what a Go project is and how a Go project is structured. Finally, it improves communication between team members and promotes clean package design and project architecture that is discussable.
4.Concurrent Software Design
understand concurrency is not the same as parallelism.
- The application must startup and shutdown with integrity.
- Know how and when every goroutine you create terminates.
- All goroutines you create should terminate before main returns.
- Applications should be capable of shutting down on demand, even under load, in a controlled way.
- You want to stop accepting new requests and finish the requests you have (load shedding).
- Identify and monitor critical points of back pressure that can exist inside your application.
- Channels, mutexes and atomic functions can create back pressure when goroutines are required to wait.
- A little back pressure is good, it means there is a good balance of concerns.
- A lot of back pressure is bad, it means things are imbalanced.
- Back pressure that is imbalanced will cause:
- Failures inside the software and across the entire platform.
- Your application to collapse, implode or freeze.
- Measuring back pressure is a way to measure the health of the application.
- Rate limit to prevent overwhelming back pressure inside your application.
- Every system has a breaking point, you must know what it is for your application.
- Applications should reject new requests as early as possible once they are overloaded.
- Don’t take in more work than you can reasonably work on at a time.
- Push back when you are at critical mass. Create your own external back pressure.
- Use an external system for rate limiting when it is reasonable and practical.
- Use timeouts to release the back pressure inside your application.
- No request or task is allowed to take forever.
- Identify how long users are willing to wait.
- Higher-level calls should tell lower-level calls how long they have to run.
- At the top level, the user should decide how long they are willing to wait.
- Use the
Context
package.- Functions that users wait for should take a
Context
.- These functions should select on <-ctx.Done() when they would otherwise block indefinitely.
- Set a timeout on a
Context
only when you have good reason to expect that a function's execution has a real time limit. - Allow the upstream caller to decide when the
Context
should be canceled. - Cancel a
Context
whenever the user abandons or explicitly aborts a call.
- Functions that users wait for should take a
- Architect applications to:
- Identify problems when they are happening.
- Stop the bleeding.
- Return the system back to a normal state.
5. Channel Design
Depending on the problem you are solving, you may require different channel semantics. Depending on the semantics you need, different architectural choices must be taken.
- If any given Send on a channel
CAN
cause the sending goroutine to block:- Be careful with Buffered channels larger than 1.
- Buffers larger than 1 must have reason/measurements.
- Must know what happens when the sending goroutine blocks.
- Be careful with Buffered channels larger than 1.
- If any given Send on a channel
WON'T
cause the sending goroutine to block:- You have the exact number of buffers for each send.
- Fan Out pattern
- You have the buffer measured for max capacity.
- Drop pattern
- You have the exact number of buffers for each send.
- Less is more with buffers.
- Don’t think about performance when thinking about buffers.
- Buffers can help to reduce blocking latency between signaling.
- Reducing blocking latency towards zero does not necessarily mean better throughput.
- If a buffer of one is giving you good enough throughput then keep it.
- Question buffers that are larger than one and measure for size.
- Find the smallest buffer possible that provides good enough throughput.
总结
这篇文章主要学习一下编程思想,大牛们可以不看,稍有点基础的初级程序员可以认真看一下,编程思想能决定你以后编程的上线。