├── .contributors
├── .githooks
└── post-merge
│ └── update-contributors
├── .github
└── workflows
│ └── BuildPDF.yml
├── .gitignore
├── Contributor.md
├── LANGS.md
├── LICENSE
├── README.md
├── _config.yml
├── book.json
├── en
├── Before-start.md
├── Start.md
└── Useful-Websites-to-Learn-How-to-Code-Quickly.md
├── package.json
└── zh
├── Before-start.md
├── Contribute-to-an-open-source-project.md
├── Contributor.md
├── Create-an-open-source-project.md
├── FAQ.md
├── Hello-world.md
├── Join-the-group.md
├── Modify-the-open-source-project.md
├── README.md
├── Read-more.md
├── SUMMARY.md
├── Select-an-open-source-project.md
├── Start.md
├── Understanding-the-source-code.md
├── Useful-Websites-to-Learn-How-to-Code-Quickly.md
└── images
├── 2048-1.png
├── 2048-2.png
├── 2048-3.png
├── 2048-4.png
├── 9-useful-CodeCademy.jpg
├── 9-useful-LifeHacker.jpg
├── 9-useful-TeamTreeHouse.jpg
├── 9-useful-codingBat.jpg
├── 9-useful-hackety.jpg
├── 9-useful-jqueryAir.jpg
├── 9-useful-keybr.png
├── 9-useful-mongodb.jpg
├── 9-useful-phpKnowHow.jpg
├── 9-useful-rubyMonk.jpg
├── 9-useful-学堂在线.png
├── debug-NetBeans-IDE-7.0.png
├── debug.png
├── keyboard.jpg
└── pyramid.jpg
/.contributors:
--------------------------------------------------------------------------------
1 | dirname: "."
2 | tryGithub: true
3 | write: false
4 | ask: false
5 | format: "template"
6 | fields: "name,github"
7 | template: [
8 | '''
9 | | Contributor Name | Github |
10 | | --------------- | ------ |
11 |
12 | '''
13 | '''
14 | | ${contributor.name} | ${contributor.github ? "[" + contributor.github + "](https://github.com/" + contributor.github + ")" : "-"} |
15 |
16 | '''
17 | ]
18 | users:
19 | zhuangbiaowei:
20 | name: "BiaoWei Zhuang"
21 | email: [
22 | "zhuangbiaowei@gmail.com"
23 | "zhuangbiaowei@huawei.com"
24 | ]
25 | github: "zhuangbiaowei"
26 | riceball:
27 | name: "Riceball LEE"
28 | email: "snowyu.lee@gmail.com"
29 | github: "snowyu"
30 | "mzlogin@github":
31 | name: "Zhuang Ma"
32 | email: "ChumpMa@gmail.com"
33 | github: "mzlogin"
34 | "wcp1231@github":
35 | name: "Chunpeng Wen"
36 | email: "wcp1231@gmail.com"
37 | github: "wcp1231"
38 |
--------------------------------------------------------------------------------
/.githooks/post-merge/update-contributors:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ -f "${PWD}/.contributors" ]
3 | then
4 | echo 'refreshing contributors'
5 | ./node_modules/.bin/get-contributors > ./Contributor.md
6 | cp ./Contributor.md zh/Contributor.md
7 | fi
8 |
--------------------------------------------------------------------------------
/.github/workflows/BuildPDF.yml:
--------------------------------------------------------------------------------
1 | name: Build learn-with-open-source PDF
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-18.04
11 |
12 | steps:
13 | - uses: actions/checkout@v1
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: '10.x'
17 |
18 | - name: Configure dependency
19 | run: |
20 | sudo apt update
21 | sudo apt install -y calibre
22 | npm install -g gitbook-cli
23 | npm install
24 | gitbook install ./
25 | - name: Generate PDF
26 | run: |
27 | gitbook pdf
28 | cp book_zh.pdf learn-with-open-source.pdf
29 | ls -l
30 |
31 | - name: Create Release
32 | id: create_release
33 | uses: actions/create-release@v1.0.0
34 | env:
35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 | with:
37 | tag_name: ${{ github.ref }}
38 | release_name: Release ${{ github.ref }}
39 | draft: true
40 | prerelease: true
41 |
42 | - name: Upload Release Asset
43 | uses: actions/upload-release-asset@v1.0.1
44 | env:
45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46 | with:
47 | upload_url: ${{ steps.create_release.outputs.upload_url }}
48 | asset_path: ./learn-with-open-source.pdf
49 | asset_name: learn-with-open-source.pdf
50 | asset_content_type: application/pdf
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | *.bak
3 | node_modules/
4 | _book/
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/Contributor.md:
--------------------------------------------------------------------------------
1 | | Contributor Name | Github |
2 | | --------------- | ------ |
3 | | BiaoWei Zhuang | [zhuangbiaowei](https://github.com/zhuangbiaowei) |
4 | | Riceball LEE | [snowyu](https://github.com/snowyu) |
5 | | Zhuang Ma | [mzlogin](https://github.com/mzlogin) |
6 | | DukeAnt | - |
7 | | myourdream | - |
8 | | mieyou8mie | - |
9 | | guanmu | - |
10 | | zhouyilong | - |
11 | | 易枭寒 | - |
12 | | wgwang | - |
13 | | 杨松 | - |
14 | | Chunpeng Wen | [wcp1231](https://github.com/wcp1231) |
15 | | 蒋鑫 |[jiangxin](https://github.com/jiangxin) |
16 |
17 |
--------------------------------------------------------------------------------
/LANGS.md:
--------------------------------------------------------------------------------
1 | # Language
2 |
3 | * [中文](zh)
4 |
5 |
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution-NonCommercial-ShareAlike 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More_considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
58 | Public License
59 |
60 | By exercising the Licensed Rights (defined below), You accept and agree
61 | to be bound by the terms and conditions of this Creative Commons
62 | Attribution-NonCommercial-ShareAlike 4.0 International Public License
63 | ("Public License"). To the extent this Public License may be
64 | interpreted as a contract, You are granted the Licensed Rights in
65 | consideration of Your acceptance of these terms and conditions, and the
66 | Licensor grants You such rights in consideration of benefits the
67 | Licensor receives from making the Licensed Material available under
68 | these terms and conditions.
69 |
70 |
71 | Section 1 -- Definitions.
72 |
73 | a. Adapted Material means material subject to Copyright and Similar
74 | Rights that is derived from or based upon the Licensed Material
75 | and in which the Licensed Material is translated, altered,
76 | arranged, transformed, or otherwise modified in a manner requiring
77 | permission under the Copyright and Similar Rights held by the
78 | Licensor. For purposes of this Public License, where the Licensed
79 | Material is a musical work, performance, or sound recording,
80 | Adapted Material is always produced where the Licensed Material is
81 | synched in timed relation with a moving image.
82 |
83 | b. Adapter's License means the license You apply to Your Copyright
84 | and Similar Rights in Your contributions to Adapted Material in
85 | accordance with the terms and conditions of this Public License.
86 |
87 | c. BY-NC-SA Compatible License means a license listed at
88 | creativecommons.org/compatiblelicenses, approved by Creative
89 | Commons as essentially the equivalent of this Public License.
90 |
91 | d. Copyright and Similar Rights means copyright and/or similar rights
92 | closely related to copyright including, without limitation,
93 | performance, broadcast, sound recording, and Sui Generis Database
94 | Rights, without regard to how the rights are labeled or
95 | categorized. For purposes of this Public License, the rights
96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
97 | Rights.
98 |
99 | e. Effective Technological Measures means those measures that, in the
100 | absence of proper authority, may not be circumvented under laws
101 | fulfilling obligations under Article 11 of the WIPO Copyright
102 | Treaty adopted on December 20, 1996, and/or similar international
103 | agreements.
104 |
105 | f. Exceptions and Limitations means fair use, fair dealing, and/or
106 | any other exception or limitation to Copyright and Similar Rights
107 | that applies to Your use of the Licensed Material.
108 |
109 | g. License Elements means the license attributes listed in the name
110 | of a Creative Commons Public License. The License Elements of this
111 | Public License are Attribution, NonCommercial, and ShareAlike.
112 |
113 | h. Licensed Material means the artistic or literary work, database,
114 | or other material to which the Licensor applied this Public
115 | License.
116 |
117 | i. Licensed Rights means the rights granted to You subject to the
118 | terms and conditions of this Public License, which are limited to
119 | all Copyright and Similar Rights that apply to Your use of the
120 | Licensed Material and that the Licensor has authority to license.
121 |
122 | j. Licensor means the individual(s) or entity(ies) granting rights
123 | under this Public License.
124 |
125 | k. NonCommercial means not primarily intended for or directed towards
126 | commercial advantage or monetary compensation. For purposes of
127 | this Public License, the exchange of the Licensed Material for
128 | other material subject to Copyright and Similar Rights by digital
129 | file-sharing or similar means is NonCommercial provided there is
130 | no payment of monetary compensation in connection with the
131 | exchange.
132 |
133 | l. Share means to provide material to the public by any means or
134 | process that requires permission under the Licensed Rights, such
135 | as reproduction, public display, public performance, distribution,
136 | dissemination, communication, or importation, and to make material
137 | available to the public including in ways that members of the
138 | public may access the material from a place and at a time
139 | individually chosen by them.
140 |
141 | m. Sui Generis Database Rights means rights other than copyright
142 | resulting from Directive 96/9/EC of the European Parliament and of
143 | the Council of 11 March 1996 on the legal protection of databases,
144 | as amended and/or succeeded, as well as other essentially
145 | equivalent rights anywhere in the world.
146 |
147 | n. You means the individual or entity exercising the Licensed Rights
148 | under this Public License. Your has a corresponding meaning.
149 |
150 |
151 | Section 2 -- Scope.
152 |
153 | a. License grant.
154 |
155 | 1. Subject to the terms and conditions of this Public License,
156 | the Licensor hereby grants You a worldwide, royalty-free,
157 | non-sublicensable, non-exclusive, irrevocable license to
158 | exercise the Licensed Rights in the Licensed Material to:
159 |
160 | a. reproduce and Share the Licensed Material, in whole or
161 | in part, for NonCommercial purposes only; and
162 |
163 | b. produce, reproduce, and Share Adapted Material for
164 | NonCommercial purposes only.
165 |
166 | 2. Exceptions and Limitations. For the avoidance of doubt, where
167 | Exceptions and Limitations apply to Your use, this Public
168 | License does not apply, and You do not need to comply with
169 | its terms and conditions.
170 |
171 | 3. Term. The term of this Public License is specified in Section
172 | 6(a).
173 |
174 | 4. Media and formats; technical modifications allowed. The
175 | Licensor authorizes You to exercise the Licensed Rights in
176 | all media and formats whether now known or hereafter created,
177 | and to make technical modifications necessary to do so. The
178 | Licensor waives and/or agrees not to assert any right or
179 | authority to forbid You from making technical modifications
180 | necessary to exercise the Licensed Rights, including
181 | technical modifications necessary to circumvent Effective
182 | Technological Measures. For purposes of this Public License,
183 | simply making modifications authorized by this Section 2(a)
184 | (4) never produces Adapted Material.
185 |
186 | 5. Downstream recipients.
187 |
188 | a. Offer from the Licensor -- Licensed Material. Every
189 | recipient of the Licensed Material automatically
190 | receives an offer from the Licensor to exercise the
191 | Licensed Rights under the terms and conditions of this
192 | Public License.
193 |
194 | b. Additional offer from the Licensor -- Adapted Material.
195 | Every recipient of Adapted Material from You
196 | automatically receives an offer from the Licensor to
197 | exercise the Licensed Rights in the Adapted Material
198 | under the conditions of the Adapter's License You apply.
199 |
200 | c. No downstream restrictions. You may not offer or impose
201 | any additional or different terms or conditions on, or
202 | apply any Effective Technological Measures to, the
203 | Licensed Material if doing so restricts exercise of the
204 | Licensed Rights by any recipient of the Licensed
205 | Material.
206 |
207 | 6. No endorsement. Nothing in this Public License constitutes or
208 | may be construed as permission to assert or imply that You
209 | are, or that Your use of the Licensed Material is, connected
210 | with, or sponsored, endorsed, or granted official status by,
211 | the Licensor or others designated to receive attribution as
212 | provided in Section 3(a)(1)(A)(i).
213 |
214 | b. Other rights.
215 |
216 | 1. Moral rights, such as the right of integrity, are not
217 | licensed under this Public License, nor are publicity,
218 | privacy, and/or other similar personality rights; however, to
219 | the extent possible, the Licensor waives and/or agrees not to
220 | assert any such rights held by the Licensor to the limited
221 | extent necessary to allow You to exercise the Licensed
222 | Rights, but not otherwise.
223 |
224 | 2. Patent and trademark rights are not licensed under this
225 | Public License.
226 |
227 | 3. To the extent possible, the Licensor waives any right to
228 | collect royalties from You for the exercise of the Licensed
229 | Rights, whether directly or through a collecting society
230 | under any voluntary or waivable statutory or compulsory
231 | licensing scheme. In all other cases the Licensor expressly
232 | reserves any right to collect such royalties, including when
233 | the Licensed Material is used other than for NonCommercial
234 | purposes.
235 |
236 |
237 | Section 3 -- License Conditions.
238 |
239 | Your exercise of the Licensed Rights is expressly made subject to the
240 | following conditions.
241 |
242 | a. Attribution.
243 |
244 | 1. If You Share the Licensed Material (including in modified
245 | form), You must:
246 |
247 | a. retain the following if it is supplied by the Licensor
248 | with the Licensed Material:
249 |
250 | i. identification of the creator(s) of the Licensed
251 | Material and any others designated to receive
252 | attribution, in any reasonable manner requested by
253 | the Licensor (including by pseudonym if
254 | designated);
255 |
256 | ii. a copyright notice;
257 |
258 | iii. a notice that refers to this Public License;
259 |
260 | iv. a notice that refers to the disclaimer of
261 | warranties;
262 |
263 | v. a URI or hyperlink to the Licensed Material to the
264 | extent reasonably practicable;
265 |
266 | b. indicate if You modified the Licensed Material and
267 | retain an indication of any previous modifications; and
268 |
269 | c. indicate the Licensed Material is licensed under this
270 | Public License, and include the text of, or the URI or
271 | hyperlink to, this Public License.
272 |
273 | 2. You may satisfy the conditions in Section 3(a)(1) in any
274 | reasonable manner based on the medium, means, and context in
275 | which You Share the Licensed Material. For example, it may be
276 | reasonable to satisfy the conditions by providing a URI or
277 | hyperlink to a resource that includes the required
278 | information.
279 | 3. If requested by the Licensor, You must remove any of the
280 | information required by Section 3(a)(1)(A) to the extent
281 | reasonably practicable.
282 |
283 | b. ShareAlike.
284 |
285 | In addition to the conditions in Section 3(a), if You Share
286 | Adapted Material You produce, the following conditions also apply.
287 |
288 | 1. The Adapter's License You apply must be a Creative Commons
289 | license with the same License Elements, this version or
290 | later, or a BY-NC-SA Compatible License.
291 |
292 | 2. You must include the text of, or the URI or hyperlink to, the
293 | Adapter's License You apply. You may satisfy this condition
294 | in any reasonable manner based on the medium, means, and
295 | context in which You Share Adapted Material.
296 |
297 | 3. You may not offer or impose any additional or different terms
298 | or conditions on, or apply any Effective Technological
299 | Measures to, Adapted Material that restrict exercise of the
300 | rights granted under the Adapter's License You apply.
301 |
302 |
303 | Section 4 -- Sui Generis Database Rights.
304 |
305 | Where the Licensed Rights include Sui Generis Database Rights that
306 | apply to Your use of the Licensed Material:
307 |
308 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
309 | to extract, reuse, reproduce, and Share all or a substantial
310 | portion of the contents of the database for NonCommercial purposes
311 | only;
312 |
313 | b. if You include all or a substantial portion of the database
314 | contents in a database in which You have Sui Generis Database
315 | Rights, then the database in which You have Sui Generis Database
316 | Rights (but not its individual contents) is Adapted Material,
317 | including for purposes of Section 3(b); and
318 |
319 | c. You must comply with the conditions in Section 3(a) if You Share
320 | all or a substantial portion of the contents of the database.
321 |
322 | For the avoidance of doubt, this Section 4 supplements and does not
323 | replace Your obligations under this Public License where the Licensed
324 | Rights include other Copyright and Similar Rights.
325 |
326 |
327 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
328 |
329 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
330 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
331 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
332 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
333 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
334 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
335 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
336 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
337 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
338 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
339 |
340 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
341 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
342 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
343 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
344 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
345 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
346 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
347 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
348 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
349 |
350 | c. The disclaimer of warranties and limitation of liability provided
351 | above shall be interpreted in a manner that, to the extent
352 | possible, most closely approximates an absolute disclaimer and
353 | waiver of all liability.
354 |
355 |
356 | Section 6 -- Term and Termination.
357 |
358 | a. This Public License applies for the term of the Copyright and
359 | Similar Rights licensed here. However, if You fail to comply with
360 | this Public License, then Your rights under this Public License
361 | terminate automatically.
362 |
363 | b. Where Your right to use the Licensed Material has terminated under
364 | Section 6(a), it reinstates:
365 |
366 | 1. automatically as of the date the violation is cured, provided
367 | it is cured within 30 days of Your discovery of the
368 | violation; or
369 |
370 | 2. upon express reinstatement by the Licensor.
371 |
372 | For the avoidance of doubt, this Section 6(b) does not affect any
373 | right the Licensor may have to seek remedies for Your violations
374 | of this Public License.
375 |
376 | c. For the avoidance of doubt, the Licensor may also offer the
377 | Licensed Material under separate terms or conditions or stop
378 | distributing the Licensed Material at any time; however, doing so
379 | will not terminate this Public License.
380 |
381 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
382 | License.
383 |
384 |
385 | Section 7 -- Other Terms and Conditions.
386 |
387 | a. The Licensor shall not be bound by any additional or different
388 | terms or conditions communicated by You unless expressly agreed.
389 |
390 | b. Any arrangements, understandings, or agreements regarding the
391 | Licensed Material not stated herein are separate from and
392 | independent of the terms and conditions of this Public License.
393 |
394 |
395 | Section 8 -- Interpretation.
396 |
397 | a. For the avoidance of doubt, this Public License does not, and
398 | shall not be interpreted to, reduce, limit, restrict, or impose
399 | conditions on any use of the Licensed Material that could lawfully
400 | be made without permission under this Public License.
401 |
402 | b. To the extent possible, if any provision of this Public License is
403 | deemed unenforceable, it shall be automatically reformed to the
404 | minimum extent necessary to make it enforceable. If the provision
405 | cannot be reformed, it shall be severed from this Public License
406 | without affecting the enforceability of the remaining terms and
407 | conditions.
408 |
409 | c. No term or condition of this Public License will be waived and no
410 | failure to comply consented to unless expressly agreed to by the
411 | Licensor.
412 |
413 | d. Nothing in this Public License constitutes or may be interpreted
414 | as a limitation upon, or waiver of, any privileges and immunities
415 | that apply to the Licensor or You, including from the legal
416 | processes of any jurisdiction or authority.
417 |
418 | =======================================================================
419 |
420 | Creative Commons is not a party to its public licenses.
421 | Notwithstanding, Creative Commons may elect to apply one of its public
422 | licenses to material it publishes and in those instances will be
423 | considered the "Licensor." Except for the limited purpose of indicating
424 | that material is shared under a Creative Commons public license or as
425 | otherwise permitted by the Creative Commons policies published at
426 | creativecommons.org/policies, Creative Commons does not authorize the
427 | use of the trademark "Creative Commons" or any other trademark or logo
428 | of Creative Commons without its prior written consent including,
429 | without limitation, in connection with any unauthorized modifications
430 | to any of its public licenses or any other arrangements,
431 | understandings, or agreements concerning use of licensed material. For
432 | the avoidance of doubt, this paragraph does not form part of the public
433 | licenses.
434 |
435 | Creative Commons may be contacted at creativecommons.org.
436 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Learn Coding with Open Source
2 |
3 | [](https://gitter.im/zhuangbiaowei/learn-with-open-source?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 | [](https://github.com/zhuangbiaowei/learn-with-open-source)
5 | [](https://www.gitbook.com)
6 | [](https://creativecommons.org/licenses/by-nc-sa/4.0/)
7 | [](https://github.com/zhuangbiaowei/learn-with-open-source/actions)
8 |
9 | This book uses [GitBook](https://www.gitbook.com) to build.
10 |
11 | License: CC BY-NC-SA 4.0
12 |
13 | 
All contents licensed under the Creative Commons Attribution Non Commercial Share Alike 4.0 license.
14 |
15 | Welcome! Join us to finish this book.
16 |
17 | You can visit the online ebook: [Learn Coding With Open Source](https://zhuangbiaowei.gitbook.io/learn-with-open-source/)
18 |
19 | You can also get the PDF on the release page.
20 |
21 | ## for developers
22 |
23 | ### Build the book
24 | Note: you will need Linux or MacOS. Windows is not yet supported.
25 |
26 | 1. install [node.js](https://nodejs.org)
27 | 2. install [ebook-convert from calibre](http://calibre-ebook.com/download)
28 | * for pdf,epub etc ebook generation.
29 | * go Calibre > Misc > Install Command Line Tool after installed
30 | * or ln -s /Applications/calibre.app/Contents/MacOS/ebook-convert /usr/local/bin
31 | 3. enter the git repository directory
32 |
33 | ```bash
34 | cd learn-with-open-source
35 | npm install
36 | ```
37 | 4. generate the ebook via:
38 | 1. generate html pages:
39 |
40 | ```bash
41 | ./node_modules/.bin/gitbook build . _book
42 | ```
43 | 2. run a local server to read html:
44 |
45 | ```bash
46 | ./node_modules/.bin/gitbook serve .
47 | ```
48 | 3. generate the pdf:
49 |
50 | ```bash
51 | ./node_modules/.bin/gitbook pdf .
52 | ```
53 |
54 | ### Update contributions automatically
55 |
56 | It will update contributions through git commits after a pull request or merge is executed.
57 | If you want to update it manually:
58 |
59 | This script will update the "Contributor.md" file and copy it to the "zh" folder.
60 |
61 | ```bash
62 | cd learn-with-open-source
63 | ./.githooks/post-merge/update-contributors
64 |
65 | ```
66 |
67 | The contributors configuration file is the ".contributors" file
68 | on the root of the repository.
69 |
70 | ### Update TOC automatically
71 |
72 | TODO: this is not finished.
73 |
74 | The gitbook uses the SUMMARY.md to get the TOC.
75 | The list in the SUMMARY.md will be the TOC.
76 |
77 | ```
78 | 1. [Topic](topic.md)
79 | 1. [SubTopic](subtopic.md)
80 | 1. TheSameFileTopicNoLinkAllowed
81 | 1. TheSameFileTopicNoLinkAllowed
82 | 1. [Topic2]
83 | ```
84 |
85 | **note:**
86 |
87 | * the parent directory is not supported via gitbook.
88 | * the topic in the same file could not be a link.
89 |
90 | the workflow automation is:
91 |
92 | * a text file to determine the markdown files order,
93 | or use the file name order in a directory.
94 | * get toc of each markdown file.
95 | * merge it into SUMMARY.md
96 |
97 | ---------
98 |
99 | # 《借助开源项目,学习软件开发》
100 |
101 | 本书使用 [GitBook](https://www.gitbook.com) 来 build 电子书。
102 |
103 | 联机电子书版本在这里: [Learn Coding With Open Source](https://zhuangbiaowei.gitbook.io/learn-with-open-source/)
104 |
105 | 开放文档:《借助开源项目,学习软件开发》
106 |
107 | 诚邀您的参与!
108 |
109 | # 著作权申明
110 | License: CC BY-NC-SA 4.0
111 |
112 |
113 | - 本作品选择采用:署名-非商业性使用-相同方式共享 的CC协议。
114 | - 您可以:复制、发行、展览、表演、放映、广播或通过信息网络传播本作品。以及创作演绎作品。
115 | - 惟须遵守下列条件:
116 | - 署名 — 您必须按照作者或者许可人指定的方式对作品进行署名。
117 | - 署名方式为:在转载或新作品开头的显著位置,注明原作者的姓名、来源及其采用的知识共享协议,与本作品在Github上的原发地址建立链接
118 | - 非商业性使用 — 您不得将本作品用于商业目的。
119 | - 相同方式共享 — 如果您改变、转换本作品或者以本作品为基础进行创作,您只能采用与本协议相同的许可协议发布基于本作品的演绎作品。
120 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-merlot
--------------------------------------------------------------------------------
/book.json:
--------------------------------------------------------------------------------
1 | {
2 | "gitbook": ">1.x.x",
3 | "plugins": [
4 | "toc",
5 | "katex"
6 | ],
7 | "pluginsConfig": {
8 | "toc": {
9 | "addClass": false,
10 | "className": "toc"
11 | }
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/en/Before-start.md:
--------------------------------------------------------------------------------
1 | # Before the Beginning
2 | ## The Target Audience for This Document
3 | ### The software developers confused in opensource
4 | * Developers who would like to write readily intelligible code but don't know how to start
5 | * Developers who would like to understand other people's code
6 |
7 | ### Software development beginner
8 | This is a document for software development beginners, who have learned no more than two programming languages and been able to complete most of exercises in the course in terms of the language skills they have learned. From the general situation of college education, they could only complete the baseline of final course assignments arranged by teachers. That is to say, they are not so well in course and have difficulty in finding a way to improve their skills.
9 |
10 | For students who graduated or will graduate from universities(within one or two year(s)), it is difficult for them to get access to truly complex projects, and they will be in charge of the trivial details even if they are involved in complex projects. They are eager to improve their ability in software development as soon as possible, but what they lack mostly is the opportunity to improve their ability.
11 |
12 | Therefore, this paper aims to introduce a more reasonable method to help all the "classmates" to improve the ability of software development in a more scientific and reasonable way.
13 |
14 | ### First-time Users of Open Source Software
15 |
16 | In the field of software development, it is almost impossible to ignore open source projects. How to improve the development efficiency and reduce the duplication of effort with the help of open source projects in the daily development work is important, and how to benefit from open source rather than suffer from it is also an interesting topic. In a nutshell, it is risky to use the open source software without reading the source code(there is no different from using normal closed source software or closed source libraries). But if we can read and understand the source code, we can avoid this risk,and the better we understand it, the better we can use the software. Open source software offers this possibility to us.
17 |
18 | This article also hopes to help those who are new to open source and want to make good use of it by sharing experience of the experienced person.
19 |
20 | ### Hobbyists Wandering Outside the Open Source Community
21 | Do you want to be part of the open source community and give back some help to the open source community after enjoying the benefits it offerd? What is going on in the open source community? There are a lot of people who have a natural affinity for open source and hope to join in it, integrate into the open source community faster, make more contributions to open source project, or even start their own open source project and pull up a team to do something amazing. There should be many friends that have such idea. We hope the introduction of this article can have certain help.
22 |
23 | Since this is an open writing document, I am not particularly sure when I write this paragraph that this document will have only four target users. Maybe it can be of value to more people……
24 | ## The Basic Conditions
25 | ### A Computer With Internet Access
26 | It does seem irresponsible to say that these are all the basics. But it's really enough. Assuming that you are just working in an open source JavaScript project, install a developer-friendly browser like FireFox/Chrome and you will be basiclly ready to start.
27 |
28 | Furtherly, of course, there can be more fastidious. For example, Windows or Linux/MacOS? What distribution should you choose for Linux? Once you get into it, there will be endless problems waiting for you.
29 | ### The Preferred Ubuntu
30 | First, the reason why Linux should be choosen is that open source software, in many cases, is a more stable and reliable version for Linux, which is easier to solve when it comes to version dependence. Of course, there are many reliable open source projects for Windows, so Linux is more of a preference for using more open source. The jade bed mentioned in JinYong's "The Return Of the Condor Heros" can be used to explain the mystery. When you are in an open source enviroment and when your operations are exposed to open source concepts, you are making progress all the time and it's going to be faster.
31 |
32 | The reason of choosing Ubuntu is actually my own preference, for it is by far the easiest to use. It's more friendly for beginners. There are more Chinese resources on the Internet.
33 |
34 | In addition, there is a very famous article on the Internet named "[Why developers should use Mac OS X and simple history of OS X(《开发人员为何应该使用Mac OS X 兼 OS X 小史》)](https://blog.youxu.info/2010/02/28/why-mac-os-x-for-programmers/)", which is also very convincing and recommended to read.
35 | ### If you really like Windows
36 | Admittedly, in the Windows environment, you can also learn about open source. There are many open source person working hard on the Windows platform. A lot of environment building tools are being developed inch by inch like RubyInstaller, XAMPP, cygwin and so on.(Specific nouns will not be explained here)
37 |
38 | But, at a lot of time, you will encounter inexplicable report error and it is not unreasonable that a lot of people will suddenly look up into the sky in a night and curse:"This rotten Windows!"
39 | ### The network will not be blocked
40 |
41 | Google is a better search engine for software development in the most of time, so even if you have to go to a lot of trouble, make sure that use Google to search for the projects, documents and materials you are looking for.
42 |
43 | Reference:
44 |
45 | * [HuoJu: Google Baidu and Google(《霍炬:google百度和谷歌的那些事》)](http://blog.devep.net/virushuo/2010/01/14/blog56google_blogtinyfool_1_go.html)
46 | * [ChenHao: To be an enviromental programmer from not using Baidu on(《陈皓:作环保的程序员,从不用百度开始》)](https://coolshell.cn/articles/9308.html)
47 |
48 | ## Somethin You need to Be Specific
49 | ### Do You Really Want to Learn Software Development?
50 |
51 | Before the formal start of learning, I really can't help myself to ask you again and again: Do you really want? Do you really want to be a "code farmer"? Do you really want to master the craft of software development, or even make a living from it? Well, I have to tell you some truth:
52 |
53 | * Software development is not the kind of high-paid and little-responsibility white-collar worker you might expect to be. Many programmers will call themselves "code farmers", because this occupation is very hard, and not easy to do well.
54 | * In addition, this is a career that requires lifelong learning. Many other fields do not have such a rapid rate of knowledge updating. But in the field of software development, if you don't touch the latest developments in technology for a year or two, you will be OUT.
55 | * Also, software development is not much easy to find a job. Job prospects are not as bright as the fabled success stories.
56 | However, there are some people who love this industry. Coding is not only their job, but also their hobby.
57 | ### Are You Really Fit in Software Development?
58 | Software development, though, is not the high-IQ and nerd industry in the legend. But it does need some qualities and abilities that if you find yourself lacking or having to hard to achieve, you're not suited for the job.
59 |
60 | * Laziness: There is a famous saying that "laziness is the virtue of programmers", because real programmers must hate to do the same thing repeatedly, at least they will write a function to complete for themselves. If they find the same paragraph is repeated in the code, they can't help themselves to eliminate it.
61 | * Organization: If this is a complex thing, I can handle it in three stages. If I think carefully about it, the first stage could be divided into five parts. Before starting the first part, there are four preparations that must be considered first.
62 | * Patience: A lot of time, the trouble in the program will come to you, and how to solve it? Solving "bug" requires insight, care and, most of all, patience. Sometimes, I really enjoy the process of "solving cases".
63 | * Curiosity: There are so many things worth to be curious about. We have a lot of curiosities in new technologies that will never be finished learning, recent developments and best practices, and even other industries and fields because no matter what industry, they will come to us and help them write code.
64 | * Serious: It is said that a lot of things almost ok is really ok. But computer is so strict that even if one hundredth of a millisecond faster than before is faster. A one in ten thousand chance of a bug is still a bug. If you are not a serious enough people, you will ignore a lot of problems which could lead to disaster.
65 | ### OK, cut the cackle and let's start!
66 |
67 | Translated by Li Yancheng
68 |
--------------------------------------------------------------------------------
/en/Start.md:
--------------------------------------------------------------------------------
1 | # Start
2 |
3 | ## Several main ways of learning software development
4 |
5 | ### The myth of 10000 hours
6 |
7 | A while ago, I discussed a topic about 10000 hour with people on the Internet. There is a book called "the alien" which says that there is no absolute genius in the world. Talent also requires more than 10000 hours of training. Everyone can be a top player. For details, please refer to a popular article "how to practice 10000 hours".
8 |
9 | On the basis of this theory, some people put forward the concept of "10000 hours of programming training". It seems that after more than 10000 hours of training, ordinary people may also become "Masters / Masters" in the field of programming. However, this theory is actually a pseudo theory that seems to be based on statistics.
10 |
11 | The first is the scope. How wide the scope is can be called a field? What is the field? Programming is a large area, compiler or database programming are two different areas. If someone focuses on compiler development in 10000 hours, they may not know anything about database programming. So, is this kind of person a master in the field of programming? If someone focuses on assembly language programming in 10000 hours, how high can the new object-oriented scripting language be?
12 |
13 | The second is training. In the 10000 hour statistics, it refers to dance, music and many other areas that need repeated practice. Is this training for proficiency really needed in the field of programming? Of course, I believe that increasing the speed of typing really helps to improve the speed of code writing, but does it really help to improve the ability of programming? It will be very difficult to discuss how to train 10000 hours of programming in the field of software development.
14 |
15 | Finally, it's about knowledge update. In a field where new terms, new technologies and new ideas are born every day, can an expert who has been working hard for 10000 hours be called an expert after three years without contacting the latest knowledge?
16 |
17 | In a word, I accepted the concept of 10000 hours in a hurry, and was so excited that I decided to work hard to learn 10000 hours of programming, which is usually just a symptom of "inspirational book poisoning".
18 |
--------------------------------------------------------------------------------
/en/Useful-Websites-to-Learn-How-to-Code-Quickly.md:
--------------------------------------------------------------------------------
1 | # Website recommendations for developers to learn programming
2 |
3 | * en:[9 Useful Websites to Learn How to Code Quickly](http://www.queness.com/post/10709/8-useful-websites-to-learn-how-to-code-quickly)
4 | * zh translation: [wangguo](http://wangguo.iteye.com/)
5 |
6 | The Internet is a rapidly evolving field, where technologies constantly being updated, like from HTML to HTML5, from CSS to CSS3, from JavaScript to JavaScript frameworks, etc. If you can't keep up with the speed, you will be out of game. Therefore, a quick grasp of a language or a technology can be very beneficial.
7 |
8 | This article provides you 9 practical online tutorials, some of them are in interactive formats, and others are in comprehensive guides and visualizations.They will help you quickly master a language. They share a common purpose, that makes your learning more fun, and makes it easier for you to master it.
9 |
10 | ## [LifeHacker Learn to code](http://www.lifehacker.com.au/2011/02/learn-to-code-the-full-beginners-guide/)
11 |
12 | Language: JavaScript
13 | 4 lessons plus best practices/resources to teach you how to program using Javascript.
14 |
15 | Each lesson has a video and detailed articles to make sure you understand them.
16 |
17 | 
18 |
19 | ## [CodeCademy](http://www.codecademy.com/)
20 |
21 | Language: JavaScript
22 |
23 | This is an interactive form of instruction that gives you a bit of a grip on JavaScript.
24 |
25 | For each course you complete, you get some achievement points and badges that will inspire your interest in learning.
26 |
27 | 
28 |
29 |
30 | ## [TeamTreeHouse](http://teamtreehouse.com/)
31 |
32 |
33 | Languages: CSS, CSS3, HTML, HTML5, JavaScript, Basic Programming, and iOS Development
34 |
35 | This is a paid member online learning service that covers topics such as Web design and development, as well as iOS development, which is now very popular.
36 |
37 | 
38 |
39 | ## [RubyMonk](http://rubymonk.com/)
40 |
41 | Language: Ruby RubyMonk is an interactive learning platform.
42 |
43 | You can learn Ruby through courses, problem solving, or related articles.
44 |
45 | 
46 |
47 | ## [Hackety](https://github.com/hacketyhack/hacketyhack)
48 |
49 | Language: Ruby
50 |
51 | Hackety will teach you the absolute basics of programming, even if you don't have any programming experience.
52 |
53 | 
54 |
55 | ## [jQuery Air](http://jqueryair.com/)
56 |
57 |
58 | Language: JavaScript jQuery is the most famous JavaScript framework. Now you can learn jQuery directly in your browser.
59 |
60 | The process of learning jQuery should be fun, and jQuery Air does it through a number of practical ways.
61 |
62 | 
63 |
64 |
65 | ## [CodingBat](http://codingbat.com/)
66 |
67 | Language: Java, Python
68 |
69 | Learn about Java and Python by solving sample problems and online coding practices.
70 |
71 | 
72 |
73 | ## [PHP Know How](http://www.phpknowhow.com/)
74 |
75 | Language: PHP
76 |
77 | This is not an interactive way to learn, but it has a good written tutorial that contains a wealth of examples and guides to teach you the basics of PHP and MySQL.
78 |
79 | 
80 |
81 | ## [MongoDB](http://www.mongodb.org/)
82 |
83 | Languages: Java, Python, Go, PHP and other mainstream development languages This is the official website of MongoDB. MongoDB is a scalable, high-performance, open-source NoSQL database written in the C? language. For java, Python, Go, PHP and other mainstream development languages.
84 |
85 | The site contains a tutorial that lets you start your MongoDB learning journey with some commands.
86 |
87 | 
88 |
89 | ## [学堂在线](https://next.xuetangx.com/)
90 |
91 | Technology: WeChat small program development, algorithm. This is an online education website supported by Tsinghua University and other institutions.
92 |
93 | It includes courses such as recommended algorithms, WeChat mini-program production, etc.
94 |
95 | 
96 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "learn-with-open-source",
3 | "version": "0.0.1",
4 | "description": "the source of the book 'learn coding with the open source projects'",
5 | "private": true,
6 | "scripts": {
7 | "refresh-contributors": "./node_modules/.bin/get-contributors > ./Contributor.md",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/zhuangbiaowei/learn-with-open-source.git"
13 | },
14 | "keywords": [
15 | "book",
16 | "chinese",
17 | "learning",
18 | "coding"
19 | ],
20 | "contributors": [
21 | {
22 | "name": "Riceball LEE",
23 | "url": "https://github.com/snowyu"
24 | },
25 | {
26 | "name": "BiaoWei Zhuang",
27 | "url": "https://github.com/zhuangbiaowei"
28 | }
29 | ],
30 | "license": "CC",
31 | "bugs": {
32 | "url": "https://github.com/zhuangbiaowei/learn-with-open-source/issues"
33 | },
34 | "homepage": "https://github.com/zhuangbiaowei/learn-with-open-source",
35 | "dependencies": {
36 | "get-contributors": "^0.2.0",
37 | "git-hooks": "^1.0.0-rc.1",
38 | "gitbook-cli": "^0.3.4",
39 | "gitbook-plugin-katex": "^1.0.0",
40 | "gitbook-plugin-toc": "snowyu/gitbook-plugin-toc",
41 | "markdown-toc": "^0.11.5"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/zh/Before-start.md:
--------------------------------------------------------------------------------
1 | # 开始之前
2 |
3 |
4 |
5 | ## 这份文档的目标读者
6 |
7 | ### 有困惑的软件开发人员
8 | * 希望能写出别人容易读懂的代码,但不知道如何做的开发者
9 | * 希望能够看懂别人代码的开发者
10 |
11 | ### 软件开发初学者
12 |
13 | 这是一份面向软件开发初学者的文档,所谓初学者,可以定义为:学过的语言不超过2种,在已经学过的语言技能方面,能够完成课程上的大部分习题。从高校教育的通常情况来说,基本能够完成老师布置的最后的课程大作业。如果要说学得很出色,大概谈不上,要想进一步提高,也很困难。
14 |
15 | 对于大学毕业(前后1~2年)的同学们来说,他们很难接触到真正较为复杂的项目,即使参与到复杂的项目之中,也会是其中非常细枝末节的部分。他们渴望快速地提升自己的软件开发能力,而恰恰最缺乏提升自身能力的机会。
16 |
17 | 因此,本文希望能够介绍一种较为合理的方法,帮助各位“同学”,以较为科学合理的方式,提高软件开发的实力。
18 |
19 | ### 开源软件的初次使用者
20 |
21 | 在软件开发这个领域,完全不接触开源项目,几乎是不可能的事情。在日常开发工作中,如何借助开源项目提高开发效率,减少重复劳动;如何从开源中受惠,而不是因开源而受害,也是一个很有意思的课题。简单地说:不读源代码,直接拿来使用,其实是有风险的(这和使用普通的闭源软件、闭源的类库,就没有区别了)。但如果我们能阅读、理解源代码,就能避免这种风险,同时理解得越是透彻,越是能够用好一个软件。开源软件正为我们提供了这种可能。
22 |
23 | 本文也希望能够通过分享过来人的经验,帮助那些初次接触开源、想要用好开源的朋友。
24 |
25 | ### 开源社区外徘徊的爱好者
26 |
27 | 想要成为开源社区的一份子,在享受到开源带来的好处之后,或许也能够回馈一些帮助给开源社区?开源社区到底是怎么一回事?有很多人对于开源有着天然的好感,希望能够加入进来,更快的融入开源社区,为开源做出更多的贡献,甚至启动一个自己的开源项目,拉起一支队伍来做些了不起的事情。有这样想法的朋友,应该也不少,希望本文的介绍能够起到一定的帮助。
28 |
29 | 由于这是一份开放式写作的文档,因此,当我写下这段话的时候,其实并没有特别确定的把握,这份文档将只有以上四类目标用户。也许,它能够对更多的人产生价值。
30 |
31 | ## 基本条件
32 |
33 | ### 一台能够上网的电脑
34 |
35 | 如果我说,以上就是全部的基本条件,似乎是太不负责任了。但是,真的也就够了。假设你只是研究JavaScript的开源项目的话,装一个FireFox/Chrome这样的对开发者友好的浏览器,基本上就可以开始学习了。
36 |
37 | 再进一步,当然可以有更多的考究。比如:究竟是选择Windows还是Linux/MacOS?Linux又应该选择什么发行版?等等等等,一旦深入,自然有无穷无尽的问题在等着你。
38 |
39 | ### 首选Ubuntu
40 |
41 | 首先解释为什么要选择Linux,因为开源软件,在很多情况下都是Linux的版本更加稳定可靠,在解决版本依赖问题的时候,也更加容易些。当然,在Windows下面,也有非常非常多靠谱的开源项目,因此选择Linux更多的是出于一种多多使用开源的偏好。金庸先生的《神雕侠侣》中提到的寒玉床,可以用来解释这其中的奥妙。当你完全处在一个开源的环境,当你的各种操作都会接触到与开源相关的各种概念时,你就时时刻刻都在进步中,这样获得进步自然会更快一些。
42 |
43 | 再说为什么选择Ubuntu,这就更是个人偏好了,因为Ubuntu的易用性目前看来还是最好的。对于初学者来说,也更加友好一些。网络上的中文资源,也更多一些。
44 |
45 | 另外,网络上有一篇非常著名的文章叫做:《[开发人员为何应该使用 Mac OS X 兼 OS X 小史](http://blog.youxu.info/2010/02/28/why-mac-os-x-for-programmers/)》,也写得非常有说服力,推荐阅读一下。
46 |
47 | ### 如果你真的喜欢Windows
48 |
49 | 必须承认,在Windows环境下,还是可以学习开源的。也有很多很多开源人,努力地在Windows平台下工作。很多环境的搭建工具,被一点一点的开发出来。比如:RubyInstaller;XAMPP;以及cygwin等等。(具体的名词这里不解释)
50 |
51 | 但是,很多时候,你会遭遇莫名其妙的报错,很多人会在某个深夜,突然抬头望天,破口大骂:“这个烂Windows!”不是没有道理的。
52 |
53 | ### 不会被阻隔的网络
54 |
55 | 是的,这篇文章如果有幸被翻译为英文,这一段话完全可以被删除,因为他们无法想象我们还会遇到这样的困难。而克服这种困难,对于学习软件开发,又是绝对必须的一种技能,所以......如果你真的发现目标网站无法访问,那就寻求帮助吧。(抱歉,无法在这份文档里提供帮助。不过,我留了email。)
56 |
57 | Google在大多数时候,对于软件开发来说,都是更好的搜索引擎,所以,哪怕你费尽千辛万苦,也一定要用Google来搜索想要寻找的项目、文档和资料,必须的!
58 |
59 | 参考资料:
60 | * [霍炬:google百度和谷歌的那些事](http://blog.devep.net/virushuo/2010/01/14/blog56google_blogtinyfool_1_go.html)
61 | * [陈皓:作环保的程序员,从不用百度开始](http://coolshell.cn/articles/9308.html)
62 |
63 | ## 你需要明确的一些事情
64 |
65 | ### 你真的想学习软件开发吗?
66 |
67 | 在正式开始学习之前,我实在是忍不住,我想一遍又一遍的询问你:你真的想吗?你真的想成为一个“码农”吗?你真的想掌握软件开发这门手艺,甚至以此来谋生吗?那么好,我得告诉你一些事实:
68 |
69 | * 软件开发工程师,绝非你想象中的事少钱多责任轻的那种高薪白领。很多程序员会自称“码农”,就是因为这份职业非常的辛苦,而且做好不易。
70 | * 另外,这是一个需要终生学习的职业,很多很多的其他领域,没有那么快的知识更新速度。但是软件开发这个领域,1~2年不接触技术最新的进展,你就OUT了!
71 | * 还有,软件开发这个行当,真的未必就那么好找工作。就业前景什么的,也并非像那些传说的成功故事一样光明。
72 |
73 | 但是,真的有一些人,热爱这个行业,编程不但是他的工作,他的业余爱好也是Coding。
74 |
75 | 如果,你确信自己不仅仅是靠编程来维生,更是将编程作为自己最大的爱好,那么欢迎您,来到一个神奇而充满魅力的世界。这里有智慧、有乐趣、更有热心的朋友和充满前途的事业!(太像传销课了...)
76 |
77 | ### 你真的适合软件开发吗?
78 |
79 | 虽然,软件开发并非像传说中的那样,是一个需要高智商的Nerd的行业。但是,他的确需要一些品质和能力,如果你发现自己并不具备,或者要很辛苦才能做到,那么,你不适合这个行当。
80 |
81 | * 懒惰:有一句名言这么说:“懒惰是程序员的美德”,因为真正的程序员,一定痛恨反复做同一件事情,至少他们会写一个函数来替自己完成。如果发现代码里重复出现相同的段落,他们会无法抑制地想要消除这种重复。
82 | * 条理:如果这是一个复杂的事情,那么我可以分成三个阶段来着手去做它。如果仔细想想,第一个阶段,还可以分为5个部分。在开始第一阶段之前,还有4个准备工作,必须首先考虑。
83 | * 耐心:很多时候,程序里的麻烦会来找你,如何解决?解决“bug”需要洞察力,需要细心,而最需要的,则是耐心。有些时候,我会非常享受这种“破案”的过程。
84 | * 好奇心:值得好奇的事情太多了,永远学不完的新技术,最近的进展和最佳实践,甚至其他行业和领域的究竟,我们都有充沛的好奇心,因为无论哪个行业,他们早晚都会来找到我们帮他们编写代码的。
85 | * 较真:很多事情,据说都差不多就可以了。但是,计算机是那么严格,快百分之一毫秒,也是快了。一个万分之一概率下会出的bug,还是bug。如果你不是一个足够较真的人,就会放过很多问题,而那些问题,往往就会酿成大祸。
86 |
87 | ### OK,闲话少叙,咱们开始吧!
88 |
89 | [下一章](Start.md)
90 |
--------------------------------------------------------------------------------
/zh/Contribute-to-an-open-source-project.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/Contribute-to-an-open-source-project.md
--------------------------------------------------------------------------------
/zh/Contributor.md:
--------------------------------------------------------------------------------
1 | | Contributor Name | Github |
2 | | --------------- | ------ |
3 | | BiaoWei Zhuang | [zhuangbiaowei](https://github.com/zhuangbiaowei) |
4 | | Riceball LEE | [snowyu](https://github.com/snowyu) |
5 | | Zhuang Ma | [mzlogin](https://github.com/mzlogin) |
6 | | DukeAnt | - |
7 | | myourdream | - |
8 | | mieyou8mie | - |
9 | | guanmu | - |
10 | | zhouyilong | - |
11 | | 易枭寒 | - |
12 | | wgwang | - |
13 | | 杨松 | - |
14 | | Chunpeng Wen | [wcp1231](https://github.com/wcp1231) |
15 |
16 |
--------------------------------------------------------------------------------
/zh/Create-an-open-source-project.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/Create-an-open-source-project.md
--------------------------------------------------------------------------------
/zh/FAQ.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/FAQ.md
--------------------------------------------------------------------------------
/zh/Hello-world.md:
--------------------------------------------------------------------------------
1 | # Hello World
2 |
3 |
4 |
5 | ## 下载源代码的N种办法
6 |
7 | ### 关于源代码管理与版本控制
8 |
9 | 首先需要介绍一些基础的概念,这里只是简要的介绍,比较详细的介绍,可以参见[Understanding Version-Control Systems](http://www.catb.org/%7Eesr/writings/version-control/version-control.html),期待有人能够将其翻译为中文(或者已经有中译本了,欢迎告知我)。
10 |
11 | **源代码([Source Code](http://en.wikipedia.org/wiki/Source_code))**:也就是通常一个软件,由程序员编写,并且可以被其他程序员阅读的,可以被直接执行/编译后执行的文本代码。
12 |
13 | **源代码管理与版本控制([Version control/Revision control](http://en.wikipedia.org/wiki/Revision_control))** :由于源代码数量急剧膨胀、变更越来越频繁,可能修改同一个源文件的人也越来越多,需要将这些代码管理起来,于是每次变更被称之为一次修正 (Revision)。版本控制更准确的说法应该是“Revision control”,每当我们修改一个源代码文件并再次保存时,就出现了两个不同的版本,一个是修改前的,一个是修改以后的。而版本控制,就是确保源文件的每一次修改,都被记录下来,并且可以知道是被谁修改的,是因为什么原因而修改的。必要时,可以找回任何一个版本的源代码。
14 |
15 | **软件版本号([Software Version](http://en.wikipedia.org/wiki/Software_versioning))** :这里的版本,是另外一个概念,源代码中的任何一个文件,都存在一个修订版本号,而作为整个软件,无论对内称呼还是对外发布,都需要一个更加正式的、完整的版本号。前者的英文是Revision,而后者的英文是Version。因此,当我们谈到版本管理的时候,很可能是同时谈到两者:一个是源代码的Revision,一个是整个项目的Version。
16 |
17 | **版本控制工具([Revision control software](http://en.wikipedia.org/wiki/List_of_revision_control_software))** :为了更好地管理源代码,程序员们开发出了林林种种的版本控制工具,有闭源的,也有开源的。而现在市面上流行的,已经几乎全是开源的了。简单的列出几种在下面:
18 |
19 | * 仅管理本地源文件
20 | * 免费/开源:SCCS (1972) RCS (1982)
21 | * 闭源:PVCS (1985)
22 | * C/S方式管理源代码
23 | * 免费/开源:CVS (1990) CVSNT (1998) Subversion (2000)
24 | * 闭源:Software Change Manager (1970s) ClearCase (1992) CMVC (1994) Visual SourceSafe (1994) Perforce (1995) StarTeam (1995) MKS Integrity (2001) AccuRev SCM (2002) SourceAnywhere (2003) SourceGear Vault (2003) Team Foundation Server (2005) Rational Team Concert (2008)
25 | * 分布式管理源代码
26 | * 免费/开源:GNU arch (2001) Darcs (2002) DCVS (2002) SVK (2003) Monotone (2003) Codeville (2005) Git (2005) Mercurial (2005) Bazaar (2005) Fossil (2007) Veracity (2011)
27 | * 闭源:TeamWare (1990s?) Code Co-op (1997) BitKeeper (1998) Plastic SCM (2006)
28 |
29 | **更多参考资料:**
30 | * 上述概念所附带的四个link,都是来自于英文版的wikipedia,有些也有附带的中文版本,顺着这四个主条目的介绍,可以点击阅读更多的词条,加深了解。
31 | * [版本控制工具历史的10个里程碑](http://blog.jobbole.com/14489/) 本文中的一些link,也非常值得点击过去细细阅读。
32 | * [为什么软件项目从集中式迁移到分布式版本控制系统的热情持续不减?](http://codinn.com/projects/why-projects-moving-to-dvcs/view/) 最新趋势,值得了解。
33 |
34 | ### 寻找早期开源项目的源代码
35 |
36 | 取得源代码的方式千千万万,现在有越来越多的开源项目,已经开始逐步采用规范的,统一的方式,提供自己的源代码以供下载。但是在开源项目发展的早期,还有很多是以并非规范的方式提供的。而在寻找一些开源项目的源代码时,google与wikipedia,将会是我们的好帮手。当然,还有更早期的一些开源项目,就是在邮件列表里发一个带附件的邮件,要找到那种项目的源代码,就得有考古的功力了。
37 |
38 | 这里举一个例子,来描述一下我寻找某一个开源项目源代码的过程。
39 |
40 | 有一个项目叫做GForge,在早期还是一个较为著名的开源托管平台的项目,这个托管平台的代码本身也是以GNU许可开源的。假设,我首先是在wikipedia上发现了这个项目: http://en.wikipedia.org/wiki/GForge
41 | 看到这个项目的介绍,我觉得大概不错,于是我就看到下面的External links,列出了四个外部链接:
42 |
43 | * GForge official website
44 | * GForge project open source page
45 | * GForge Advanced Server page
46 | * FusionForge project open source page
47 |
48 | 一个比较合理的猜测,自然是首先访问[GForge project open source page](http://gforge.org/projects/gforge/)因为这个项目托管在自己的开源平台上,应该是顺理成章的。进入这个页面之后,我迷惑了一下,他竟然是一个中文界面,里面有文件、档案发行和SVN三个疑似可以下载的地方。经过试错,我发现:文件里没啥东西。SVN的存取信息里告诉我,可以svn checkout [http://gforge.org/svn/gforge](http://gforge.org/svn/gforge)获得最新的源代码。而在档案发行里,我发现了[各个历史版本的列表](http://gforge.org/gf/project/gforge/frs/?action=FrsReleaseBrowse&frs_package_id=2)而最新的那个5.0版本并非一个压缩包,而是一个txt文件,里面告诉我:GForge项目已经被全部重新设计和重写,目前可以在[as-help](http://gforge.org./gf/project/as-help/)这个项目里看到。另外,如果要下载最新的版本,可以到[http://gforgegroup.com/es/download.php](http://gforgegroup.com/es/download.php)
49 |
50 | 而如果要下载早期的版本,那么历史版本列表的那些gforge-x.x.tag.bz2,就可供我挑选了。
51 |
52 | 更加糟糕的情况也许会需要我们在google里搜索:“XXX source code download”这样的关键字,才能找到,这里不再赘述。
53 |
54 | ### SVN、Git、Mercurial快速介绍
55 |
56 | 三本值得一看的书
57 |
58 | * [Subversion 与版本控制](http://svnbook.red-bean.com/)
59 | * [progit 中文版](https://progit.bootcss.com/)
60 | * [hginit.com 中文版](https://zh-hginit.readthedocs.io/en/latest/)
61 |
62 | 另外
63 |
64 | * [Mercurial 权威指南](https://i18n-zh.googlecode.com/svn/www/hgbook/zh/index.html)(这本书的翻译尚未完成,因此推荐直接阅读英文版)
65 |
66 | 基本上,如果想要开始使用并深入掌握这三种版本管理工具的其中一种,都可以由此入门,并最终融会贯通。
67 |
68 | **SVN如何获取代码**
69 |
70 | 如果你在windows平台下,推荐安装[TortoiseSVN](http://tortoisesvn.net/downloads.html),然后,就在图形界面下简单操作。
71 |
72 | 填入SVN来源URL,直接CheckOut出最新的版本(HEAD revision),或者选择某个具体的版本(Revision),选择CheckOut的目录即可。
73 |
74 | 如果你在linux/mac平台下,那么命令行会非常方便:
75 |
76 | svn checkout http://SiteDomain/path/ProjectName 获取最新的版本
77 | svn checkout http://SiteDomain/path/ProjectName --revision {....} 获取某个版本
78 | svn checkout http://SiteDomain/path/ProjectName/tags/Release_x.xx 获取上某某tag的具体发行版本
79 |
80 | **Git如何获取代码**
81 |
82 | 如果一个git管理的项目放在github这样的成熟项目托管平台,获取代码是非常简单的,而且网站还会有详细的操作指南,教你一步一步的如何操作。
83 |
84 | 至少,你可以先参照[GitHub的指南](http://help.github.com/win-set-up-git/),搭建自己的git开发环境。
85 |
86 | 然后,获取代码也极其简单:
87 |
88 | 这里要注意的是,gitHub给出的项目地址GitRepoURL不止一个,这是因为git是支持多种协议的,例如默认的ssh,https等。
89 |
90 | git clone GitRepoURL
91 |
92 | **Mercurial如何获取代码**
93 |
94 | 正如GitHub是主打Git的开源托管平台,[BitBucket](https://bitbucket.org/)则是一个主打Mercurial的开源托管平台。因此,我们可以在这里找到关于Mercurial的操作指南。而因为Git的飞速发展,现在BitBucket也开始同时支持Git,所以在[bitbucket 101](http://confluence.atlassian.com/display/BITBUCKET/Set+up+Git+and+Mercurial),可以同时看到两种工具的安装指南。
95 |
96 | hg clone HgRepoURL
97 |
98 | 即可获得Mercurial仓库的完整副本。(Mercurial又简称为hg)
99 |
100 | ### 基于包管理的方式获取源代码
101 |
102 | 这是新增的一个小节,因为在很多动态脚本语言中,都有类似的包管理工具,在wikipedia中有一个词条[List of software package management systems](http://en.wikipedia.org/wiki/List_of_software_package_management_systems),其中的Application-level package managers小节,就介绍了十多种不同语言的包管理工具。
103 |
104 | 想要更进一步的了解软件包管理系统,可以阅读[英文版](http://en.wikipedia.org/wiki/Package_management_system) [中文版](http://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%8C%85%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F)
105 |
106 | 与过去的很多开源项目不同,这种脚本语言的包管理工具实在是方便,一行命令,连下载,带安装,就都有了。本章4.2节的让代码运行起来里,会举几个这样的例子。这里就不再赘述了。
107 |
108 | **Application-level package managers**
109 |
110 | | 语言 | 包管理工具 | 相关文档与资源 |
111 | | ------ | ---------------------------------------- | ---------------------------------------- |
112 | | Perl | [CPAN](http://www.cpan.org/) | [[1]](http://en.wikipedia.org/wiki/CPAN) [[2]](http://www.cpan.org/misc/cpan-faq.html) |
113 | | PHP | [PEAR](http://pear.php.net/) [PECL](http://pecl.php.net/) | [[1]](http://en.wikipedia.org/wiki/PHP_Extension_and_Application_Repository) [[2]](http://pear.php.net/manual/en/) |
114 | | Ruby | [RubyGems](http://www.rubygems.org/) [Bundler](http://bundler.io/) | [[1]](http://docs.rubygems.org/) [[2]](http://rubydoc.info/github/carlhuda/bundler/master/Bundler) |
115 | | Java | [Maven](http://maven.apache.org/) | [[1]](http://en.wikipedia.org/wiki/Apache_Maven) [[2]](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) |
116 | | Python | [EasyInstall](http://en.wikipedia.org/wiki/EasyInstall) [PyPI](https://pypi.python.org/pypi) | [[1]](http://peak.telecommunity.com/DevCenter/PythonEggs) [[2]](http://en.wikipedia.org/wiki/Python_Package_Index) |
117 | | NET | [NuGet](http://nuget.codeplex.com/) | [[1]](http://nuget.codeplex.com/documentation) |
118 | | NodeJS | [npm](http://npmjs.org/) | [[1]](http://npmjs.org/doc/) |
119 |
120 | ## Windows下的开发环境准备
121 |
122 | Windows,MacOS,Linux是当下主流的三大操作系统。很大一部分计算机用户出于经济适用和方便的原因,都选择 Windows操作系统,但对于计算机学习者来说,却不可避免的会使用Linux,因为你的大多数程序最终是跑在线上的 Linux服务器上,而且 Linux相对与其他系统,具有安全、稳定、高效、资源消耗少、易操作等一系列特点。所以,这里单独介绍除了虚拟机外 Windows环境下使用 Linux系统的一个简单方法(WSL),方便 Windows用户学习使用 Linux。
123 |
124 | ### 关于WSL
125 |
126 | [WSL](https://baike.baidu.com/item/wsl/20359185?fr=aladdin)(Windows Subsystem for Linux)是一个在 Windows 10 上能够运行原生 Linux二进制可执行文件的兼容层。
127 | Linux 的 Windows 子系统让开发人员可以直接在 Windows 上运行 Linux 环境(包括大多数命令行工具,实用程序和应用程序),而无需建立在虚拟机的开销之上,整个系统只有200多兆,但基本包含了你能用到的所有功能,并且和 Windows完美互操作(省去 Linux挂载本地 Windows分区或目录的操作),目前 Linux的 Windows子系统已经相当完善,可当作完整 Linux 系统使用(极少部分Windows 应用不能正常运行)。
128 |
129 | 在WSL下,你可以实现如下功能,但不仅限于这些操作:
130 |
131 | 1. 在 Microsoft Store 中选择你偏好的 GNU/Linux 分发版(推荐Ubuntu);
132 |
133 | 2. 运行 Bash shell 脚本和 GNU/Linux 命令行应用程序;
134 |
135 | 3. 使用分发包管理器安装其他软件;
136 |
137 | 4. 使用类似于 Unix 的命令行 shell 调用 Windows 应用程序;
138 |
139 | 5. 在 Windows 上调用 GNU/Linux 应用程序。
140 |
141 | WSL 体系结构的新版本 WSL2 也已经可以使用,WSL与 WSL2 的区别可自行查询。当然,你也可以选择虚拟机或者安装双系统,但传统的 [VM](https://baike.baidu.com/item/%E8%99%9A%E6%8B%9F%E6%9C%BA/104440?fromtitle=VM&fromid=16532539) (虚拟机推荐VMware)启动速度慢,隔离会消耗大量资源,需要时间进行管理,双系统更加消耗内存以及带来管理上的不便,不过这两种情况下的系统更能显示出 Linux的完整结构和操作,大家可以根据自己需求以及电脑配置进行选择。
142 |
143 |
144 | ### WSL的安装
145 |
146 | **下载安装流程**
147 |
148 | 1. 打开 Windows “启用或关闭Windows功能”;
149 | 2. 勾选 “适用于Linux的Windows子系统”;
150 | 3. 在 Windows应用商店搜索“Linux”,选择您喜欢的Linux版本,推荐Ubuntu;
151 | 4. 正常下载安装(建议不要修改安装路径);
152 | 5. 安装以后即可打开Ubuntu使用Linux命令对windows文件进行操作;
153 |
154 | **升级到WSL2方法**
155 |
156 | 1. 按以上流程成功安装Ubuntu,且版本必须是18917之后的版本;
157 | 2. 在搜索框中输入Powershell点击Run as Administrator;
158 | 3. 在打开的命令行中输入 Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform 启用虚拟机平台可选组件;
159 | 4. 完成后重启系统,之后依旧以管理员身份打开powershell,输入wsl -l查看已经安装的子系统;
160 | 5. 输入命令wsl --set-version Ubuntu-18.04 2,这里的Ubuntu-18.04换成你的子系统名称(这里再强调一遍,必须是18917之后的版本);
161 | 6. 输入wsl -l -v查看目前WSL版本,查看是否已经成功安装。
162 |
163 | **其他说明**
164 |
165 | 推荐一款好看的 Windows端的终端模拟器——Fluent Terminal,如需要的话可自行搜索相关教程([GitHub](https://github.com/felixse/FluentTerminal)),在设置中选择WSL,之后子系统的所有操作都可以在Fluent terminal中操作,美观的不是一点。
166 | WSL使用与Linux使用一致,尽情享用吧。
167 |
168 | ## 让代码运行起来
169 |
170 | 经过思考,决定将这一小节以实例的方式写出。也欢迎大家补充各种不同语言的how to install。
171 |
172 | ### Ruby版
173 |
174 | **在Windows环境下** 推荐安装[RubyInstaller](http://rubyinstaller.org/),进入下载页面,选择一个ruby版本,比如[Ruby 1.9.3-p125](http://rubyforge.org/frs/download.php/75848/rubyinstaller-1.9.3-p125.exe),下载、运行安装即可。
175 |
176 | **在Linux/Mac环境下** 推荐安装[RVM](http://beginrescueend.com/)或者[rbenv](http://rbenv.org/)
177 |
178 | $ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
179 | ubuntu下,将下两行中的.bash_profile改为.profile
180 | $ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # > Load RVM function' >> ~/.bash_profile
181 | $ source ~/.bash_profile
182 | $ rvm requirements
183 | 根据提示,安装其他必要的软件包
184 | $ rvm install 1.9.3
185 | $ rvm use 1.9.3
186 |
187 | 安装一个开源项目
188 |
189 | $ gem install sinatra
190 |
191 | 搞定收工。。。
192 |
193 | 如果之前没有安装过rubygems这个包,则会困难一些。首先要在[RubyGems](> )这个页面挑一个文件格式下载,并解压缩。然后执行以下命令:
194 |
195 | $ cd directory
196 | $ ruby setup.rb
197 |
198 | 搞定收工。。。
199 |
200 | 参考:[使用RVM在ubuntu下安装ruby&rails](http://www.cnblogs.com/klobohyz/archive/2011/11/21/2256518.html)
201 |
202 | ### PHP版
203 |
204 | **在Windows环境下** 推荐安装WAMP(Windws+Apache+MySQL+PHP)套件,[XAMPP](http://www.apachefriends.org/en/xampp-windows.html)
205 |
206 | **在Linux环境下** 以下将简单介绍在Ubuntu下安装LAMP的过程,其他的linux平台以及Mac平台,请自行搜索。
207 |
208 | $ sudo apt-get install mysql-client mysql-server
209 | 根据提示,输入两次MySQL的root密码。
210 | $ sudo apt-get install apache2
211 | 在浏览器中访问 http://localhost,应该可以看到It Works等文字。表明Apache2安装成功。
212 | $ sudo apt-get install php5 libapache2-mod-php5 libapache2-mod-auth-mysql php5-mysql
213 | $ sudo /etc/init.d/apache2 restart #重启Apache服务器,完成配置PHP的工作
214 | $ sudo vim /var/www/info.php
215 | 将以下内容写入文件
216 |
219 | 在浏览器中访问 http://localhost/info.php 应该能够看到PHP的版本及模块说明等内容。这样就表明,Linux+Apache+MySQL+PHP已经配置完成了。
220 |
221 | **安装一个开源项目** 以在Ubuntu上安装一个wordpress为例
222 |
223 | $ wget http://cn.wordpress.org/wordpress-3.3.1-zh_CN.tar.gz #需要寻找最新的版本
224 | $ tar -zxvf wordpress-3.3.1-zh_CN.tar.gz
225 | $ mysql -uroot -p
226 | mysql> CREATE DATABASE IF NOT EXISTS wordpress default charset utf8 COLLATE utf8_general_ci;
227 | mysql> GRANT ALL PRIVILEGES
228 | ON wordpress.*
229 | TO 'wp_user'@'localhost'
230 | IDENTIFIED BY 'wp_password'
231 | WITH GRANT OPTION;
232 | mysql> exit
233 | $ cp wp-config-sample.php wp-config.php
234 | $ vim wp-config.php
235 | (最主要是修改以下四个值的定义)
236 | define('DB_NAME', 'wordpress');
237 | define('DB_USER', 'wp_user');
238 | define('DB_PASSWORD', 'wp_password');
239 | define('DB_HOST', 'localhost');
240 |
241 | 在浏览器中访问 [http://localhost/wordpress/wp-admin/install.php](http://localhost/wordpress/wp-admin/install.php) 按提示完成各个步骤,就搞定了,整个时间不超过5分钟。
242 |
243 | 最后一句的提示,很有趣味:“WordPress 安装完成。您是否还沉浸在愉悦的安装过程中?很遗憾,一切皆已完成!”
244 |
245 | [参考文档 1](http://codex.wordpress.org/zh-cn:%E5%AE%89%E8%A3%85WordPress) [参考文档 2](http://supriyadisw.net/2006/12/wordpress-installation-on-ubuntu-with-lamp)
246 |
247 | ### Java版
248 |
249 | **在Ubuntu下以源代码方式安装Tomcat**
250 |
251 | $ wget http://apache.etoak.com/tomcat/tomcat-7/v7.0.27/src/apache-tomcat-7.0.27-src.tar.gz #寻找最新版本
252 | $ tar -zxvf apache-tomcat-7.0.27-src.tar.gz
253 | $ cd apache-tomcat-7.0.27-src
254 | $ vim BUILDING.txt # 阅读编译指南,按照指示操作
255 | $ 下载 jdk-6u31-linux-x64.bin #tomcat7.0.x的源代码编译,要求jdk6的版本,jdk7在编译时,会报错
256 | $ cd
257 | $ ./jdk-6u31-linux-x64.bin
258 | $ export JAVA_HOME=~/jdk1.6.0_31/
259 | $ wget http://apache.etoak.com//ant/binaries/apache-ant-1.8.3-bin.tar.gz
260 | $ tar -zxvf apache-ant-1.8.3-bin.tar.gz
261 | $ export PATH=%PATH:~/apache-ant-1.8.3/bin:~/jdk1.6.0_31/bin
262 | $ export ANT_HOME=~/apache-ant-1.8.3/
263 | $ cd apache-tomcat-7.0.27-src
264 | $ ant
265 | $ cd output/build/bin/
266 | $ ./catalina.sh run
267 |
268 | 至此,在浏览器中,访问[http://localhost:8080/](http://localhost:8080/) 可以看到Tomcat的欢迎页。
269 |
270 | ### Python版
271 |
272 | **在Ubuntu上安装Python Webpy**
273 |
274 | $ sudo easy_install web.py
275 | $ python
276 | Python 2.7.5 (default, Mar 9 2014, 22:15:05)
277 | [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
278 | Type "help", "copyright", "credits" or "license" for more information.
279 | >>> import web
280 |
281 | **在Ubuntu上安装Python Webpy -- 另一种方法**
282 |
283 | $ sudo pip install web.py
284 | $ python
285 | Python 2.7.5 (default, Mar 9 2014, 22:15:05)
286 | [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
287 | Type "help", "copyright", "credits" or "license" for more information.
288 | >>> import web
289 |
290 | 备注:安装easy_install或者pip的方法
291 |
292 | $ sudo apt-get install python easy_install
293 | $ sudo apt-get install python pip
294 | 上述方法,二选一
295 |
296 | 到这一步,Webpy就算是安装完成了。太简单了,我们还得再用这个框架干点什么。
297 |
298 | $ cat hello.py
299 | #!/bin/env python
300 | #-*- coding:utf-8 -*-
301 | import web
302 | urls = (
303 | '/', 'index'
304 | )
305 |
306 | class index:
307 | def GET(self):
308 | return "Hello, world!"
309 |
310 | if __name__ == "__main__":
311 | app = web.application(urls, globals())
312 | app.run()
313 | $ python hello.py
314 | http://0.0.0.0:8080/
315 |
316 | 这时,用浏览器访问 [http://localhost:8080/](http://localhost:8080/) 你将看到 "Hello, world!"
317 |
318 | ### JavaScript(nodejs)版
319 |
320 | 现在的JavaScript发展的确飞快,已经不仅在浏览器里可以使用了,这里先简单介绍一下服务器端的node.js的安装与使用。
321 |
322 | **在Ubuntu下安装node.js、npm与express.js**
323 |
324 | 首先确认GCC编译环境的正确安装,否则请:“apt-get install build-essential”
325 | $ wget http://nodejs.org/dist/v0.6.15/node-v0.6.15.tar.gz
326 | $ tar -zxvf node-v0.6.15.tar.gz
327 | $ cd node-v0.6.15
328 | $ sudo apt-get install libssl-dev
329 | $ ./configure
330 | $ make
331 | $ sudo make install
332 | $ node -v
333 | v0.6.15
334 | $ curl http://npmjs.org/install.sh | sudo sh
335 | $ npm -v
336 | 1.1.18
337 | $ npm install express
338 | $ vim test.js
339 | #File Begin
340 | var app = require('express').createServer();
341 |
342 | app.get('/', function(req, res){
343 | res.send('Hello World!');
344 | });
345 |
346 | app.listen(3000);
347 | #File End
348 | $ node test.js
349 |
350 | 打开浏览器,访问[http://localhost:3000/](http://localhost:3000/) 将看到 Hello World!
351 |
352 | ### C/C++版
353 |
354 | 因为在王越的系列文章《Mac OS X背后的故事》里,其中第八章《[三好学生Chris Lattner的LLVM编译工具链](https://www.cnblogs.com/ender-cd/articles/4048486.html)》有对LLVM的介绍,这使我决定尝试把LLVM,作为c语言的hello world项目。
355 |
356 | 说实话,在开源项目中,C语言的各种开源项目的编译安装,都是非常类似的。绝大多数命令都是以下三行:
357 |
358 | $ ./configure
359 | $ make
360 | $ make install
361 |
362 | 当然,在windows下,会麻烦得多。LLVM的安装也非常简单,命令如下:
363 |
364 | $ cd where-you-want-llvm-to-live
365 | $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
366 | $ cd llvm/tools
367 | $ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
368 | $ cd ../projects
369 | $ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
370 | $ svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite
371 | $ cd ..
372 | $ mkdir build
373 | $ cd build
374 | $ ../configure
375 | $ make
376 | $ make check-all
377 | $ make update
378 | $ make install
379 |
380 | 然后,我们可以尝试用LLVM的编译工具链,来编译c语言的代码。
381 | 创建一个文件hello.c
382 |
383 | #include
384 |
385 | int main() {
386 | printf("hello world\n");
387 | return 0;
388 | }
389 |
390 | 编译hello.c,得到hello
391 |
392 | $ clang hello.c -o hello
393 |
394 | 编译c代码,得到LLVM的bitcode文件。
395 |
396 | $ clang -O3 -emit-llvm hello.c -c -o hello.bc
397 |
398 | 第一行以普通方式,执行编译好的可执行文件,第二行调用LLVM JIT,命令为lli,来执行LLVM的bitcode。
399 |
400 | $ ./hello
401 | $ lli hello.bc
402 |
403 | 更多内容可以参考:
404 |
405 | * [Getting Started with the LLVM System](http://llvm.org/docs/GettingStarted.html)
406 | * [参考文档 漫谈C语言及如何学习C语言](http://sunxiunan.com/?p=1661)
407 |
408 | ## 如何克服可能遇到的困难
409 |
410 | **1. 仔细看文档**
411 |
412 | LLVM的文档很有意思,在他开篇头三条是:1. Read the documentation. 2. Read the documentation. 3. Remember that you were warned twice about reading the documentation.
413 |
414 | 是的,认真地,非常认真地阅读相关文档,是最重要的方法。其他的一切方法,都是排在这个后面的。
415 |
416 | 当然,文档的正确性和完整性,也是可以怀疑的。有很多开源项目,往往存在文档bug、文档版本与代码版本不同步等问题。比如LLVM的安装文档,也并非完全正确,我到现在都还不明白,在1.2.3.条那么正经的提示之后,他的第8条,只有configure、make、make check-all、make update,居然没有make install!
417 |
418 | 但是,先看文档,尤其是项目本身的文档,而非二手、三手文档,是必须的第一步。
419 |
420 | **2. 注意依赖,注意版本号**
421 |
422 | 优秀的安装手册,会提示你各种版本依赖问题。在开始正式安装之前,核对各种相关系统、工具、类库的版本,是非常重要的。之前我在安装apache tomcat的时候,就发现用java sdk的最新版JDK7,是不能正确编译的。必须将JDK,退回到JDK6.x,才能正确。
423 |
424 | 说实话,在开源软件安装的时候,估计有60%的问题,都是出在版本错误上。而剩下的40%,多半是看文档不认真的原因。
425 |
426 | **3. 仔细看出错提示信息,并且在网上搜索答案**
427 |
428 | 在编译LLVM的时候,我遇到了一个古怪的bug:“collect2: ld terminated with signal 9 [Killed]”,当时完全不理解是怎么回事,只能在Google上找答案,幸好,类似的悲剧也在别人身上发生过。我找到了一个简明扼要的回答:“You probably ran out of memory.”。于是,我重新调整了Ubuntu虚拟机的内存大小,就编译通过了。
429 |
430 | 事实上,将出错信息的关键一行原文,加上开源项目的名称作为关键词,在google上搜索。通常能够找到相关的答案。
431 |
432 | **4. 不要太早钻研细节**
433 |
434 | 因为是完全从源代码开始安装,所以其实可以有比二进制方式安装多得多的选择。比如configure能够配置的各种参数,一开始最好全部选择缺省,这是因为过早陷入安装的细节,会分散我们学习的注意力。
435 |
436 | **5. 在网上找一找攻略**
437 |
438 | 有很多前人,愿意将自己的安装步骤仔仔细细地记录下来,从而节约我们大量的时间。找到优质的攻略,是事半功倍之道。但是,要特别注意攻略提及的软件版本及相关环境。在网上搜索攻略时,也需要考虑类似情况,比如:不要只是简单的搜索“ubuntu apache source install”,而是搜索包括软件版本的“ubuntu 10.04 64 apache source install”。这样能够避免照着不同版本的攻略,一个劲的死拼,从而浪费了大量的时间。另外,再一次提醒,**不要在百度搜索**。在国内的技术圈,有无数的“开发者”,喜欢反复的转载别人的blog和文章。不但不注明原文来源,甚至连格式、排版都丢失了,内容也难免出现错漏。简直就是一堆垃圾。而在百度搜索,这种垃圾又特别多,躲都躲不开。
439 |
440 | 所以,最好是在Google搜索,如果没办法访问外网,bing也是一个不错的选择!
441 |
442 | **6. 如果很难搞定,不要一条道走到黑,换个方向**
443 |
444 | RP问题,是存在的。喘口气,歇一歇,换个方向。试试别的开源项目吧。
445 |
446 | [上一章](Select-an-open-source-project.md) | [下一章](Understanding-the-source-code.md)
447 |
--------------------------------------------------------------------------------
/zh/Join-the-group.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/Join-the-group.md
--------------------------------------------------------------------------------
/zh/Modify-the-open-source-project.md:
--------------------------------------------------------------------------------
1 | # 修改开源项目
2 |
3 |
4 |
5 | 经过挑选,我决定拿最近比较火爆的开源游戏2048来练手,因为这个项目的规模不大,改起来应该不难。
6 |
7 | ## 改一个游戏来练手
8 |
9 | 众多的2048改编版,都非常类似,就是将数字的加法,变成某种等级序列的递进。比如:两个夏合在一起,变成商;两个商合在一起,变成西周。
10 |
11 | 确立了目标之后,我们需要找到在哪里修改代码,当然,前提是我们得把代码搞到本地来。
12 |
13 | 首先访问:https://github.com/gabrielecirulli/2048 然后fork出一个自己的版本
14 | 例如:https://github.com/zhuangbiaowei/2048
15 |
16 | 然后,在自己的机器上,执行:
17 | git clone git@github.com:zhuangbiaowei/2048.git
18 |
19 | 随后,挑选自己喜欢的编辑器,打开2048的目录,开始查找可以下手的地方。
20 |
21 | 在js目录下的game_manager.js,我们发现了一个函数,叫做:addRandomTile。在这个函数里,有一行是这么写的:`var value = Math.random() < 0.9 ? 2 : 4;` 这种搞法,真的非常粗暴,随机加入一个方块,有90%的概率是2,有10%的概率是4。
22 |
23 | 所以,我也选择了比较粗暴的搞法,在这个js的第一行,加了一句:`NameArray = ['夏','商','西周','春秋','战国','秦','汉','三国','两晋','南北朝','隋','唐','五代十国','宋','元','明','清','民国','新中国'];` 然后把刚才的那句改成:`var value = Math.random() < 0.9 ? NameArray[0] : NameArray[1];`
24 |
25 | 这是唯一的修改,我们可以在浏览器里打开index.html,看看效果。
26 | 
27 | 每次出来的方块,的确是朝代名称了,但是加在一起之后,却全都变成了2。
28 |
29 | 还是在game_manager.js,我们发现了如下一段代码:
30 | ```javascript
31 | var merged = new Tile(positions.next, tile.value * 2);
32 | merged.mergedFrom = [tile, next];
33 |
34 | self.grid.insertTile(merged);
35 | self.grid.removeTile(tile);
36 |
37 | // Converge the two tiles' positions
38 | tile.updatePosition(positions.next);
39 |
40 | // Update the score
41 | self.score += merged.value;
42 |
43 | // The mighty 2048 tile
44 | if (merged.value === 2048) self.won = true;
45 | ```
46 | 看来这就是我们要修改的关键所在了。`tile.value`的值现在是一个字符串,所以不能简单的乘以2,我们可以先找到它在NameArray里的位置,然后取它的下一个值。
47 | ```javascript
48 | var pos =NameArray.indexOf(tile.value);
49 | var merged = new Tile(positions.next, NameArray[pos+1]);
50 | ```
51 | 另外,`merged.value`也不能直接加到`self.score`里去了,要改成:
52 | ```javascript
53 | now_value=Math.pow(2,pos+2);
54 | self.score += now_value;
55 | if (now_value === 2048) self.won = true;
56 | ```
57 | 再运行一下看看,发现了一些丑陋的bug。
58 | 
59 |
60 | 1. 颜色不对,不同的朝代应该有不同的颜色
61 | 2. 字体大小不对,两个字的朝代,有一个字就到下面去了
62 |
63 | 打开Firefox里的Firebug,我们可以查看到问题所在:
64 | 
65 |
66 | 原版的2048,相当粗暴地直接将方块里的内容,当成css的class的内容。因为现在的方块里都变成了汉字,所以我们得将汉字转换成实际的数字。
67 |
68 | 在html_actuator.js中,我们找到了这样一句: `var classes = ["tile", "tile-" + tile.value, positionClass];`
69 |
70 | 我们可以在这一行的前面,补上两句:
71 | ```javascript
72 | var pos =NameArray.indexOf(tile.value);
73 | var tile_value=Math.pow(2,pos+1);
74 | //再修改一下刚才的那句:
75 | var classes = ["tile", "tile-" + tile_value, positionClass];
76 | ```
77 | 于是,正常的颜色就会出现了。至于字体大小的问题,我们得回到main.css中去找答案。
78 | ```javascript
79 | .tile .tile-inner {
80 | border-radius: 3px;
81 | background: #eee4da;
82 | text-align: center;
83 | font-weight: bold;
84 | z-index: 10;
85 | font-size: 55px; }
86 | ```
87 | 我们可以简单粗暴将`font-size: 55px;`,改成`font-size: 35px;`。我们看一下现在的效果:
88 | 
89 |
90 | OK,打完收工!
91 |
92 |
93 | ## 二分查找捉虫记(作者:蒋鑫)
94 |
95 | ### 问题现象
96 |
97 | Git 2.8.0 版本即将发布,今天把工作站的 Git 版本升级到 `2.8.0-rc0`,结果悲剧了。所有使用 HTTP 协议的 Git 仓库都无法正常访问!
98 |
99 | 在确认不是网络和内部的 Git 服务器问题之后,自然怀疑到了 HTTP 代理。果然清空了 `http_proxy` 环境变量后,Git 命令工作正常了:
100 |
101 | http_proxy= git ls-remote http://internal-git-server/git/repo.git
102 |
103 | 可是在我升级之前 Git 工作是正常的啊!又尝试下面命令,即设置一个错误的 http 代理,同时通过 `no_proxy=*` 来绕过代理,
104 | 看看 Git 命令能否正确执行:
105 |
106 | $ http_proxy=bad_proxy no_proxy=* git ls-remote http://internal-git-server/git/repo.git
107 | fatal: unable to access 'http://internal-git-server/git/repo.git/': Couldn't resolve proxy 'bad_proxy'
108 |
109 | 显然新版本的 Git 没有去检查 `no_proxy` 环境变量设置。这个 Bug 是如何产生的呢?
110 |
111 | ### 二分查找
112 |
113 | 将版本切换到 `v2.7.0`,编译安装 Git。(注意一定要安装,而不是执行当前目录下的 Git。这是因为该命令执行过程中会依次调用 `git-ls-remote`
114 | 和 `git-remote-http` 命令,而这两个命令是位于安装路径中的。)
115 |
116 | $ git checkout v2.7.0
117 | $ make -j8 && make install # 我的工作站是四核CPU,故此使用 -j8 两倍并发执行编译
118 |
119 | 测试发现 Git 2.7.0 能够通过 `no_proxy` 变量,绕过错误的 `http_proxy` 环境变量:
120 |
121 | $ http_proxy=bad_proxy no_proxy=* git ls-remote http://internal-git-server/git/repo.git
122 | 206b4906c197e76fcc63d7a453f9e3aa00dfb3da HEAD
123 | 206b4906c197e76fcc63d7a453f9e3aa00dfb3da refs/heads/master
124 |
125 | 那么一定是 `v2.7.0` 和 `v2.8.0-rc0` 中间的某个版本引入的 Bug!
126 |
127 | 想必大家都玩过猜数字游戏吧:一个人在1到100的数字中随意选择一个,另外一个人来猜,小孩子总是一个挨着一个地猜,
128 | 懂得折半查找的大人总是获胜者。Git 提供的 git bisect 这一命令,就是采用这样的二分查找快速地在提交中定位 Bug,
129 | 少则几次,多则十几次就会定位到引入Bug的提交。
130 |
131 | 1. 首先执行下面命令启用二分查找。
132 |
133 | $ git bisect start
134 |
135 | 2. 标记一个好版本。下面的命令使用 tag(v2.7.0)来标记 Git 2.7.0 版本是好版本,换做40位的提交号也行。
136 |
137 | $ git bisect good v2.7.0
138 |
139 | 3. 标记 Git 2.8.0-rc0 是一个坏版本。注意:马上就是见证奇迹的时刻。
140 |
141 | $ git bisect bad v2.8.0-rc0
142 | Bisecting: 297 revisions left to test after this (roughly 8 steps)
143 | [563e38491eaee6e02643a22c9503d4f774d6c5be] Fifth batch for 2.8 cycle
144 |
145 | 看到了么?当完成对一个好版本和一个坏版本的标记后,Git 切换到一个中间版本(`563e384`),并告诉我们大概需要8步可以找到元凶。
146 |
147 | 4. 在这个版本下执行前面的测试操作:
148 |
149 | $ make -j8 && make install
150 | $ git --version
151 | git version 2.7.0.297.g563e384
152 | $ http_proxy=bad_proxy no_proxy=* git ls-remote http://internal-git-server/git/repo.git
153 | fatal: unable to access 'http://internal-git-server/git/repo.git/': Couldn't resolve proxy 'bad_proxy'
154 |
155 | 5. 对这个版本进行标记。
156 |
157 | 这是一个坏版本:
158 |
159 | $ git bisect bad
160 | Bisecting: 126 revisions left to test after this (roughly 7 steps)
161 | [e572fef9d459497de2bd719747d5625a27c9b41d] Merge branch 'ep/shell-command-substitution-style'
162 |
163 | 我们可以机械地重复上面4、5的步骤,直到最终定位。但是人工操作很容易出错。如果对版本标记错了,把 good 写成了 bad 或者相反,
164 | 就要执行 `git bisect reset` 重来。(小窍门:git bisect log 可以显示 git bisect 标记操作日志)
165 |
166 | 于是决定剩下的二分查找使用脚本来完成。
167 |
168 | ### 自动化的二分查找
169 |
170 | Git 二分查找允许提供一个测试脚本,Git 会根据这个测试脚本的返回值,决定如何来标记提交:
171 |
172 | * 返回值为 0:这个提交是一个好提交。
173 | * 返回值为 125:这个提交无法测试(例如编译不过去),忽略这个提交。
174 | * 返回值为 1-127(125除外):这个提交是一个坏提交。
175 | * 其他返回值:二分查找出错,终止二分查找操作。
176 |
177 | 那么就我们先来看看 `git ls-remote` 的返回值:
178 |
179 | * 正确执行的返回值是 0:
180 |
181 | $ http_proxy= git ls-remote http://internal-git-server/git/repo.git
182 | 206b4906c197e76fcc63d7a453f9e3aa00dfb3da HEAD
183 | 206b4906c197e76fcc63d7a453f9e3aa00dfb3da refs/heads/master
184 | $ echo $?
185 | 0
186 |
187 | * 错误执行的返回值是 128!
188 |
189 | $ http_proxy=bad_proxy git ls-remote http://internal-git-server/git/repo.git
190 | fatal: unable to access 'http://internal-git-server/git/repo.git/': Couldn't resolve proxy 'bad_proxy'
191 | $ echo $?
192 | 128
193 |
194 |
195 | 于是创建一个测试脚本 `git-proxy-bug-test.sh`,内容如下:
196 |
197 | #!/bin/sh
198 |
199 | make -j8 && make install && \
200 | git --version && \
201 | http_proxy=bad_proxy no_proxy=* \
202 | git ls-remote http://internal-git-server/git/repo.git
203 |
204 | case $? in
205 | 0)
206 | exit 0
207 | ;;
208 | 128)
209 | exit 1
210 | ;;
211 | *)
212 | exit 128
213 | ;;
214 | esac
215 |
216 | 然后敲下如下命令,开始自动执行二分查找:
217 |
218 | $ git bisect run sh git-proxy-bug-test.sh
219 |
220 | 自动化查找过程可能需要几分钟,站起来走走,休息一下眼睛。再回到座位,最终的定位结果就展现在了眼前:
221 |
222 | 372370f1675c2b935fb703665358dd5567641107 is the first bad commit
223 | commit 372370f1675c2b935fb703665358dd5567641107
224 | Author: Knut Franke
225 | Date: Tue Jan 26 13:02:48 2016 +0000
226 |
227 | http: use credential API to handle proxy authentication
228 |
229 | Currently, the only way to pass proxy credentials to curl is by including them
230 | in the proxy URL. Usually, this means they will end up on disk unencrypted, one
231 | way or another (by inclusion in ~/.gitconfig, shell profile or history). Since
232 | proxy authentication often uses a domain user, credentials can be security
233 | sensitive; therefore, a safer way of passing credentials is desirable.
234 |
235 | If the configured proxy contains a username but not a password, query the
236 | credential API for one. Also, make sure we approve/reject proxy credentials
237 | properly.
238 |
239 | For consistency reasons, add parsing of http_proxy/https_proxy/all_proxy
240 | environment variables, which would otherwise be evaluated as a fallback by curl.
241 | Without this, we would have different semantics for git configuration and
242 | environment variables.
243 |
244 | Helped-by: Junio C Hamano
245 | Helped-by: Eric Sunshine
246 | Helped-by: Elia Pinto
247 | Signed-off-by: Knut Franke
248 | Signed-off-by: Elia Pinto
249 | Signed-off-by: Junio C Hamano
250 |
251 | :040000 040000 de69688dd93e4466c11726157bd2f93e47e67330 d19d021e8d1c2a296b521414112be0966bd9f09a M Documentation
252 | :100644 100644 f46bfc43f9e5e8073563be853744262a1bb4c5d6 dfc53c1e2554e76126459d6cb1f098facac28593 M http.c
253 | :100644 100644 4f97b60b5c8abdf5ab0610382a6d6fa289df2605 f83cfa686823728587b2a803c3e84a8cd4669220 M http.h
254 | 二分查找运行成功
255 |
256 | ### 解决问题
257 |
258 | 既然我们知道引入 Bug 的提交,让我们看看这个提交:
259 |
260 |
261 | $ git show --oneline --stat 372370f1675c2b935fb703665358dd5567641107
262 | 372370f http: use credential API to handle proxy authentication
263 | Documentation/config.txt | 10 +++++--
264 | http.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++
265 | http.h | 1 +
266 | 3 files changed, 85 insertions(+), 3 deletions(-)
267 |
268 |
269 | 相比很多人动辄提交改动了几百、几千行的代码,这个提交的改动算得上简短了。小提交的好处就是易于阅读、易于问题定位、易于回退。
270 |
271 | 最终参照上面定位到的问题提交,我的 Bugfix 如下(为了下面的一节叙述方便,给代码补丁增加了行号):
272 |
273 | 01 diff --git a/http.c b/http.c
274 | 02 index 1d5e3bb..69da445 100644
275 | 03 --- a/http.c
276 | 04 +++ b/http.c
277 | 05 @@ -70,6 +70,7 @@ static long curl_low_speed_limit = -1;
278 | 06 static long curl_low_speed_time = -1;
279 | 07 static int curl_ftp_no_epsv;
280 | 08 static const char *curl_http_proxy;
281 | 09 +static const char *curl_no_proxy;
282 | 10 static const char *http_proxy_authmethod;
283 | 12 static struct {
284 | 13 const char *name;
285 | 13 @@ -624,6 +625,11 @@ static CURL *get_curl_handle(void)
286 | 15 }
287 | 16
288 | 17 curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
289 | 18 +#if LIBCURL_VERSION_NUM >= 0x071304
290 | 19 + var_override(&curl_no_proxy, getenv("NO_PROXY"));
291 | 20 + var_override(&curl_no_proxy, getenv("no_proxy"));
292 | 21 + curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy);
293 | 22 +#endif
294 | 23 }
295 | 24 init_curl_proxy_auth(result);
296 | 25
297 | 26 --
298 | 27 2.8.0.rc0
299 |
300 | ### 写提交说明
301 |
302 | 这个提交是要贡献给 Git 上游的,评审者可能会问我如下问题:
303 |
304 | 1. Bug 的现象是什么?
305 |
306 | “系统的 no_proxy 变量不起作用,git 可能无法访问 http 协议的仓库。”
307 |
308 | 2. 从什么版本引入这个 Bug?
309 |
310 | “我们定位到的这个提交引入的 Bug。之所以会引入这个 Bug,是因为这个提交读取了 `http_proxy` 等环境变量,
311 | 自动通过 `git-credential` 获取的信息补齐 `http_proxy` 的缺失的代理认证口令,并显示设置 libcurl 的参数。”
312 |
313 | 3. 之前的版本为什么没有出现这个问题?什么条件下会出现?
314 |
315 | “之前的版本也会出现问题,但是只有在用户主动设置了 `http.proxy` 配置变量才会出现。
316 | 用户很少会去设置 `http.proxy` 配置变量,而通常是使用 `http_proxy` 环境变量。”
317 |
318 | 4. 你是如何解决的?你的解决方案是否最佳?
319 |
320 | “读取 `no_proxy` 环境变量,并为 `libcurl` 配置相应参数。因为 `libcurl` 只在 `7.19.4` 之后才引入 `CURLOPT_NOPROXY`,因此需要添加条件编译。”
321 |
322 | 实际上,前面的 Bugfix 原本是没有那个条件编译的。即补丁的第18行、22行一开始是没有的,
323 | 在回答第4个问题的时候,我仔细查看了 [libcurl API](https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html),
324 | 发现只有在 `7.19.4` 版本之后,才支持 `CURLOPT_NOPROXY` 参数,因此如果不添加这个编译条件,
325 | 在特定的平台可能会导致 Git 无法编译通过。
326 |
327 | 下面就是最终的提交说明:
328 |
329 | http: honor no_http env variable to bypass proxy
330 |
331 | Curl and its families honor several proxy related environment variables:
332 |
333 | * http_proxy and https_proxy define proxy for http/https connections.
334 | * no_proxy (a comma separated hosts) defines hosts bypass the proxy.
335 |
336 | This command will bypass the bad-proxy and connect to the host directly:
337 |
338 | no_proxy=* https_proxy=http://bad-proxy/ \
339 | curl -sk https://google.com/
340 |
341 | Before commit 372370f (http: use credential API to handle proxy auth...),
342 | Environment variable "no_proxy" will take effect if the config variable
343 | "http.proxy" is not set. So the following comamnd won't fail if not
344 | behind a firewall.
345 |
346 | no_proxy=* https_proxy=http://bad-proxy/ \
347 | git ls-remote https://github.com/git/git
348 |
349 | But commit 372370f not only read git config variable "http.proxy", but
350 | also read "http_proxy" and "https_proxy" environment variables, and set
351 | the curl option using:
352 |
353 | curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
354 |
355 | This caused "no_proxy" environment variable not working any more.
356 |
357 | Set extra curl option "CURLOPT_NOPROXY" will fix this.
358 |
359 | Signed-off-by: Jiang Xin
360 |
361 | ### 贡献给上游
362 |
363 | Git 项目本身是通过邮件列表参与代码贡献的,基本的操作流程是将代码转换为补丁文件,然后邮件发送。
364 | 基本上就是两条命令:`git format-patch` 和 `git send-email`。
365 |
366 | 下面的链接就是 Git 社区关于我这个提交的讨论。Junio已经确认这个提交是 2.8.0 的一个 regression,相信会合入2.8.0的发布版。
367 |
368 | * http://thread.gmane.org/gmane.comp.version-control.git/287843/focus=287888
369 |
--------------------------------------------------------------------------------
/zh/README.md:
--------------------------------------------------------------------------------
1 | 开放文档:《借助开源项目,学习软件开发》。
2 |
3 | 诚邀您的参与!
4 |
5 | # 著作权申明
6 |
7 | * 本作品选择采用:“署名-非商业性使用-相同方式共享”的CC协议。
8 | * 您可以:复制、发行、展览、表演、放映、广播或通过信息网络传播本作品。以及创作演绎作品。
9 | * 惟须遵守下列条件:
10 | * 署名 — 您必须按照作者或者许可人指定的方式对作品进行署名。
11 | * 署名方式为:在转载或新作品开头的显著位置,注明原作者的姓名、来源及其采用的知识共享协议,与本作品在Github上的原发地址建立链接
12 | * 非商业性使用 — 您不得将本作品用于商业目的。
13 | * 相同方式共享 — 如果您改变、转换本作品或者以本作品为基础进行创作,您只能采用与本协议相同的许可协议发布基于本作品的演绎作品。
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/zh/Read-more.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/Read-more.md
--------------------------------------------------------------------------------
/zh/SUMMARY.md:
--------------------------------------------------------------------------------
1 | 0. [前言](Before-start.md)
2 | 1. 这份文档的目标读者
3 | 2. 基本条件
4 | 3. 你需要明确的一些事情
5 | 1. [预备](Start.md)
6 | 1. 学习软件开发的几条主要途径
7 | 2. 为什么借助开源学习是最有效的
8 | 3. 在学习一门语言之前
9 | 4. 选择一门语言
10 | 5. 必须初步掌握的基本功
11 | 6. MOOC 课程
12 | 7. 关于开发工具
13 | 1. 关于开发工具的分类(by 李路)
14 | 2. 各种参考资料
15 | 8. [版本管理,包管理和语言环境搭建](Hello-world.md)
16 | 1. 下载源代码的N种办法
17 | 1. 关于源代码管理与版本控制
18 | 2. 寻找早期开源项目的源代码
19 | 3. SVN、Git、Mercurial快速介绍
20 | 4. 基于包管理的方式获取源代码
21 | 2. 让代码运行起来
22 | 1. Ruby版
23 | 2. PHP版
24 | 3. Java版
25 | 4. Python版
26 | 5. JavaScript版
27 | 6. C/C++版
28 | 3. 如何克服可能遇到的困难
29 | 2. [如何选择开源项目](Select-an-open-source-project.md)
30 | 1. 到哪里去寻找开源项目
31 | 2. 什么样的开源项目适合初学者
32 | 3. 值得推荐给大家的开源项目
33 | 4. 各语言的Awesome List
34 | **重点讲解:按语言,按难度选择示例讲解**
35 | 3. [理解源代码](Understanding-the-source-code.md)
36 | 1. 寻找文档,熟悉功能,先玩一遍,记下功能。
37 | 2. 静态理解:
38 | 1. 目录结构
39 | 2. 包名与文件名
40 | 3. 类名、函数名与变量名
41 | 4. 注释与Readme
42 | 5. UML图
43 | 6. 外部文档
44 | 3. 动态理解
45 | 1. 输出日志
46 | 2. 设置断点与单步跟踪
47 | 3. 抛出异常
48 | 4. 修改代码,破坏性尝试
49 | 4. 主线与支线
50 | 1. 寻找入口
51 | 2. 跟踪关键流程
52 | 3. 寻找挂接点
53 | 5. 外围代码
54 | 1. 必须存在的外围功能
55 | 2. demo/example
56 | 3. 单元测试
57 | 6. 知其所以然
58 | 4. [修改开源项目](Modify-the-open-source-project.md)
59 | 1. 改一个游戏来练手
60 | 2. 二分查找捉虫记
61 | 5. [为开源项目做贡献](Contribute-to-an-open-source-project.md)
62 | 1. 提bug与建议
63 | 2. 帮助完善文档
64 | 3. 提交代码(功能代码与测试代码)
65 | 4. 周边代码(demo/扩展/子项目)
66 | 5. 外部宣传
67 | 6. 其他各种杂务
68 | 6. [成为组织的一员](Join-the-group.md)
69 | 1. 交流圈
70 | 2. 组织结构
71 | 3. 开源项目的组织方式
72 | 4. 基本礼仪
73 | 7. [自己发起一个开源项目](Create-an-open-source-project.md)
74 | 8. [延伸阅读](Read-more.md)
75 | 1. [指导开发者快速学习编程的网站推荐](Useful-Websites-to-Learn-How-to-Code-Quickly.md)
76 | 9. [贡献者](Contributor.md)
77 | 10. [开源问答](FAQ.md)
78 |
--------------------------------------------------------------------------------
/zh/Select-an-open-source-project.md:
--------------------------------------------------------------------------------
1 | # 3. 选择一个开源项目
2 |
3 |
4 |
5 | ## 3.1. 到哪里寻找开源项目
6 |
7 | ### 开源基金会
8 |
9 | 大部分开源项目都来自于开源社区,而大部分开源社区背后都有基金会在运作,比较知名的有Apache基金会(以Java技术为主的开源软件),Linux基金会(专注于Linux系统的开源软件),Eclipse基金会(专注于基于Eclipse IDE的开源软件),Jboss基金会(专注于JAVA EE方面的开源项目)等。每个基金会都会有目前该基金会正在进行的项目列表,我们可以从其中寻找自己感兴趣的项目。
10 |
11 | * Apache:[https://projects.apache.org/projects.html?name](https://projects.apache.org/projects.html?name)
12 | * Linux:[http://www.linuxfoundation.org/programs](http://www.linuxfoundation.org/programs)
13 | * Eclipse:[http://www.eclipse.org/projects/listofprojects.php](http://www.eclipse.org/projects/listofprojects.php)
14 | * Jboss:[http://www.jboss.org/projects](http://www.jboss.org/projects)
15 |
16 | ### 开源项目托管网站
17 |
18 | 另外,每个开源项目都需要有自己的管理平台,各大基金会的开源项目也不例外,因此,各个开源项目的托管网站是也是一个寻找开源软件的好去处。
19 |
20 | 目前在业界比较知名的项目托管网站主要有SourceForge,GitHub。
21 |
22 | 微博上的@OpenERP_Jeff 补充说:[launchpad](https://launchpad.net/)是一个很重要的开源hosting网站,著名的开源项目有ubuntu、mysql和zope。项目计划、蓝图、代码库、bug管理、翻译都很完整。
23 |
24 | | 服务提供商 | SVN | Git | Mercurial | 介绍 |
25 | | ---------------------------------------- | ---- | ---- | --------- | ---------------------------------------- |
26 | | [Google Code](http://code.google.com/) | 支持 | 支持 | 支持 | Google Code属于“富二代”,其在速度上,使用体验上都优于其他几个托管网站,其中最值得一提的是其丰富的帮助文档,许多文档还有中文版本。因此,对于初学者来说,比较容易上手,也可以获得一个很好的学习机会。当然,因为都是google.com的域名,所以时不时的会访问不了管理界面,原因大家懂的。另外,因为使用简单方便,相应的其在功能上就相对较弱一点。但是应付一般的项目还是绰绰有余。注:**已经于2016年4月1日关闭了** |
27 | | [Sourceforge](http://http//sourceforge.net/) | 支持 | 支持 | 支持 | SourceForge可以算是开源界的托管始祖,很多古老的,知名的开源项目都托管在它上面,其对开源界的贡献估计可以和Apache对 Java界的贡献相提并论了。因此,其在功能上经过了长时间的考验,大家想要的功能都能找到。不过,因为强大,其上手难度也相对较高,而且全英文界面,对于英文较弱的同学来说也是一件很痛苦的事。 |
28 | | [Github](http://github.com/) | 支持 | 支持 | 不支持 | GitHub属于托管界的新贵,伴随着Git的蓬勃发展而发展。越来越多的开源软件使用Github托管。最近因Rails漏洞被Hacker黑了也让其处于媒体的风口浪尖。这个事件从一个侧面反映了其在业界的影响力。 |
29 | | [CodePlex](http://www.codeplex.com/) | Yes | Yes | Yes | 微软的开源项目基地 |
30 | | [BitBucket](https://bitbucket.org/) | No | Yes | Yes | Python的项目在上面比较多 |
31 | | [launchpad](https://launchpad.net/) | No | No | No | 使用[bzr](http://bazaar.canonical.com/)管理代码,项目很多,如Ubuntu等,中国大陆访问速度巨慢无比 |
32 |
33 | 维基百科有一个词条,列出了非常非常多的开源托管服务的比较:
34 |
35 | * [Comparison of open source software hosting facilities](http://en.wikipedia.org/wiki/Comparison_of_open_source_software_hosting_facilities)
36 | * [自由软件主机服务比较](http://zh.wikipedia.org/wiki/%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6%E4%B8%BB%E6%9C%BA%E6%9C%8D%E5%8A%A1%E6%AF%94%E8%BE%83)
37 |
38 | ### 技术社区
39 |
40 | 像ITeye、InfoQ、OSChina、CSDN等国内知名的技术社区都非常关心开源软件的发展,在社区新闻、月刊等载体上都有最新的,流行的开源软件介绍。同时在社区,还有一个很大的好处,你会找到很多志同道合的朋友,这可是学习过程中的一大乐事。
41 |
42 | ### 各大科技公司的研究院
43 |
44 | Google的BigTable论文,Amazon的Dynamo论文开启了目前火热的云计算时代,各大科技公司对技术领域的引领能力毋庸置疑,同时,很多公司也是开源运动的忠实支持者,像国外的Google、Facebook、Yahoo、国内的淘宝、百度、~~盛大~~、豆瓣等,连曾经的坚决反对者 Microsoft也开始通过赞助Apache基金会扭转自己在开源界的形象。关注各大科技公司的研究院最新的开源软件可以了解目前整个业界的技术趋势,而且他们开源的软件的未来发展前景都比较看好,因此,是一个寻找开源软件的有效途径。
45 |
46 | ### 谷歌编程之夏(Google Summer of Code)
47 |
48 | 我个人觉得GSoC是一个寻找开源项目的好地方。原因有以下几点:
49 |
50 | 1. GSoC有一个[历年来的参与者列表](https://www.google-melange.com/archive/gsoc)([https://www.google-melange.com/archive/gsoc](https://www.google-melange.com/archive/gsoc)),这个列表中的有各种各样的开源组织可以让想参与的人挑选(今年的列表上有180个组织)。
51 | 2. 参与者列表上的组织是经过一定的审核才选出来的,选拨出来的组织一般质量比较好,社区活跃度也很高。
52 | 3. 列表上的组织为了吸引参加人员,一般在项目的主页上会有专门的wiki为参加人员导航(比如这个[DragonFlyBSD项目](http://www.dragonflybsd.org/docs/developer/gsoc2012student/)([http://www.dragonflybsd.org/docs/developer/gsoc2012student/](http://www.dragonflybsd.org/docs/developer/gsoc2012student/))),很适合新手快速了解这个项目。
53 | 我想即使无法参加GSoC本身,通过GSoC的预热也是一个很不错的机会,可以让想要参与开源项目的人有一个很好的入口。
54 |
55 | 注:本小节来自于Ashi的邮件,在此表示感谢!
56 |
57 | ### 搜索引擎
58 |
59 | 如果您对某类技术特别感兴趣,或者遇到某个技术难题想找业界成熟的解决方案,搜索引擎(Google,Bing等)都是一个不错的工具,其在我们寻找开源软件的过程中也起同样的作用。通过一些关键词的罗列就能帮助我们找到感兴趣的开源项目。
60 |
61 | ### 博客和微博
62 |
63 | 关注各个领域大牛们的博客和微博,他们会紧跟技术节奏给我们推荐他们领域最新的开源软件,甚至会为我们讲解这些开源软件的底层实现原理,带领我们入门,这是多么高尚的行为啊。
64 |
65 | 关注各大科技公司的博客和微博,他们也会经常透露自己的开源计划,以及分析业界的一些开源软件在自己公司内部的应用,这对我们深入了解一个开源软件的技术价值有很大的帮助。
66 |
67 | ### 微信公众号
68 |
69 |
70 |
71 | ### 技术问答网站
72 |
73 | 这是最直接的一个方式,在知乎、StackOverflow、Quora等问答网站直接请人推荐几款开源软件,工程师的热情会让你受宠若惊的,很有可能向你推荐某个开源软件的就是这个开源软件的创始人。
74 |
75 | ### 维基百科
76 |
77 | 在维基百科上,有很多辛勤的人们,在整理着各种相关的资料,例如:
78 |
79 | * [http://en.wikipedia.org/wiki/Open-source_software](http://en.wikipedia.org/wiki/Open-source_software)
80 | * [http://en.wikipedia.org/wiki/List_of_open_source_software_packages](http://en.wikipedia.org/wiki/List_of_open_source_software_packages)
81 | * [http://en.wikipedia.org/wiki/Comparison_of_open_source_software_hosting_facilities](http://en.wikipedia.org/wiki/Comparison_of_open_source_software_hosting_facilities)
82 |
83 | 等等,在其中搜索相关的词条,还能发现很多的宝藏。
84 |
85 | ## 3.2. 什么样的开源项目适合初学者
86 |
87 | ### 缘起
88 |
89 | 说实话,在当初列这个提纲的时候,我并没有想好如何写这一节。但是,开放地做事情,就常常会有奇妙的事情发生,佛家称之为“助缘”,各种对这件事情有帮助的缘分,都会在不经意间出现。
90 |
91 | 一位叫李军的朋友,给我发来邮件,信中写道:“我想是否我们能够通过沟通,然后你再对我有些了解,给我指出点建议,并且是详细的建议,我看学apache开源框架应该不错的,不知道我是否适合,谢谢。期待你的回复。”
92 |
93 | 在与他的往来邮件中,我也真的将这一节渐渐地想清楚了。另外,在与李军的讨论中,我还发现,需要开辟一个专门的章节,讨论:“学习开源项目,能够提升软件开发中的哪些能力。”
94 |
95 | 在此,我想对李军表示感谢,更希望有越来越多的朋友,参与到这个文档的讨论中来,相信它会变得越来越完善。
96 |
97 | ### 明确自己的目的
98 |
99 | 选择一个开源软件,首先要明确的,是自己的动力何在。是出于兴趣?还是出于工作需要?比如,有人对于搜索引擎特别感兴趣,想了解搜索引擎是怎么做出来的?那么首先可以考虑先寻找一些专业的书籍,来了解一些关键的知识点。如果对于某一领域的知识点,缺乏必要的了解,可能完全无法理解一个项目里的代码。在掌握初步的知识以后,自然可以去找Lucene、Sphinx来学习。也可能是出于工作需要,比如平时是用PHP开发Web应用,已经在用某一个常见的PHP框架了,希望能够对这个框架有一个深入的学习了解,甚至希望横向地比较多个不同的PHP Web框架,这些都是非常清晰的目的。自然在学习的过程中,不太会迷失方向。
100 |
101 | 比较危险的一种,是听说某某项目很有名气,甚至是为了将来找工作比较容易,就贸然一头扎进某个项目中去了。怀有这种学习目的的人,往往会选择到那种很庞大,也很成熟的项目,打开文件夹一看,成百上千的源文件,根本无法看完,一下子就懵了,再就是颓了。心想自己大概不是学软件开发的料吧~~
102 |
103 | ### 优先选择能够独立运行的项目
104 |
105 | 开源的项目有很多种类,能够独立运行的项目,当然很多。但是也有不少项目,是其他开源项目的插件、类库、扩展包之类的东西,这些在一开始接触开源的时候,最好不要涉猎,因为理解他们,可能会需要理解他们背后的那个庞然大物,往往会遭遇很多难解的细节,一不小心,就进行不下去了。
106 |
107 | 当然,还有一类项目,他们虽然是独立运行,但是想要让他们独立运行成功,还得安装、配置很多其他的依赖项目,这个往往会让初学者特别绝望,搞了一个礼拜,居然这个项目都还没有运行起来...
108 |
109 | 所以,小的、能够独立运行的、不依赖于太多其他项目的开源项目,可以优先选择。
110 |
111 | PS. 在Docker出现以后,运行一个项目,往往只需要一行简单的命令。在Github上,也能找到很多demo项目,或者是docker-compose.yml文件,这些是很好的入手点。
112 |
113 | ### 选择活跃的项目
114 |
115 | 项目的活跃程度,包括两个部分,一个是开发者提交新代码的频繁程度。另一个是在社区中对于这个项目的讨论热烈程度。提交代码越是活跃,提交的人越多,越能证明这个项目是很有价值的,也证明这个项目是值得你花精力去学习的。而项目在社区讨论的热烈程度,则能够确保当你遇到问题的时候,能够搜索到别人的答案,或者你自己提问以后,能够有人热心回答你。
116 |
117 | 当然,活跃程度都是相对的,如果你真的对一个项目感兴趣,可以直接试着给这个项目的作者发邮件,提问题。大多数开发者都会很高兴有人关注他的项目,也会通常会热心的回答你的问题的。
118 |
119 | ### 判断代码质量
120 |
121 | 并非所有的开源项目,都是高手写的,都值得你去学习。事实上,有很多垃圾开源项目,代码仔细一看,写得真是一塌糊涂。所以,试着阅读一下这个项目的代码。至于如何判断一个项目的代码质量,之前我在知乎回答过一个类似的问题“如何让自己写的代码易维护?”,推荐各位朋友参考一下。
122 |
123 | 当然,更加推荐的,是阅读《Clean Code》一书,非常好的一本介绍如何提高代码质量的书。附一篇书评,可以一读:[《写代码犹如写文章》](http://book.douban.com/review/5199308/)
124 |
125 | ### 选择合适的版本
126 |
127 | 最后,面对已经发展了多年的开源项目,最好不要选择最新的版本。如果你是在工作中想要使用这个项目,当然应该选择最新的稳定版,甚至测试版、 beta版。但是如果是出于学习的目的,为了减少复杂度,快速地理解这个项目的核心结构与开发思想,选择第一个稳定版,是一个比较妥当的办法。
128 |
129 | 然后,在初步理解了第一个版本的代码之后,再不断地通过阅读changelogs,追踪最新的版本中的代码变更,体会作者修改代码的目的、手法与技巧。这样应该会有很大的收获。
130 |
131 | ## 3.3. 值得推荐给大家的开源项目
132 |
133 | | 项目名称 | 语言(平台) | 所属领域 | 推荐理由 |
134 | | ---------------------------------------- | ----------------------------- | ------------- | ---------------------------------------- |
135 | | [Petshop4.0](http://msdn.microsoft.com/en-us/library/Aa479070) | NET | 企业开发 | 1.微软官方用来展示.Net企业开发实力的项目,架构优雅;2.涉及中小型企业开发常用技术;3.网络资源较多 |
136 | | [Haozesfx](http://haozesfx.codeplex.com/) | NET | Winform,SIP协议 | 1.基于飞信实现的开源项目,实用性强,方便二次开发;2.结构清晰,设计成熟;3.实现了SIP协议 |
137 | | [ThinkPHP](http://www.thinkphp.cn/) | PHP | Web框架 | 1.应用较为广泛的Web开发框架,成熟稳定;2.集成多项先进的设计思想;3.活跃的社区支持和完善的中文文档(帮助手册,Demo,代码注释) |
138 | | [Nginx](http://nginx.org) | C/Linux/Unix/windows/MAC | 基础设施 | 代码优秀简洁,插件系统牛逼,HTTP协议可谓当今码农的必备知识 |
139 | | [bottle](http://bottlepy.org) | Python/Linux/Unix/windows/MAC | web开发 | 代码优秀简洁,3000多行代码(包括注释)搞定web server |
140 | | [memcached](http://memcached.org/) | C | 基础设施 | Free & open source, high-performance, distributed memory object caching system。by Jun Guo |
141 | | [Docker](https://docker.com/) | Go | 容器,基础设施 | 目前最热容器技术的基石,有孙宏亮《Docker源代码解读》可供参考 |
142 |
143 | ## 3.4 各语言的Awesome List
144 |
145 | github中有人总结过各个语言在不同的应用方向上值得推荐的开源项目列表, 即Awesome List. Awesome List不仅可以方便大家找到优秀的项目进行学习, 还可以让大家方便地找到各种已有的轮子来进行开发.
146 |
147 | | 语言/平台 | Awesome List 地址 |
148 | | ---------------- | ----------------|
149 | | Java | [awesome-java](https://github.com/akullpp/awesome-java) |
150 | | c++ | [awesome-cpp](https://github.com/fffaraz/awesome-cpp) |
151 | | python | [awesome-python](https://github.com/vinta/awesome-python) |
152 | | go | [awesome-go](https://github.com/avelino/awesome-go) |
153 | | javascript(浏览器) | [awesome-javascript](https://github.com/sorrycc/awesome-javascript) |
154 | | nodejs | [awesome-nodejs](https://github.com/sindresorhus/awesome-nodejs) |
155 | | .net | [awesome-dotnet](https://github.com/quozd/awesome-dotnet) |
156 | | .net core | [awesome-dotnet-core](https://github.com/thangchung/awesome-dotnet-core) |
157 | | ruby | [awesome-ruby](https://github.com/markets/awesome-ruby) |
158 | | php | [awesome-php](https://github.com/ziadoz/awesome-php) |
159 | | rust | [awesome-rust](https://github.com/rust-unofficial/awesome-rust) |
160 | | dart | [awesome-dart](https://github.com/yissachar/awesome-dart) |
161 | | ios(Objective-C和swift) | [awesome-ios](https://github.com/vsouza/awesome-ios) |
162 | | android | [awesome-android](https://github.com/snowdream/awesome-android) |
163 |
164 |
165 | [上一章](Start.md) | [下一章](Hello-world.md)
166 |
167 |
--------------------------------------------------------------------------------
/zh/Start.md:
--------------------------------------------------------------------------------
1 | # 开始
2 |
3 |
4 |
5 | ## 学习软件开发的几条主要途径
6 |
7 | ### 一万小时的神话
8 |
9 | 前一阵子我在网上与人讨论一个一万小时的话题。有一本叫做《异类》的书中说到这样的观点:世上本没有绝对的天才,天才也需要超过1万小时的训练。人人都有可能成为顶级高手。具体可以参考一篇流传甚广的文章《[怎样练习一万小时](https://www.geekonomics10000.com/519)》
10 |
11 | 在这种理论的基础上,有人提出了“一万小时编程训练”的概念,似乎经过一万小时以上的训练,普通人也有可能成为编程领域的“大师/高手”。但是,这个理论其实是一个貌似建立在统计学基础上的伪理论。
12 |
13 | 首先是范围,多大的一个范围,算是一个领域呢?编程是一个大的范围,编译器或者数据库编程是其中两个不同的领域。如果有人用一万小时专注于编译器的开发,他们对于数据库方面的编程,可能是一窍不通的。那么,这种人,算不算编程领域的大师呢?如果有人用一万小时专注于汇编语言的编程,那么对于新出现的面向对象的脚本语言,能够有多高的水平呢??
14 |
15 | 其次是训练,在一万小时的相关统计中,提到了舞蹈、音乐等众多需要反复练习的领域,而这种针对熟练程度的训练,真的是编程领域需要的吗?当然,我相信提高打字速度,的确有助于提高代码编写的速度,但是这真的有助于提高编程的能力吗?要想在软件开发这个领域,讨论如何才算是训练了一万小时的编程,会非常困难。
16 |
17 | 最后是关于知识更新,在一个每天都在诞生新名词,新技术,新思路的领域,一个曾经埋头苦练一万小时的高手,在3年不接触最新知识以后,还能称之为高手吗?
18 |
19 | 总之,匆匆忙忙地接受了一万小时的概念,被激励得热血沸腾,打算下定决心奋力学习一万小时编程,通常不过是“励志书中毒”的症状而已。
20 |
21 | ### 软件开发的能力体系是怎样的?
22 |
23 | 在很多领域,我们都可以用一个金字塔模型,来描述该领域的能力体系,在软件开发领域,同样如此。
24 |
25 | 
26 |
27 | 简单解释一下:
28 |
29 | 低的三项,属于知识类。基础知识包括计算机、数学、算法、逻辑等等知识,这些知识,通过认真地学习书本教材,基本能够掌握。
30 |
31 | 编程技能,往往是跟具体的语言相关的,当然,多学几门不同的语言,对于快速掌握一门新的语言,大有帮助。
32 |
33 | 领域知识,则是与工作的具体方向有关,比如针对多媒体领域的编程,自然要熟悉图形、声音等等的相关领域知识。针对企业级应用的开发,对于管理制度、财务、成本、仓储的东西,总得搞清楚才行。
34 |
35 | 中与高的两项,属于超越编程局限的通用能力,不仅仅是软件开发上用得到,在各方面都非常需要这三类能力。逻辑能力,可以通过训练提高;理解能力,可以通过经验积累;而创造能力,的确比较难,有天赋的成分在其中。
36 |
37 | ### 有哪些途径,可以锻炼这些能力?
38 |
39 | * 阅读与习题:找到一堆的经典教科书,狠狠地读,认真地把书里的习题都给做了,这样对于打下扎实的基础,将会有极大的帮助。
40 |
41 | * 视频教程/ScreenCast:每次讲解一个主题,学习一下总会有收获,只是效率不高。
42 |
43 | * MOOC课程的出现,正在改变这样的现状,不过国内的MOOC课程大多是渣(简单的把视频教程搬上来就称为MOOC)
44 | * 比较好的英文MOOC平台有Coursera(https://www.coursera.org),edX(https://www.edx.org)
45 |
46 | * PPT/Slide/PDF:这种属于某次技术会议上的演讲稿,如果能够配合视频看,效果还好些,否则通常会不知所云。
47 |
48 | * Wiki:针对某个词条,某个特定的问题,会有相当清晰的解释,不过要看运气,有些词条的解释就非常粗略,甚至过时。
49 |
50 | * Blog:在分享知识与经验的过程中,blog是很不错的载体,如果你能够找到的话。
51 |
52 | * BBS:曾经是最主要的学习方式,很多人通过泡论坛来提高自己,不过说实话,效率很低,而且容易跑题。
53 |
54 | * 邮件组:的确存在着不错的一些邮件组,不过不好找,欢迎多多推荐。
55 |
56 | * 问答社区(StackOverFlow/Quora/知乎):
57 |
58 | 新兴的交流社区,在面临特定问题时,可以尝试搜索或提问。平时多泡泡社区,努力回答别人的问题,也有助于自己的提高。
59 |
60 | * 工作中的项目:当然,老板给你发工资,肯定希望你尽快完成,在压力之下,通常进步都会很快。只是这种进步也许是你无法选择的。
61 |
62 | * QQ群:真的有人借助QQ群来学习吗?
63 |
64 | * 开源项目/开源社区:当然,这个是最重要的,咱们下节详细说。
65 |
66 | ## 为什么要学习
67 |
68 | 学习有不同的目的:有人学习是因为兴趣或者好奇;有人是为了增加生存的技术,把学习作为改变工作、生活状态的手段;当然,也有些人,学习是为了思想的交流,与周围的人交流,与远方的朋友交流,与过世的先哲交流。
69 |
70 | 静下心来,仔细想想自己为什么要学习很重要。如果学习的目的不明确,学习就缺少源动力。这种思考在学习之初是需要的,在学习过程中也同样是需要的。因为随着学习的进行,个人对学习的态度、感受也会发生变化,学习的目的也需要及时的调整。
71 |
72 | 一个善于学习的人,是能充分利用各种学习机会进行学习实践的人。有人七十多岁开始学画油画,也有人利用每天坐地铁的时间学会一门外语,甚至还有些人把微博、网络公开课作为学习的重要工具。只要学习目的明确了,学习就变成了一件有意义的事,因而才可能持久。
73 |
74 | 生物进化了几百万年,才使人类有了学习的能力,这种能力是区别于一般动物的。人类的学习是一个觉醒的过程,近百年人类文明高速演进,特别是互联网的出现,使学习从原始的环境适应演进为主动的创造并迅速转为社会向上的推动力,或者向下的破坏力。
75 |
76 | ### 为什么借助开源学习是最有效的
77 |
78 | 当今社会,大多数人都离不开机器的使用,而机器又依赖于程序的控制。学习编程不仅仅是软件工程师的事,它应该成为每个社会成员的一个基本的技能。正如语言是人类交流的基本技术,编程是人与机器交流的基本技能。学会编程,可以使机器按照你的意志运行,使每个人按自己的兴趣整合信息资源,以利于更有效地学习。
79 |
80 | 软件是近百年发展最快的技术之一,特别是随着智能手机与平板电脑的普及,软件技术更是渗透到了我们生活的各个方面。学会编程,并不意味着要去建立一个复杂的系统。其实写个报表的计算公式或者做一个小动画也可以是一种编程的体验。
81 |
82 | 软件编程需要的基本环境就是一台电脑,当然如果有互联网的接入则更利于交流与技术信息的查询。
83 |
84 | 使用Linux最大的好处是它本身就是一个软件开发的开放平台,你可以方便地下载各种开发工具,比如gnu c/c++,python或者其它。你应该学会使用apt-get,这是一个Ubuntu下强大的软件包管理工具。
85 |
86 | 在网站kernel.org上,有各种版本的内核源代码,如果你想从根本上学习操作系统,也可以通过LFS快速地学习内核构建的过程。
87 |
88 | 源代码开放的最大的好处是我们不需要重复设计和制造轮子。每个人都可以在软件巨人的臂膀上构造自己的梦想代码天堂。
89 |
90 | 无论从美国的facebook、谷歌、苹果还是从中国的华为成功的经验中我们都可以看到,开源的代码以及开源的项目是当前众多商业公司的技术立足之根本。开源已经造就了无数商业神话。我们大部分人只知道苹果的酷,但很少有人在苹果的版权说明中,看到有关开源项目的罗列。
91 |
92 | 微软的比尔盖茨以及苹果的乔布斯大家耳熟能详,但对软件产业最有影响力的人应该是出生于芬兰的李纽斯(Linus Torvalds)。谷歌正是采用Linux为内核,才使android几乎在一夜之间窜红并重创诺基亚。而李纽斯在软件界的影响力,堪比罗马教皇。
93 |
94 | 有一部电影叫源代码,也是对代码开源化的一个隐喻。如果你读到了关键的源代码,也许你真的可以改写历史。当然,李纽斯说得很好,开源应该是快乐的,“Just for fun”。我们不需要太多的使命感与焦虑,改变世界也许只是一个顺带的结果。
95 |
96 | 源代码是我们最好的营养。
97 |
98 | ### 方向不对,努力白费
99 |
100 | 在中国,如果你想面朝大海,应该是一路向东。当然向西也是可以的,不过要多费些周折。技术的更新非常快,但如果把握了大势往往可以事半功倍。
101 |
102 | 举一个实际的例子:十多年前,PHP是一个相对冷门的编程工具。在很多场合,很多人都不好意思说自己是搞PHP开发的。而如今,PHP已经成为主流的开发工具,很多搞.net的人出于生计的考虑,不得不转向Java或者PHP。
103 |
104 | > 这个例子不妥,语言只是载体、工具,任何语言都能达成自己的目的。
105 | >
106 | > 以前父母总是以这样的方式去教育孩子,这个专业(语言)很热门,薪水很高...
107 |
108 | 选择开发工具只是软件工匠们需要认真定夺的一个方面。其它如系统构架、测试方法、团队管理、决策者眼光等等,更是关系每个程序员未来的诸多要素。
109 |
110 | ### 开源的精神内涵使学习变得更加有意义
111 |
112 | 在商业极度发展的今天,人们对物质的无限追求使很多人忘记了生活的本质。人被异化为物的附属品,价值被虚拟的概念、标签重置。
113 |
114 | 互联网的出现,促进了人类相互之间的沟通。软件高速更新发展的自然需求和因团队协作所带来的有效性、高效性造就了一个全新的文化:开源文化。软件便于分享、开源代码便于扩展的特质,使以Linux操作系统为代表的开源项目迅速崛起。大批的软件工程师不仅通过开源项目找到了精神寄托、同道中人,而且还找到了与商业社会有效融合的模式与渠道,解决了事业与兴趣结合的问题,实现了生活、学习、工作甚至社会公益的完美统一。
115 |
116 | 在开源精神的感召下,学习变得更加积极主动。
117 |
118 | 在分享、贡献的核心价值体系下,人们能充分体会人心温情的另一面。与传统商业社会利用信息不对称在交易中图谋利益最大化不同,开源世界里的人们在创造、协作的过程中完成一个又一个不断成长的软件系统,这些系统有些使整个社会运行更有效、当然也有的在损坏甚至危及社会的安全。人类精神世界的两面性在开源世界里更直接、更激烈地表现出来,正在影响着现实的诸多方面。
119 |
120 | ### 开源社区是最好的学校
121 |
122 | 软件是构建虚拟世界的基础,而开源社区则是软件新技术产生、发展的主要场所,因而也是学习软件技术最好的学校。
123 |
124 | 当前最大的网络社区应该算游戏社区,这个社区的人大多是在消费社会资源。而开源社区则分化成两个阵营:一个是以创新、创造为目的,创造社会价值;另一个则是以破坏、非法取得信息资源为目的,损毁社会资源与体系。
125 |
126 | 在开源社区里,有大量热心的程序员,他们乐于分享自已对技术的理解、心得,他们通过各自的行动扩大自已的影响力,在协助别人的同时不断加深自己对技术的理解程度和实践能力。而新的社区加入者也可以在与社区互动的过程中找到自己技术与精神的导师(Mentor),正如电影黑客帝国(Matrix)中尼欧(Neo)遇到摩菲(Morpheus)。
127 |
128 | 如果说我们生活的世界是上帝创造的,那么我们对面的这个数字的世界则是由程序员创造的。数字世界与现实世界不断地融合,使现实世界与虚拟世界的边界变得越来越模糊。在学校课堂里,陈旧的教学方法、过时的教学内容、有限的学习资源是无法与互联网上丰富的开源社区资源相比的。社区内部团队协作的自发性、自主性、可靠性也极大地提高了社区成员学习的效率,并使个体超常规成长成为可能。
129 |
130 | 在媒体上经常看到十、三四岁的少年创造一个个软件项目的奇迹,殊不知这与国外成熟的开源社区发展息息相关。如果国内开源社区渐渐发展起来了,我们有理由相信在不久的将来,我们的周围会出现众多皮尔斯·富里曼(Pierce Freeman)这样的天才少年。
131 |
132 | ### 移动互联网时代,学习是开放的更是开源的
133 |
134 | 随着智能手机、平板电脑的普及,学校以及教室的功能将被弱化,人们可以在各种公共场所组成形式多样的学习社区。而开源社区提供多种专业技术人员以及业余爱好者面对面交流的机会。有的地方还出现了包括软件、硬件开源的创客空间。大家在无线网络环境下快速组成学习社区,分享交流最新的技术,互相协助解决各种技术问题。发现的志同道合的朋友,有的技术团队在天使投资者的支持下,在学习的过程中还可以建立创业团队。
135 |
136 | 在企业的内部,根据企业的发展战略,也可以形成企业内部的开源社区,通过开源项目整合企业内部与外部的技术资源。开放的心态使企业以开源文化的发展为契机引领技术的潮流。
137 |
138 |
139 |
140 | ## 在学习一门语言之前
141 |
142 | 你至少应该对计算机科学有所了解,当然你也可以不管不顾,在没有任何基础的情况下,直接开始学习一门编程语言,但是,随着面对的问题越来越困难,你还是会深切感受到,补习基础知识的重要性。
143 |
144 | 这里推荐一个不错的计算机科学入门MOOC课程:
145 |
146 | [斯坦福大学 计算机科学入门课程](https://www.coursera.org/course/cs101)
147 |
148 | 它面向无任何基础的学生,介绍计算机科学的基本知识:
149 |
150 | * 计算机和代码的本质,它们能做哪些事情,不能做哪些事情
151 | * 计算机硬件如何运作:芯片、CPU、内存和存储设备
152 | * 必备术语:bits(二进制位)、bytes(字节)、megabytes(百万字节)、gigabytes(千兆字节)
153 | * 软件如何运作:什么是程序,什么叫做“运行”
154 | * 数码图片是如何实现的
155 | * 计算机代码:循环和逻辑
156 | * 大概念:抽象、逻辑和程序缺陷
157 | * 结构化数据是如何实现的
158 | * 互联网是如何实现的:ip 地址、路由、以太网、wi-fi
159 | * 计算机安全:病毒、木马和密码,噢我的天啊!
160 | * 模拟和数字
161 | * 数字媒体、图片、声音、视频、压缩
162 |
163 | 在了解了计算机科学之后,你就可以开始选择一门语言来进行学习。
164 |
165 | ## 选择一门语言
166 |
167 | **首先需要说明,这里所讨论的选择语言,并非工作中开发语言的选择,而是出于学习软件开发,提高软件开发能力的目的,讨论如何选择语言。**
168 |
169 | ### 一些基本的判断依据
170 |
171 | * 最好是跨平台/平台无关的语言。比如Java、Ruby、Python、PHP、JS这样的语言。
172 |
173 | .NET平台的众多语言,因为mono的存在,现在也算是跨平台的了。
174 |
175 | * 这门语言所创建的开源项目,要足够多,可供选择。C/C++、Java、Python、PHP都
176 |
177 | 可以非常好的满足这个条件,随着github平台的出现,Ruby的开源项目现在也越来越
178 |
179 | 多的了。随着nodejs的兴起,JS的开源项目也呈现明显的上升趋势。
180 |
181 | * 语言以及语法本身,要具备较好的可读性。这里我非常推崇Ruby,因为这门语言从创立
182 |
183 | 之初,就是极端重视代码可读性的,整个Ruby社区的风格,也非常强调代码的简洁优雅。
184 |
185 | * 相关的文档资料容易查找,这方面大多数流行语言都符合条件。C/C++、Java、PHP、C#、
186 |
187 | Python都已经极为丰富了。
188 |
189 | * 最好身边有能够随时请教的这门语言的高手。如果有了这一条,其他都无所谓了。
190 |
191 | * 最好能够至少分别学习一门静态类型语言与一门动态类型语言。
192 |
193 | ### 推荐一些语言学习网站
194 |
195 | * 《笨办法学语言》系列,详见下节的介绍
196 | * [CodeCombat](http://codecombat.com/) 通过游戏闯关,一步一步学习语言,而且这还是一个开源项目
197 | * [指导开发者快速学习编程的网站推荐](Useful-Websites-to-Learn-How-to-Code-Quickly.md)
198 | * [菜鸟教程](https://www.runoob.com/)包括了所有常见语言的入门级教程,适合新手。
199 | * [W3school](https://www.w3school.com.cn/p.asp)也包括了一些常见语言的入门级教程,适合新手学习。
200 | * 当然,各个语言的官方网站,也是必须常去的查询的
201 |
202 | ### 一些忠告
203 |
204 | * 不要根据流行的编程语言排行榜,选择语言
205 |
206 | * 不要根据某某语言最容易找工作,薪酬水平最高,来选择语言
207 |
208 | * 不需要贪图掌握太多的语言
209 |
210 | 越是深入的学习一门语言A,越是能够快速的学习另一门语言B。A和B可以是任何两种语言。努力深入透彻的掌握目前正在使用的这门语言,深入、再深入。这些努力,在你以后要学习其他语言的时候,一定会有回报的。
211 |
212 | ### 一点建议
213 |
214 | * 选择深入的语言,其实就是选择一种生活方式
215 | * 各种开发语言都有最适合的工作领域
216 | * 各种开发语言的技术社区在中国各自有各自的文化
217 | * 选择日常可以用到的开发语言深入进去,事半功倍 ;-)
218 | * 选择hacker 界公认的好语言,坚持学习,总是能得到养份的,获得多少,看能坚持多久!
219 | * 这里公认的是指 Lisp —— Paul Graham在The root of LISP 里曾经曰过:
220 |
221 | > “吾观之,自古语言模型者,惟 C 与 LISP 简洁而隽永,高山仰止,
222 | >
223 | > 后来者皆取 C 之形,循 LISP 之神也。”
224 |
225 | ### 推荐语言
226 |
227 | **这个列表,可以不断扩充,也欢迎大家补充自己的推荐语言与推荐理由**
228 |
229 | 首选语言:
230 |
231 | 如果以常规的应用开发为目的来学习一门语言,那么面向对象类型的语言(java,freePascal,.net)能
232 |
233 | 够让你养成严谨的基于对象分类思索模式的开发习惯,这会是一个好的开始。
234 |
235 | 如果是为了快速开发建站,那么php,ruby,nodejs,python不失为一个选择。
236 |
237 | 不过可能到了后面需要补坑。
238 |
239 | | 语言名称 | 主要开源项目 | 推荐理由 |
240 | | ------ | ------------------------- | ---------------------------------------- |
241 | | ruby | Ruby On Rails | 动态语言,简洁清新 |
242 | | java | Tomcat | 经典的面向对象静态语言,长盛不衰,优秀项目多如牛毛 |
243 | | python | scipy, nltk, django, ansi | 最接近人类语言的通用语言,在开源的科学计算领域一骑绝尘,在数据挖掘、web开发、系统管理等领域也为表现突出 |
244 | | c | lua,mongrel2 | 面向过程的,存在于所有平台,历史悠久的语言。如果你的未来应用方向是嵌入式开发的话这是首选 |
245 | | nodejs | sails.js,angular,coffee | 疯狂的科学家们在用js做一系列的不可思议的事情,有一统的趋势 |
246 |
247 | [对比语言元素: PHP, Perl, Python, Ruby](http://hyperpolyglot.org/scripting)
248 |
249 | 其实选用哪一个语言并不重要,关键是你要能使用该语言去控制,去驱使计算机。
250 |
251 | ## 必须初步掌握的基本功
252 |
253 | 以下所讨论的基本功,其实是一个相当宽泛的概念。很难确切的定义一个门槛:不到某种程度,你就无法学习开源了。而是说,在掌握了一些必要的能力之后,再开始学习,会学得不那么辛苦。
254 |
255 | ### 计算机基础知识
256 |
257 | 计算机相关的基础知识,其实相当琐碎,很多人都是在日常的使用与开发过程中,逐步掌握的。在了解各种各样的零零碎碎的知识同时,对于各种知识及其相互关联,有一个整体上的把握,我称之为“地图思维”,是非常重要的。
258 |
259 | 简单来说,计算机相关的基础知识主要包括:基本操作与使用;计算机体系结构;网络基础知识;算法导论等等。
260 |
261 | * 计算机操作与使用:
262 |
263 | * 会初步使用至少一种操作系统吧;
264 | * 会自己装一个虚拟机(VirtualBox什么的都可以);
265 | * 知道常见的文件格式如何打开;
266 | * 知道去哪里下载并安装相关的应用软件;
267 | * 诸如此类的知识。推荐一个网站:[我爱电脑网](http://www.woaidiannao.com/)真心觉得不错,那些乱七八糟的广告可以略过。
268 |
269 | * 计算机体系结构(组成原理):
270 |
271 | * 《[深入理解计算机系统](http://book.douban.com/subject/5333562/)》
272 |
273 | 书评:《[NB学校的NB课程的NB教材--CSAPP](http://book.douban.com/review/3150951/)》
274 |
275 | * 网络基础知识:
276 |
277 | * 《[计算机网络](http://book.douban.com/subject/1179807/)》,
278 | * 书评:《[我看过的最好的网络入门书](http://book.douban.com/review/2304950/)》
279 |
280 | * 算法与设计:
281 |
282 | * 《[Algorithms](http://book.douban.com/subject/4854123/)》
283 | * 书评:《[大家好,我是译者](http://book.douban.com/review/5337314/)》
284 | * 《[设计模式 可复用面向对象软件的基础](http://book.douban.com/subject/2279416/)》
285 | * 《[代码大全](http://book.douban.com/subject/1951158/)》
286 | * 《[程序设计实践](http://book.douban.com/subject/1096711/)》
287 |
288 | * 数学基础:
289 |
290 | * 《[具体数学-计算机科学基础](http://book.douban.com/subject/1231910/)》
291 |
292 | * 语言:
293 |
294 | * [java编程思想](http://book.douban.com/subject/2061172/)
295 | * [Google Java 编程规范](http://google.github.io/styleguide/javaguide.html)
296 | * [C编程一站式学习](http://akaedu.github.io/book/)
297 |
298 | ### 至少掌握一门编程语言
299 |
300 | 听上去似乎是废话,如果连语言都没有掌握,怎么可能开始学习开源软件,看人家的源代码呢?不过,怎样才算掌握了一门语言呢?能够写出Hello World,自然是不算的。掌握这门语言的基本语法,肯定也是不够的。也许找一本某某语言的经典教材,然后把后面的习题都给做出来,的确算是一个简单的办法。不过,编程语言实在太多,相关的经典教材,就更是多不胜数。这里就不再一一推荐了。
301 |
302 | 不过特别想推荐一个《笨办法学语言》系列,目前有:Python、Ruby、C、Regex、SQL、CLI六种。引用我觉得最有道理的一段话: “不要复制粘贴。你必须手动将每个练习打出来。复制粘贴会让这些练习变得毫无意义。这些习题的目的是训练你的双手和大脑思维,让你有能力读代码、写代码、观察代码。如果你复制粘贴的话,那你就是在欺骗*自*己,而且这些练习的效果也将大打折扣。” 相关链接如下:
303 |
304 | * [Learn code the hard way](http://learncodethehardway.org/)
305 | * [《笨办法学 Python 》在线中文版](http://readthedocs.org/docs/learn-python-the-hard-way-zh_cn-translation/en/latest/)
306 | * [Python初学者(零基础学习Python、Python入门)书籍、视频、资料、社区推荐](https://github.com/Yixiaohan/codeparkshare)
307 |
308 | ### 熟练掌握搜索引擎的使用
309 |
310 | * 第一戒律:尽可能在Google,而不是Baidu搜索。对于软件开发而言,Google才是最佳武器。
311 | * 不断地积累关键字:一个内容你搜索不到,只是因为你没有听说过那个关键字。比如,我想要找一个图像处理的开源项目,如果你知道 “Computer Vision”是指计算机视觉,那么直接搜“Open Source Computer Vision”,OpenCV一定就会是第一个结果。如果你知道OpenCV,那么想要找一个2D图像转换成3D图像的技术,有没有开源实现,就可以试着搜“2D to 3D OpenCV”,也许就会更快地找到想要的内容。当你对某个领域完全没有了解时,可以先试着搜索一些周边词汇,看看相关的文档,然后了解行内人是用哪些关键词的,然后再去搜索,就会迅速地缩小范围。
312 | * 搜索出错信息:当然,当你遇到错误时,直接把错误输出放到Google里去搜索,也说不定就会遇到和你有相同遭遇的同学,看看别人是怎么解决的。
313 | * 尝试各种专业的、垂直的搜索引擎:比如StackOverFlow或者Quora这样的专业问答社区,koders 则是一个源代码搜索的引擎。google search里的Blog、Discussions里也有不少好东西。
314 | * 2019Google镜像地址:http://ac.scmor.com/ 包含谷歌学术镜像与网页镜像。
315 | * ~~到百度试试手气:毕竟人家也抓了不少网页了,说不定会有Google没抓到的呢?~~
316 | * 不,任何时候,都不要去百度碰运气,你可以选择的搜索引擎有很多:Bing、Yahoo...
317 |
318 | ### 英语不能太差
319 |
320 | 当然,这个更加是没底的事情,只是我自身英文也非常差,所以没资格教育别人,推荐余晟老师的一篇博客,供大家学习:[《关于程序员学英语的经验》](http://www.luanxiang.org/blog/archives/1236.html)
321 |
322 |
323 |
324 | ## MOOC 课程
325 |
326 | 注意: **绝大部分是英文课程**
327 |
328 | ### Python
329 |
330 | * [计算机科学及Python编程导论](https://www.edx.org/course/introduction-computer-science-mitx-6-00-1x-0#.U_HC-_mSxSU)
331 |
332 | * 这个是非常棒的计算机开发入门课程(授课老师Prof. Eric Grimson是MIT的副校长)
333 |
334 | * 用python语言作为示范讲解
335 |
336 | * [中文字幕](http://open.163.com/special/opencourse/bianchengdaolun.html)(建议和英文字幕对照看)
337 |
338 | ### Java
339 |
340 | 1. [Intro to Java Programming Building Programs with Classes & Objects](https://www.udacity.com/course/intro-to-java-programming--cs046)
341 | 2. [Java编程导论 - 第1部分:开始使用Java编程](https://www.edx.org/course/introduction-programming-java-part-1-uc3mx-it-1-1x#.VQZrMo6Ueo0)
342 | 3. [Introduction to Java Programming – Part 1](https://www.edx.org/course/introduction-java-programming-part-1-hkustx-comp102-1x)
343 | * 香港大学 港式英语很High
344 |
345 | ### C
346 |
347 | * [程序设计入门——C语言(浙大)](http://www.icourse163.org/course/zju-199001#/info)
348 | * [计算机程序设计-C 台湾大学](https://www.coursera.org/course/cprogramming)
349 |
350 | ### 计算机体系结构(组成原理)
351 |
352 | * [The Hardware/Software Interface](https://www.coursera.org/course/hwswinterface)
353 | * 这门Coursera的课程几乎完全取材于《深入理解计算机系统》这本书,连编程作业都是完全照搬CSAPP在CMU的作业
354 | * 很棒
355 | * 先修知识:
356 | * Introductory programming in C or Java
357 | * familiarity with binary numbers
358 |
359 | ### 算法
360 |
361 | * 算法
362 | * [算法,第一部分(普林斯顿大学)](https://www.coursera.org/course/algs4partI)
363 | * [算法,第二部分(普林斯顿大学)](https://www.coursera.org/course/algs4partII)
364 | * 教材:《[Algorithms](http://book.douban.com/subject/4854123/)》
365 |
366 | ## 关于开发工具
367 |
368 | * 关于这个话题,我在知乎上发起了一个话题,欢迎参考。[关于开发/编程工具,你有哪些心得或给初学者的建议?](http://www.zhihu.com/question/20302904)
369 | * 过犹不及:所有的工具,都是为了提高我们的开发效率而存在的,但是,如果为了那些工具,投入了太多的精力,则可能舍本逐末,忘记了自己的根本目标。也许有人会说,磨刀不误砍柴功,但是,千万不要只顾磨刀,忘记砍柴啊。
370 | * 对于初学者而言,GUI是更加自然的方式。虽然,计算机的发展过程,是先有命令行,后有图形界面。但是,键盘、鼠标的综合运用,会更加容易被人掌握。当然,随着熟练程度的增加,纯用键盘操作,加上花样繁多的快捷键,会大大的提高操作的效率。再进一步,有一些优秀的GUI工具,极其丰富的支持各种快捷方式,同时又兼顾图形界面的美观与方便,是最值得推荐的。但是,还是回到那句话:过犹不及。
371 | * 好的教程,会帮助我们的熟悉开发工具,我一直认为TextMate的迅速普及,是由于RailsCast的功劳。因此,花时间找一些靠谱的教程,尤其是视频教程,会很有效。
372 | * 开发人员,往往会有两个误区:一是频繁地挑选、比较多种开发工具;二是长时间埋头于自己最常用的那个工具,对于外面世界的发展毫无兴趣。我的个人建议是,定期抬起头来,看看新工具的进展与介绍。1~2年为一个周期就好,不用太频繁。
373 | * 知其然,更要知其所以然。千万不要变成被工具惯坏了的程序员。
374 | * 不要总试图要汉化它(by 李焕林)
375 | * 工具是给懒人用的,不是给傻子用的。(by 程劭非)
376 | * 还会不定期地补充一些心得进来...
377 |
378 | ### 关于开发工具的分类(by 李路)
379 |
380 | 我认为开发工具分三类,需区别对待:
381 |
382 | 1. 可以使用一辈子的工具,学习路径几乎没有尽头,值得在职业初期就好好考虑,仔细斟酌进行选择,并在整个生涯中不断努力力求学到更多,你的工作效率会因为这种努力不断提高。如:
383 |
384 | ```
385 | * 编辑器: emacs, vim
386 | * 基本操作系统环境:如bash
387 | * 基本编程语言: c / lisp
388 | ```
389 |
390 | 2. 任何时候都需要掌握的工具,这类工具总是每隔一个周期就有新的产品出现,取代掉旧有的产品,但相对来说是值得学习的,能保持一个较长的时代的有效期,如:
391 |
392 | * 版本控制系统:git
393 | * 社交网络: stack overflow / github
394 | * 写作工具: markdown / reStructureText / latex / html
395 | * 通用编程语言: python / ruby / javascript
396 |
397 | 3. 特定领域需要的工具,此类工具往往时效性较短,不断被新产品取代,一旦掌握,能在特定领域获得非常高的效率,但缺点是很快会过期,通常是几年之内
398 |
399 | * 各类编程框架:rails / backbone
400 | * 各类测试框架:xunit / rspec
401 | * 用户行为分析工具: ga
402 | * 各类设计工具: balsamiq
403 | * 各类项目管理,代码集成工具: github / trac / basecamp / redmine
404 |
405 | ### 各种参考资料
406 |
407 | 以下链接尽可能都给英文维基百科的link,分类页尽可能给维基百科里的Category页
408 |
409 | * [Programming tool](http://en.wikipedia.org/wiki/Programming_tool)
410 | * [Text editors](http://en.wikipedia.org/wiki/Category:Free_text_editors)
411 | * [Emacs](http://en.wikipedia.org/wiki/Emacs)
412 | * [Vim](http://en.wikipedia.org/wiki/Vim_%28text_editor%29)
413 | * [JEdit](http://en.wikipedia.org/wiki/JEdit)
414 | * [Notepad++](http://en.wikipedia.org/wiki/Notepad%2B%2B)
415 | * [Sublime Text](http://en.wikipedia.org/wiki/Sublime_Text)
416 | * [Atom](https://atom.io/) Github 出品 纯coffeescript(nodejs)开发,我喜欢
417 | * [Integrated development environments](http://en.wikipedia.org/wiki/Integrated_Development_Environment) / [IDE List](http://en.wikipedia.org/wiki/Category:Free_integrated_development_environments)
418 | * [Emacs](http://en.wikipedia.org/wiki/Emacs)
419 | * [Dev-C++](http://en.wikipedia.org/wiki/Dev-C%2B%2B)
420 | * [Eclipse](http://en.wikipedia.org/wiki/Eclipse_%28software%29)
421 | * [NetBeans](http://en.wikipedia.org/wiki/NetBeans)
422 | * [Cloud9 IDE](http://en.wikipedia.org/wiki/Cloud9_IDE)
423 | * [Code::Blocks](http://en.wikipedia.org/wiki/Code::Blocks)
424 | * [KDevelop](http://en.wikipedia.org/wiki/KDevelop)
425 | * [Revision control software](http://en.wikipedia.org/wiki/Category:Free_revision_control_software)
426 | * [SVN](http://en.wikipedia.org/wiki/Apache_Subversion)
427 | * [Git](http://en.wikipedia.org/wiki/Git_%28software%29)
428 | * [Mercurial](http://en.wikipedia.org/wiki/Mercurial)
429 | * [Test-driven development](http://en.wikipedia.org/wiki/Test-driven_development) / [Behavior Driven Development](http://en.wikipedia.org/wiki/Behavior_Driven_Development)
430 | * [xUnit](http://en.wikipedia.org/wiki/XUnit)
431 | * [RSpec](http://en.wikipedia.org/wiki/RSpec)
432 | * [Rapid prototyping tools](http://garmahis.com/reviews/wireframe-tools/)
433 | * [Balsamiq Mockups](http://en.wikipedia.org/wiki/Balsamiq)
434 | * [Axure RP Pro](http://en.wikipedia.org/wiki/Axure_RP)
435 | * [Project management software](http://en.wikipedia.org/wiki/Category:Free_project_management_software)
436 | * [Bugzilla](http://en.wikipedia.org/wiki/Bugzilla)
437 | * [XMind](http://en.wikipedia.org/wiki/XMIND)
438 | * [Redmine](http://en.wikipedia.org/wiki/Redmine)
439 | * [Trac](http://en.wikipedia.org/wiki/Trac)
440 | * [MediaWiki](http://www.mediawiki.org/wiki/MediaWiki)
441 |
442 | ### 关于英文资料
443 |
444 | 回应Shi YiMin的评论:"大学一、二年级的新生看这个英文的资料是不是会有点困难?"。
445 |
446 | 我觉得,还是要努力地去看吧,如果发现理解有困难,再去寻求各种帮助。毕竟相比对应的中文版,英文版的内容质量要好得多。再者,维基百科里的这些内容,主要还是简介性质的,不算太难。
447 |
448 |
449 |
450 | [上一章](Before-start.md) | [下一章](Select-an-open-source-project.md)
451 |
--------------------------------------------------------------------------------
/zh/Understanding-the-source-code.md:
--------------------------------------------------------------------------------
1 | # 理解源代码
2 |
3 | 在这一章中,只打算讨论以命令式编程范型为主的语言,因为其他的编程范型的开源项目,笔者接触太少了(期待各类达人多多补充)。
4 |
5 | ## 静态理解
6 |
7 | 阅读一个开源项目的源代码,通常都很容易。大多数开源项目的托管网站,都提供了无需下载,直接阅读源代码的功能,比较有趣的是,大家可以比较一下 SourceForge、Google Code以及Github的查看源代码的功能。这分别代表了老、中、青三代开源托管平台,对于查看代码的重视程度。
8 |
9 | ### 目录结构
10 |
11 | 好的开源项目,通常会选择合理的目录结构,来组织自己的代码。而所谓合理,通常意味着遵循约定俗成的规范。比如:
12 |
13 | |目录名|含义|
14 | |------|----|
15 | |conf/configure|各种配置文件|
16 | |src/source|项目的源代码|
17 | |doc/document|项目文档|
18 | |test/unittest|单元测试|
19 | |tools/utils|相关工具|
20 | |lib|库文件|
21 | |app|应用相关的文件(在web项目中经常出现)|
22 | |controllers|控制器,在遵循MVC模式的Web项目中,经常出现|
23 | |models|模型,在遵循MVC模式的Web项目中,经常出现|
24 | |views|视图,在遵循MVC模式的Web项目中,经常出现|
25 | |db|数据库相关文件|
26 | |demo/example|相关示例代码|
27 | |misc|其他杂项|
28 | |include|头文件所在目录,C/C++项目中常见|
29 | |out/build|编译结果输出目录|
30 | |third_party/vender|第三方库|
31 | |install|安装所需的相关文件|
32 |
33 | ### 包名与文件名
34 |
35 | 在软件体系中,包(Package)是一个很重要的概念,与模块(Module)类似,但是又有所区别。一个项目,在初始设计时,就需要做模块划分,每一个大小合适的模块,往往就可以作为一个开发工作单元,分配给某个开发者完成。当然,对于那种大型的、复杂的项目,还需对模块做进一步的细分,比如:子模块(Sub Module)。而包(Package),则往往具有一定的可重用性。我们可以认为,一个模块,开源出去未必会有人来用。而一个设计良好的包,本身就可以作为一个开源项目,放出去给被人使用。
36 |
37 | 因此,从更加有利于软件开发的协作的角度来说,合理的命名包,就变得非常重要。
38 |
39 | 越是现代的开源项目,越是懂得不必一切从零开始搭建。所以我们常常会发现,一个开源项目,他们自己会开发一组Package,同时也依赖一批别人开发的Package。在静态理解项目时,了解一个项目有哪些包,以及依赖哪些包,就非常重要。
40 |
41 | 举例之一:Rails是一个著名的Ruby开源项目。我们访问它的[Github主页](https://github.com/rails/rails),就可以看到这个项目的源代码结构。
42 |
43 | * 首先需要选择查看某一个稳定版本,比如3.2版
44 | * https://github.com/rails/rails/tree/3-2-stable
45 | * 然后阅读install.rb文件
46 | * https://github.com/rails/rails/blob/3-2-stable/install.rb
47 | * 我们可以看到的内容,主要包含两大部分:
48 | * 编译Rails的依赖包:activesupport、activemodel、activerecord、activeresource、actionpack、actionmailer、railties。这些都是Rails项目自己开发的包
49 | * 然后再编译Rails本身
50 | * Rails本身的包描述文件是:rails.gemspec
51 | * https://github.com/rails/rails/blob/3-2-stable/rails.gemspec
52 | * 通过阅读rails.gemspec,我们可以了解到,Rails这个项目,依赖的包还包括:bundler、sprockets-rails。
53 | * 事实上,通过阅读activesupport等一系列包的.gemspec文件,我们还会发现更多的外部依赖包。
54 |
55 | 不同的项目,描述包文件,以及包依赖关系,有各种不同的格式。需要一一分别学习。这里就不再详细解说了。
56 |
57 | 在一个开源项目中,代码当然是由一个一个的源代码文件组成的。通过查看文件名,往往可以了解一个文件的大概内容。例如:
58 |
59 | * errors.rb,通常会与出错处理有关
60 | * i18n.rb,通常会与国际化有关
61 | * logger.rb,通常会与日志有关
62 | * json目录下的两个文件decoding.rb和encoding.rb,自然是JSON格式的编解码相关代码
63 |
64 | 通常,要迅速的辨认出一个文件名的含义,与领域知识大有关系。例如:http.rb,通常会是处理http协议相关。而request和response,则通常是网络协议中的请求与响应相关的处理代码。对于这些单词的熟悉程度,决定了我们阅读与理解代码的迅捷程度。
65 |
66 | ### 类名、函数名与变量名
67 |
68 | Java是一门很讲究规范的语言,所以他的每一个类,就会对应一个同名的.java文件(内部类除外)。这使得我们寻找类所在的源文件,变得非常简单。当然,这样会造成源文件数量的增加,也许会有人不喜欢。
69 |
70 | 不同的语言,对于命名有其自己的规范,我们可以做一个列表,来简单列出这些规范。
71 |
72 | |语言|包/命名空间命名|类命名|函数/方法命名|常量命名|变量命名|
73 | |----|---------------|------|-------------|--------|--------|
74 | |Java|domainname.package 全部都是小写的单词,以.区隔|ThisClassName 每个单词都以大写字母开头|theMethodName 第一个单词以小写字母开头|THE_VALUE 全部大写,单词以下划线分隔|theValue 与函数名一致|
75 | |C#|DomainName.Package 每个单词都以大写字母开头,以.区隔|ThisClassName 每个单词都以大写字母开头|TheMethondName 与类名一致|THE_VALUE 全部大写,单词以下划线分隔|TheValue 与类名一致|
76 | |PHP|domainname.package 全部都是小写的单词,以.区隔|ThisClassName 每个单词都以大写字母开头|theMethodName 第一个单词以小写字母开头|$THE_VALUE 全部大写,单词以下划线分隔|$theValue 与函数名一致|
77 | |C/C++|std::hex 全部小写,以::区隔|CThisClassName 以大写C开头,后续是大写字母开头的单词|TheMethodName 每个单词以大写字母开头|nMAX_VALUE 特别会引入前缀的概念,例如:n代表整形、b代表布尔型、c代表字符型等等|nTheValue 与常量类似,单词区分大小写|
78 | |Delphi|MyUnit.Unit2 遵循Pascal命名法:一个名字里如果包含多个单词,每个单词的首字母都要大写,以.区隔|TThisClassName 以大写T开头,后续是大写字母开头的单词|TheMethodName 每个单词以大写字母开头|castMaxValue 特别会引入前缀的概念,例如:i代表整形、b代表布尔型、c代表字符型等等,cast代表常量|iTheValue 与常量类似,单词区分大小写|
79 | |Ruby|Module::SubModule 每个单词以大写开头,以::区隔|ThisClassName 每个单词都以大写字母开头|the_method_name 全小写单词,以下划线分隔,!?有特定的含义|MAX_VALUE 全大写单词,以下划线分隔|the_value 全小写单词,以下划线分隔|
80 | |Python|mod_submod 全部小写,以_区隔|ThisClassName 每个单词都以大写字母开头|the_method_name/theMethodName 全小写单词,以下划线分隔,也可以类似Java的命名,私有函数以双下划线开头|MAX_VALUE 全大写,以下划线分隔|the_value 全小写,以下划线分隔|
81 | |JavaScript|无|ThisClassName 每个单词都以大写字母开头|thePrivateMethod/ThePublicMethod 私有函数小写字母开头,公有函数以大写字母开头|MAX_VALUE 全大写,下划线分隔|theValue 小写字母开头,私有变量,加下划线|
82 |
83 | 这是一个非常粗略,挂一漏万的表格,详细的命名规范,请参考各种具体语言的命名规范文档。
84 |
85 | ### 注释与Readme
86 |
87 | 很多时候,开源项目代码里的注释不仅不会帮助读者理解,反而会带来误导。或者因为语言表述让人不知所云,或者是用特定的缩写符号表示的只写给自己看的TODO,或者是改了代码而没有改注释,这些反而不利于读者理解代码,甚至造成理解错误。因此我强烈地不建议读者过于重视阅读注释。
88 |
89 | 但是,在业内有一种流派,非常重视注释,而且信奉从源代码的注释,就可以直接生成项目的开发文档。比如JavaDoc这样的东西,在Java的开源项目里,简直用到泛滥,也造成了Java的很多项目,注释数量比代码的数量还要多。而且,格式规范,千篇一律(为了生成Document),真正有意义的注释内容,少之又少。纯粹是干扰阅读。
90 |
91 | 很多时候,我都建议阅读代码,就真的去读代码。然后试着从类名、方法名、变量名中,大致“猜出”代码的意义。然后再实际地将代码运行起来,看看执行过程中,这些代码是如何工作的。
92 |
93 | 总之,不到万不得已,不要先看注释。
94 |
95 | 虽然我个人对于注释,相当的不重视,但是却非常认同Readme的价值。令我倍感欣慰的是,Github的创立者,也完全赞成这一点。他们将一个项目的首页,直接规定为“代码展示+Readme”,也就强迫所有在Github上安家的开源项目,将更多的精力,投注到Readme的撰写中去。这样形成的良性循环,使得我们可以乐观的预期:越来越多的开源软件,将会越来越重视项目根目录下的Readme文件的价值,将一个项目最为重要的内容,以最为精炼的方式,在Readme中,以结构良好的方式,展现出来。
96 |
97 | 因此,首先阅读Readme,对于了解一个开源项目,是一个非常好的选择。
98 |
99 | ### UML图
100 |
101 | UML是一种软件建模语言,全称为:统一建模语言(UML,Unified Modeling Language)。非常巧合的是,在打算写这一小节的今天,@蔡学庸 发了两条微博:
102 |
103 | > 有时候我会一边读源码,一边将我的理解画成图。这是我最近读源码画的图,还没有美化处理。
104 | >
105 | > 阅读源代码时,将代码顺手图像化,有助于我思考与记忆。位置、色彩、形状,这些都是我将源代码图像化时会采用的手段。
106 |
107 | 我非常期待,他能够就这个问题,谈到更多的心得。在我看来,在阅读源代码的时候,不断记录,在脑海里形成整个项目的全景图像,是非常有帮助的。
108 |
109 | 关于UML的定义,可以参考维基百科: [UML](http://zh.wikipedia.org/wiki/UML),以下引用一段:
110 |
111 | > 统一建模语言(UML,Unified Modeling Language)是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。
112 | >
113 | > UML集成了Booch,OMT和面向对象软件工程的概念,将这些方法融合为单一的,通用的,并且可以广泛使用的建模语言。UML打算成为可以对并发和分布式系统的标准建模语言。
114 | >
115 | > UML 并不是一个工业标准,但在Object Management Group的主持和资助下,UML正在逐渐成为工业标准。OMG 之前曾经呼吁业界向其提供有关对象导向的理论及实现的方法,以便制作一个严谨的软件建模语言(Software Modeling Language)。
116 | >
117 | > 有很多业界的领袖亦真诚地回应OMG,帮助她建立一个业界标准。
118 |
119 | 在UML系统开发中有三个主要的模型:
120 |
121 | * **功能模型**: 从用户的角度展示系统的功能,包括用例图。
122 | * **对象模型**: 采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类图。
123 | * **动态模型**: 展现系统的内部行为。包括序列图,活动图,状态图。
124 |
125 | 在学习开源软件时如何使用UML,有以下一些经验和忠告:
126 |
127 | * 不用使用工具,自动化的生成UML。自己手绘或者用Umbrello这样的开源工具自己绘制,将大大提高阅读并理解代码的能力。
128 | * 首先建立对象的静态模型,也就是先画“类图”。
129 | * 在UML规范之外,可以加一些辅助自己记忆的符号,这个没有一定的规矩,方便好记就行。
130 | * 其次在动态理解的过程中,对关键的执行路径,画出时序图(Sequence Diagram),将有助于深入理解项目的执行过程。
131 | * 对于非面向对象的软件项目,可以参照类图与组件图的模式,画出模块图。也有助于加深理解。
132 | * UML本身有越来越复杂,越来越学术化的倾向,要适可而止。
133 |
134 | ### 外部文档
135 |
136 | 开源项目的文档水平,有如下几个层次:
137 |
138 | * 没有文档(比这个更糟糕的,是有一些错漏的,长时间没有更新的垃圾文档)
139 | * 有一个根据代码注释自动生成的XXDoc,通常这样的文档,价值很低。还不如直接去看代码。
140 | * 有一个简单的综述性质的文档,至少告诉你一个项目的大概。
141 | * 有完整的项目文档,这样的项目已经非常罕见了。
142 | * 有各国志愿者帮助翻译的多语言文档。这样的项目,通常已经是世界一流的项目了。
143 | * 有专门的文档、博客、甚至图书,《XX项目源码解读》之类。一般只有Linux、MySQL这样的项目,才有这样的待遇吧。
144 |
145 | 一般来说,外部文档的可信度并不高,而且往往过时。不到走投无路,我不建议找外部文档来帮助理解。当然,一些太复杂的项目,作为入门导引,看看也无妨。
146 |
147 | ZoomQuiet补充:可以借用 CMMI 的几个层次来类比出文档的层次:
148 |
149 | * 0级: 无文档
150 | * 1级: 号称有文档
151 | * 2级: 有可用文档
152 | * 3级: 文档完备
153 | * 4级: 文档丰富
154 | * 5级: 文档开放,可持续完善
155 |
156 | ## 动态理解
157 |
158 | 所谓动态理解,就是让项目运行起来,在运行项目的过程中,理解一个项目是如何运行的。(这个有点像绕口令了。。。)
159 |
160 | ### 输出日志
161 |
162 | 所谓日志,在软件领域,通常是指程序运行的一种记录。开发者与维护人员,可以通过分析日志,了解程序的运行状况。日志输出的数量多寡,可以分为以下几种:
163 |
164 | * 完全没有输出(这不是一种好的做法)
165 | * 有出错与崩溃时的输出日志(主要用于排除故障)
166 | * 打开某个参数配置的开关,例如将日志级别修改为debug,将会输出更多的日志信息(主要用于调试程序)
167 | * 为了理解特定的片段,直接修改代码,增加更多的日志输出,甚至将代码执行过程中的所有相关变量,全都输出出来。(用于查找疑难杂症,深入理解源代码等目的。)
168 |
169 | ZoomQuiet补充:同前,应该使用相同的递进分析层次
170 |
171 | * 0级: 无日志
172 | * 1级: 号称有日志
173 | * 2级: 有可用日志
174 | * 3级: 日志级别完备
175 | * 4级: 日志粒度可调节
176 | * 5级: 有通用日志服务,可集中分析
177 |
178 | 一个比较完善的开源项目,通常会输出一些日志,如果你搜索整个项目的源代码,都找不到(log,logger,logging)这样的关键字,那就比较糟糕了。
179 |
180 | 通过修改源代码,以增加更多的日志输出,是我们常用的一种手段,最好是能够找到项目中可供参考的输出日志的办法,照着那个例子来改写。如果实在找不到,或者调用存在一些陷阱,也可以自己纯粹手工地添加日志输出代码。简单的举一个ruby的例子,下面的这一行代码,就可以输出一段内容到日志文件里去了。
181 |
182 | File.open("temp.log","a") { |f| f.puts("log info") }
183 |
184 | 输出日志,能够解决大多数情况下的理解需求,唯一可能会有陷阱的,则是**多线程程序输出的日志**,因为每次输出的内容可能次序不一致,因此需要特别小心。
185 |
186 | ### 设置断点与单步跟踪
187 |
188 | IDE有一个重要的好处,就是可以帮助程序员调试程序。在一个图形化界面里,跟踪调试程序,有着纯文字界面难以比拟的便利性。
189 |
190 | 
191 |
192 | Netbeans IDE 7.0 调试PHP的程序片段
193 |
194 | 在一个宽屏的显示器里,同时显示源代码树、对象结构、当前执行到的代码行、当前的各种变量值、调用序列、各个线程、输出内容等等等等,还是很爽的。
195 | 当然,要使得IDE能够调试一个开源项目,还是有很多琐碎的事情需要处理。例如:
196 |
197 | * 如何在IDE中打开一个项目
198 | * 如何在IDE中配置一个项目的依赖项
199 | * 如何在IDE中编译并运行一个项目
200 | * 如何在IDE中设置断点
201 |
202 | 这些如何,因语言、平台、IDE、版本、具体项目的不同,而有所区别。这里没法给出一个周到全面的解决方案,但是可以给一些搜索方面的建议:
203 |
204 | * 假设要在Netbeans 7中打开一个开源的Java项目,可以搜索“how to open java project in netbeans 7”,然后我们可以找到一些文档:
205 | * http://netbeans.org/kb/docs/java/project-setup.html
206 | * http://stackoverflow.com/questions/4382619/how-can-i-open-non-netbeans-java-project-using-netbeans
207 |
208 | 当然,一定会有各种让人挠头的问题,各位多多尝试吧。另外推荐一本书,是张银奎写的《软件调试》,大部头。但是的确是一本好书!
209 |
210 | http://book.douban.com/subject/3088353/
211 |
212 | ### 输出变量
213 |
214 | 对于不使用IDE但是想要对代码进行调试的情况,可以通过将每一步的变量进行输出的方式来查看变量的值,或者变量的类型,分析每一步具体输出的变量的值和该值可能进行的操作,这种方式的优点是可以整体性把握程序中变量的处理过程,从头到尾快速追踪一个或几个变量,比较适合于不能添加断点,单步调试比较困难的情况,同时,与添加断点单步调试相比,输出变量的方法可以使不同时期、不同处理过程中的变量同时出现在Console中,可以进行比较直观对比查看某一变量经过某一过程之后发生的变化。
215 |
216 | 在Python语言中,在对数据进行处理的过程中,我经常会使用输出变量和断点调试相结合的方式进行,因为断点调试中变量的值是实时变化的,想要对其进行对比就可以通过进行输出来对比变化。
217 |
218 | ### 抛出异常
219 |
220 | 有很多种语言,都支持异常处理,以及手动抛出异常。在特定的位置,将整个调用序列打印出来,可以方便我们快速的找到整个项目,是从何处开始,又是如何一层一层的调用,最终到达我们设置抛出异常的位置的。
221 |
222 | 在Java语言中,我们可以这么写:(new Exception()).printStackTrace();
223 | 在PHP语言中,我们可以直接调用函数:debug_backtrace();或者debug_print_backtrace();
224 | 在Ruby语言中,我们可以这么写:
225 |
226 | begin
227 | 1/0
228 | rescue => exception
229 | puts exception.backtrace
230 | end
231 |
232 |
233 | 其他种类的语言,建议各位可以自行Google。
234 |
235 | 在调用了类似的函数之后,我们可以或者类似如下这样的输出:
236 |
237 | java.lang.Exception
238 | at org.jruby.lexer.yacc.LexerSource.getSource(LexerSource.java:147)
239 | at org.jruby.parser.Parser.parse(Parser.java:122)
240 | at org.jruby.Ruby.parseFile(Ruby.java:1965)
241 | at org.jruby.Ruby.parseFile(Ruby.java:1969)
242 | at org.jruby.Ruby.parseFromMain(Ruby.java:364)
243 | at org.jruby.Ruby.runFromMain(Ruby.java:327)
244 | at org.jruby.Main.run(Main.java:214)
245 | at org.jruby.Main.run(Main.java:100)
246 | at org.jruby.Main.main(Main.java:84)
247 |
248 | 以上信息,清楚的现实了某某源文件的某某行,发生了一个调用,进而在下一个源文件中的某个函数,被调用了。于是,我们就可以从抛出异常的代码,开始逐级回溯,阅读相应的代码片段。
249 |
250 | ### 修改代码,破坏性尝试
251 |
252 | 在初步理解了项目代码之后,可以尝试做一些简单的修改,看看会发生什么。
253 |
254 | * 编译错误
255 |
256 | 静态类型的语言,在这方面有更多优势,通过编译时给出的错误提示,你可以知道自己改坏了什么,以及为什么它被改坏了。比较令人头痛的,是用了各种复杂的模板语法的C++语言,这时候编译器可能会给出一些令人莫名其妙的报错信息,那你就抓瞎了。不过,开源初学者,一上手就去啃复杂的C++代码,也很难说是明智的选择。
257 |
258 | * 运行时报错
259 |
260 | 与编译期报错类似,你也可以通过阅读一堆一堆的报错信息,了解代码是如何运作的,以及为什么原来不报错,现在就开始报错了。
261 | 不过,触发运行时报错,可能会有些困难,这涉及到你修改的代码,是处于主线还是支线位置,以及有多少相关功能,依赖于你所修改的代码。
262 |
263 | * 功能失效
264 |
265 | 可以尝试注释掉一些代码,看看会发生什么事情,比如某个功能按钮失灵甚至消失。当然,对于JavaScript代码,我们常常会喜欢在某些位置加上alert,看看什么时候会弹出一个消息提示框,却什么事都没有完成。
266 |
267 | * 走走捷径
268 |
269 | 我们常常会看到的一类代码,是长期发展完善后的产物。从接收消息,要处理某某事件开始,到真正去完成某某功能,其间还做了很多的额外工作,比如数据校验,纪录日志,触发其他消息等等,将这些代码全部注释掉,大多数功能都还是正常的,但是,会出各种意外,可以进一步做出各种尝试。(详见5.3. 主线与支线)
270 |
271 | ### 工具
272 |
273 | 有很多辅助代码阅读工具,简单的介绍一些
274 |
275 | * IDE类
276 |
277 | 既然是IDE,自然大多数都已经集成了相当不错的代码阅读功能,索引,反查,标注,自由跳转,通常都应有尽有。比较好的IDE,有Eclipse、Netbeans、IntelliJ IDEA、Visual Studio(Express)等等,各种面向专门语言的IDE还有很多,可以自行在Google搜索“Best XXX IDE”。
278 |
279 | 进阶阅读:[18 个最佳代码编辑器/IDE推荐](http://www.iteye.com/news/24235)
280 |
281 | * 传统神器+超牛插件
282 |
283 | 所谓传统神器,自然是指Emacs与VIM,这两款神器不能简单的以是否IDE来划分。他们都带有众多的插件,可以扩展出惊人的灵活性。
284 |
285 | 推荐阅读两篇文章:
286 | [Emacs和它的朋友们——阅读源代码篇](http://baohaojun.github.com/reading-source-code-cn)
287 | [自己动手定制一个高效阅读源代码的vim](http://zqwt.012.blog.163.com/blog/static/1204468420114194264789/)
288 |
289 | * 专业工具
290 |
291 | 专业工具,通常也是由商业公司开发的收费软件,人家要挣钱,自然也要有拿得出手的好东西。这里推荐两款软件,更多介绍,请自行搜索相关介绍与教程:
292 |
293 | * [Understand](http://www.scitools.com/index.php)
294 | * [source insight](http://www.sourceinsight.com/)
295 |
296 | * 软件工程相关工具
297 |
298 | 所谓软件工程的相关工具,主要是一些与面向对象概念相关的UML工具,比如IBM的Rational Rose、Sybase的Power Desinger、还有Borland的Together,都是大公司出品的一些大家伙。可以将面向对象语言(主要是Java)的项目,转换输出成为UML的各种图,有一定的参考价值,玩玩也不错。
299 |
300 | ## 主线与支线
301 |
302 | 一个开源项目,我们总可以从中找到主要的功能与次要的、辅助的功能。一个系统从启动开始,到完成最核心的功能、任务,最后成功结束,就是一条主线。而各种可能达到的次要功能,就是支线。
303 |
304 | 一个项目在最初创建的时候,总有一组想要实现的核心功能,其他都是次要的目标。比如:我做一个BBS,要让用户能够登录,发言(或者回复评论他人的发言),退出登录。这就是主线。而:设置用户头像,版主的各种权限与管理功能,顶、 踩功能,帖子内投票,站内短信等等等等,都可以算是次要功能。
305 |
306 | 在一个项目中,首先清理出主线以及其相关的代码,是一个非常必要的工作,主要的入手处,是项目的Readme文档。另外,对于某一领域的基础知识,也非常必要。
307 |
308 | ### 寻找入口
309 |
310 | 看一堆代码,总要找一个入手处。而不同的项目,入手处是不一样的。举几个例子:
311 |
312 | * 一个满足MVC模式的Web项目,通常会有多个Controller,这些Controller就是代码的入口处。如何才能找到某个访问路径对应的Controller呢?这就需要去看Route的定义了。
313 | * 一个较为普通的C/C++/Java项目,通常会有一个或者好几个含有main()函数的文件,那个就是代码的入口处。
314 | * Make、NMake、Rake、Ant、Maven等等,都是各种不同语言与项目,可能会用到的批处理任务管理工具,有很多的项目,是以这些配置文件中描述的文件,作为入口的,这自然需要理解相应的配置文件的语法规则。
315 | * 5.2.3节中,描述的抛出异常的方法,也是找到入口的办法。
316 |
317 | ### 跟踪关键流程
318 |
319 | 所谓跟踪关键流程,核心要义,就是学会使用调试器。包括集成开发环境(IDE)与命令行方式的调试器(例如GDB)。
320 |
321 | 无论何种调试工具,其基本的用法都是一致的:
322 |
323 | * 设置断点
324 | * 运行时中断
325 | * 单步跟踪
326 | * 查看或修改内存中的各种变量
327 |
328 | 在下图所示的Java代码debug截图中:
329 |
330 | * 我们将断点设置在CookieExample.java的第43行(红色行)。
331 | * 以debug方式运行后,代码将会停留在第43行。
332 | * 我们连续按六次F8,表示代码向下执行六行,目前停留在第51行(绿色行)。
333 | * 在窗口的下方,我们可以看到当前内存中的各种变量,例如title这个变量,就是String类型,值等于:"Cookies Example"
334 | * 在屏幕的左下角,我们可以看到这个java源文件包含两个方法与一个实例变量。
335 | * 在屏幕的左上角,我们可以看到这个项目执行的调用序列,撇开那些外部框架的代码,我们可以认为是ExampleFilter.java的doFilter方法在第101行时调用了CookieExample.java中的doGet方法。
336 |
337 | 
338 |
339 | 最笨的办法,就是一行一行地跟着代码的执行,反复的观察并理解,这些代码究竟做了哪些事情。随着对代码理解的加深,我们可以每次多执行几行,跳过一些已经没有疑问的代码,在更多的地方设置断点,甚至可以在运行时,试着修改某些变量的值,看看会发生什么变化。
340 |
341 | 跟踪关键流程,最容易犯的错误,就是单步跟踪时,迷失在代码的丛林里,晕头转向。及时识别出不太重要的代码(比如,试着注释掉一些代码段,看看会不会造成太大的影响),并且跳过这些段落,是保证有效追踪的关键。
342 |
343 | 说实话,要将代码调试这个事情讲解清楚,值得写整整一本书,有兴趣深入学习的同学,可以找一些专门的书籍来看,例如:《[软件调试的艺术](http://book.douban.com/subject/4111413/)》、《[Debug Hacks中文版](http://book.douban.com/subject/6799412/)》
344 |
345 | ### 理解插件体系
346 |
347 | 在较为现代的开源项目之中,常常会出现某种插件体系结构,整个系统可以分为三个主要的部分:核心功能+插件管理框架+扩展插件。
348 |
349 | 通过这样的体系结构,开源项目的主创人员,可以集中精力实现自己设想中的功能,而将其他扩展功能的开放任务,交给有兴趣的外部开发者:一方面可以吸引更多的人来参与;另一方面,也可以有效的隔离外部开发者对于核心架构的干扰。
350 |
351 | 因此,现在很多参与开源项目的方式,并非一开始就可以加入核心代码的开发,而是围绕着插件体系,为系统新增一个插件,或者修改其中的一个插件。对于复杂的系统而言,有时候一个插件,也成为了一个独立的开源项目,可以自由地参与其中。
352 |
353 | 不同的语言,不同的开源项目,可能具有不同的插件体系,较为著名的,有Eclipse的插件体系OSGi、FireFox的插件体系、jQuery的插件体系、Redmine的插件体系以及Joomla!的插件体系等等。
354 |
355 | 在维基百科上有一个关于插件的概要介绍:
356 |
357 |
358 | 要理解某个项目的插件体系,通常需要找到专门的介绍文档,仔细阅读。例如Java的OSGi,已经非常的复杂,值得专门写N本书来深入介绍:[豆瓣搜索OSGi的结果](http://www.douban.com/search?cat=1001&q=OSGi)
359 |
360 | 这里做一些简单的介绍的,是在不看文档的情况下,试着从代码寻找答案的初步方法。以Joomla!CMS为例:
361 |
362 | 将Joomla的源代码解压缩以后,我们发现有三个目录的名字,较为可疑:components、modules、plugins,看上去都是作为扩展插件而存在的。
363 |
364 | 首先查看components目录,里面有一堆的以com_开头的文件夹,看起来就是每一个文件夹,是一个组件。进入其中的一个文件夹:com_banners。打开banners.php,发现有三行关键代码:
365 |
366 | $controller = JControllerLegacy::getInstance('Banners');
367 | $controller->execute(JFactory::getApplication()->input->get('task'));
368 | $controller->redirect();
369 |
370 | 其中Legacy这个单词,引起了我的注意:看来component是一种遗留类型的插件,每个插件,也以MVC的风格写成。在源文件里搜索“class JControllerLegacy”,于是发现了一组文件:
371 |
372 | /libraries/legacy/controller/admin.php
373 | /libraries/legacy/controller/form.php
374 | /libraries/legacy/controller/legacy.php
375 |
376 | 看来都是用来处理遗留的扩展系统的controller的。
377 |
378 | 继续阅读com_banners里的代码,在models目录下,有一个banner.php文件,在其中我们又看到了一行值得注意的代码:
379 | class BannersModelBanner extends JModelLegacy
380 | 看来是与处理遗留扩展系统中的controller类似,用来处理model的。在源文件里搜索“class JModelLegacy”,于是发现了另一组文件:
381 |
382 | /libraries/legacy/model/admin.php
383 | /libraries/legacy/model/form.php
384 | /libraries/legacy/model/item.php
385 | /libraries/legacy/model/legacy.php
386 | /libraries/legacy/model/list.php
387 |
388 | 从这8个文件入手,我想就可以看明白component的扩展机制了。
389 |
390 | 在看modules目录下的文件,也是一堆以mod_开头的文件夹,打开其中一个mod_banners/mod_banners.php
391 |
392 | 也能发现一行值得注意的代码:
393 |
394 | require JModuleHelper::getLayoutPath('mod_banners', $params->get('layout', 'default'));
395 |
396 | 在源文件中搜索“class JModuleHelper”,就会另外发现一个文件:
397 | /libraries/legacy/module/helper.php
398 |
399 | 看来是处理遗留扩展系统中的modules的,读懂这个文件,应该就可以理解Module的扩展机制了。
400 |
401 | 最后看看plugins下的代码,与component和module不同,plugins是可以分层的,在authentication目录下,还有gmail、joomla、ldap三个目录,每个目录下,又有两个关键的文件,而且都与目录名(插件名)相同,gmail.php、gmail.xml。看来一个是gmail认证的实现文件,一个是这个插件的配置文件。
402 |
403 | 在源文件中搜索“class JPlugin”,可以发现两个文件:
404 |
405 | /libraries/joomla/plugin/helper.php
406 | /libraries/joomla/plugin/plugin.php
407 |
408 | 配合这两个文件,加上插件目录下的.php与.xml文件,应该就可以较为清楚的理解plugins的实现机制了。
409 |
410 | ## 外围代码
411 |
412 | ### 必须存在的外围功能
413 |
414 | 当我们阅读一个开源项目的代码时,当时首先是找到主线代码,然后努力去理解其核心的内容。但是,一个完整的开源项目,必须存在很多外围的功能与代码,除了文档之外,还有其他一些必不可少的内容。
415 |
416 | * 例如,一个C/C++的开源项目,通常会有的Makefile文件,已经较为正规一点的项目都会提供的configure脚本文件。没有这样的文件,想要自己编译整个项目,几乎是不可能的。
417 | * 再比如:一个项目如果与数据库相关,必备的数据库建表、初始化数据灯工作,就得有一些工具来辅助。最糟糕的,是写一个txt文档,让你照着做,好一点的是提供一个或一组SQL,供人执行,这方面Rails做得非常的到位,我们通常可以在一个Rails的开源项目下,找到一个/db/migrate的目录,这里面提供的脚本,是专门用于数据迁移的。
418 | * 一些好的开源项目,会允许多种不同的运行模式,例如在运行时加上debug参数,就能够输出更多的调试信息,供使用者查找可能存在的问题。在阅读理解代码的时候,这些调试代码也是辅助理解开源项目的好方法。
419 | * 依赖管理也是一个麻烦的事情,这方面有两个较为好的榜样,Ruby的开源项目往往会在根目录下附带一个Gemfile文件,下载源码之后,只要再执行一个bundle install即可。Node.JS也有类似的好习惯,根目录下的package.json文件,就是类似的定义包依赖的文件,只要执行npm install,就万事大吉。
420 | * 负责任的开源项目,在提供源代码之前,就已经做了充分的测试,而且通常是按照单元测试的规范来做的。对于C/C++项目,我们在make之后,一般可以make test,或者对于Java项目,我们可以ant test。对于ruby项目,我们可以rake test或者rspec xxx.rb
421 | * 当然,负责任的开源框架,通常还会提供demo与example,连带单元测试的介绍,我们都会再下面的两节,详细展开。
422 |
423 |
424 | ### 单元测试
425 |
426 | 在软件开发的各种最佳实践中,我认为最具有其他性的,是“测试驱动开发(TDD)”,而最容易误导开发者的,则是“设计模式(DP)”,在阅读开源项目的代码时,如果我看到编写完整而全面的单元测试代码,我自然会对整个项目的质量高看一眼。而如果我在源代码里看到了充斥着陈腐味道的各种设计模式的名字时,我会猜测这是一个“玩具项目”——也就是那种经验不足的开发,学习练手的项目。
427 |
428 | 单元测试,也有高下之分,好的单元测试,会测试关键逻辑与核心算法;而敷衍了事的单元测试,则会去测试get/set这样的代码,看起来一堆assert,却毫无价值。
429 |
430 | 阅读单元测试的代码,也有一种弊端,就是因为陷入点点滴滴的琐碎细节,进而迷失了方向。所以,不要在一开始就去阅读单元测试的代码,而是先对项目的整体有所了解之后,再开始阅读。
431 |
432 | 再者,好的单元测试的代码,会特别注重使用场景的构建:某个功能点,在什么情况下,被预期会做出什么样的反应。而构建使用场景的代码,主要集中在startUp这样的函数里,以及各种Mock对象的构造之中,因此,关注startUp与Mock创建,而不是仅仅去看一个一个的testXXX()方法,会更容易理解开发者的意图。
433 |
434 | ### demo/example
435 |
436 | 我们可以简单的将开源项目划分成两类,一类是给最终用户使用的项目;一类是基于这个项目,可以继续做开发的。
437 | 对于第二类项目,有可以分为几类:开发框架(各种Web MVC框架)、基础服务(MySQL、Message Queue)、可以被插件扩展的软件(FIrefox、Chrome)、编程语言(Ruby、Python、NodeJS)、模板引擎(SaSS、Less、HAML)等等。
438 |
439 | 所有这第二类项目,都需要告诉使用者,应该如何使用自己的项目,给出开发文档、入门教程、指南、手册之类,当然多多益善。但是,最能够指导用户学习的,却是demo或者example。
440 |
441 | 一个负责任的开源项目,就应该给出足够覆盖自身功能特性的例子,以指导开发者的使用,同时也是对自身功能特性的一种全面的检验。
442 |
443 | 对于初学者而言,运行demo,尝试修改,嫁接组合,其实就是类似对一个开源项目的较小规模的阅读与理解。所以,好的demo,不仅应该是丰富的,最好还是循序渐进的。从Hello World级的demo,到PetShop级的demo,都会对开发者有很大的帮助。
444 |
445 | 至于如何阅读理解这些demo,其实就是将之看成一个小型的开源项目,然后应用本章的各种方法而已,在此不再赘述。
446 |
447 | ## 知其所以然
448 |
449 | 有一句俗语叫做:“知其然,更要知其所以然”。用在任何学习科目上,几乎都是恰当的。本章叫做《理解开源项目》,而之前的4个小节,可以说都是属于“知其然”的功夫。如何才能知其所以然呢?
450 |
451 | ### 所以然包括哪些内容?
452 |
453 | 往大了说,整个这份文档,希望帮助读者达到的,就是能够对于开源软件“知其所以然”。这样才算是真正提高了软件开发的能力。因此,我们可以将“架构决策”、“代码风格”、“领域知识”、“编程技巧”等等内容,都算作是所以然的一部分。
454 |
455 | **架构决策** 通过深入阅读和分析源代码,理解整个项目,为何像这样,而不是那样做架构设计。其间蕴含着项目作者的经验和智慧,理解了这个,将是一种巨大的收获。
456 |
457 | **代码风格** 每一种语言、每一个社区、每一个开发者群体,甚至每一个开源项目,都有其独特的代码风格,这种风格,有其背后的合理性,也有很多是来源于某种开发哲学的思考。理解一种代码风格,就是理解一种思考的模式,一种思想的体系。能够多了解一些不同种类的代码风格,对于提高软件开发能力,将有很大的帮助。
458 |
459 | **领域知识** 有些代码不容易看懂,很重要的一个原因,是这个项目所涉及的领域,我们没有什么深入的了解。多年的程序员经验告诉我,要做好某一个行业的软件,一定要成为某一个行业的内行。甚至要比那个本行业的业内人士,更加精通。因此,一个优秀的程序员,通常是能够跟你聊多个不同行业的话题的。强大到你几乎无法分别他的是不是业内人士。因此,通过理解开源项目,进而理解相关的领域知识,会有很多收获。
460 |
461 | **编程技巧** 阅读优秀的开源项目的代码,有时候很像是看一本好书。细细品味,慢慢的体会。我们会发现一点一滴的“妙处”。这些妙处凝聚了程序员的巧思妙想,能够体会得越多,对我们的帮助也就越大。
462 |
463 | ### 所以然还包括的一些内容:
464 |
465 | **个人偏好** 开源作者也是普通人,他们有很多观点和取舍,未必能够说服他人,只能算是他们自己的偏好。而他们将自己的偏好表达在代码里,有些时候,我们能够很容易理解 (因为我们也是这样想的)。有些时候,我们就会感觉很不解,而且,常常会发生的一类故事就是:某某大牛写了一个开源项目,另一个大牛有感觉不爽的地方。提了意见建议,人家又不肯改。结果,这另外一个大牛,就一怒之下,另起炉灶,写了一个新的开源项目。
466 |
467 | **历史原因** 有一篇很有意思的文章,解释了《[为什么Vim使用HJKL键作为方向键](http://linux.cn/article-542-1.html)》,其实原因很简单。当Bill Joy创建Vi文本编辑器时,他使用的机器是ADM-3A终端机,这机器就是把HJKL键作为方向键的。
468 |
469 | 
470 |
471 | ### 如何搞清楚这些所以然呢?
472 |
473 | **思考** 当然,这种思考应该伴随我们“通过开源项目,学习软件开发”的始终。但是,从方法论来说,可以尝试从以下一些角度出发来思考:
474 |
475 | * 如果我来做一个,会如何去做?
476 | * 如果能够对这个项目做减法,我可以去掉哪些模块和代码?真的能够去掉吗?
477 | * 通过阅读单元测试,理解开发者的设计思路。
478 | * 尝试做一些破坏或者修改,来理解项目中的那些做法。这个在下一章会更详细的讨论。
479 |
480 | **讨论** 到开源社区去,发起一些讨论。当然,前提是你必须经过足够深入的思考。不要尽是问一些傻问题
481 |
482 | **向作者提问** 与上面的讨论类似,前提是要先思考。当然,还有一个讨巧的办法,你可以提出:我想翻译这个开源项目的英文文档。然后,对方当然会很高兴——国际化了嘛。这样你就可以在翻译的过程中,提出各种各样的问题……
483 |
484 | **阅读指南** 有些著名的开源项目,本身也非常复杂,所以会有一些文档与书籍:linux内核代码分析、MySQL源码解读、PHP源码分析等等。如果有心学习这样的大型开源项目,这种入门指南,也是很有价值的。但是,这毕竟是别人嚼过的饭,肯定不如自己去啃来的香。所以,还是回到那句老话,源代码才是最有营养的。
485 |
486 | ### 参考文档
487 |
488 | * [看源代码那些事](http://zhh2009.iteye.com/blog/1011122)
489 | * [Tomcat7调试运行环境搭建与源代码分析入门](http://zhh2009.iteye.com/blog/1557891)
490 | * [Redis代码阅读](http://www.iteye.com/blogs/subjects/olylakers)
491 | * [通过修改JRuby,给我的ruby代码加密](http://working-on-opensource.group.iteye.com/group/wiki/1332-by-modifying-the-jruby-given-to-me-by-ruby-code-encryption)
492 |
493 | [上一章](Hello-world.md) | [下一章](Modify-the-open-source-project.md)
494 |
--------------------------------------------------------------------------------
/zh/Useful-Websites-to-Learn-How-to-Code-Quickly.md:
--------------------------------------------------------------------------------
1 | # 指导开发者快速学习编程的网站推荐
2 |
3 | * 英文原文:[9 Useful Websites to Learn How to Code Quickly](http://www.queness.com/post/10709/8-useful-websites-to-learn-how-to-code-quickly)
4 | * 翻译: [wangguo](http://wangguo.iteye.com/)
5 |
6 | 互联网是一个飞速发展的领域,从HTML到HTML5、从CSS到CSS3、从JavaScript到JavaScript框架,技术在不断地更新换代。如果你不能跟上这个形势,你将会被淘汰。因此,快速掌握一门语言或一项技术,对于你的Web开发工作将是百利无一害的。
7 |
8 | 本文为你带来了9个实用的在线教程,一些是互动形式的,还有一些则以全面的指南和可视化形式帮助你快速掌握一门语言。它们有共同的目的,让你的学习更加有乐趣,以及更容易让你掌握这些知识。
9 |
10 | ## [LifeHacker Learn to code](http://www.lifehacker.com.au/2011/02/learn-to-code-the-full-beginners-guide/)
11 |
12 | 语言:JavaScript
13 |
14 | 4节课+最佳实践/资源,教你如何使用Javascript进行编程。每节课有一个视频和详细的文章,来确保你理解这些内容。
15 |
16 | 
17 |
18 | ## [CodeCademy](http://www.codecademy.com/)
19 |
20 | 语言:JavaScript
21 |
22 | 这是一个互动的教学形式,让你一点一点掌握JavaScript。每完成一个课程,你可以得到一些成就点和徽章,通过该形式来激发你的学习兴趣。
23 |
24 | 
25 |
26 |
27 | ## [TeamTreeHouse](http://teamtreehouse.com/)
28 |
29 | 语言:CSS、CSS3、HTML、HTML5、JavaScript、Basic编程和iOS开发
30 |
31 | 这是一个付费会员在线学习服务,完全覆盖了Web设计和开发等主题,也包括目前非常流行的iOS开发。
32 |
33 |
34 | 
35 |
36 | ## [RubyMonk](http://rubymonk.com/)
37 |
38 | 语言:Ruby
39 |
40 | RubyMonk是一个互动的学习平台。你可以通过课程、问题解决或者相关文章来学习Ruby。
41 |
42 | 
43 |
44 | ## [Hackety](https://github.com/hacketyhack/hacketyhack)
45 |
46 | 语言:Ruby
47 |
48 | Hackety将会教你掌握绝对的编程基础知识,即使你没有任何编程经验。
49 |
50 |
51 | 
52 |
53 | ## [jQuery Air](http://jqueryair.com/)
54 |
55 | 语言:JavaScript
56 |
57 | jQuery是最著名的JavaScript框架。现在你可以直接在浏览器中学习jQuery。学习jQuery的过程应该是充满乐趣的,jQuery Air通过大量实践的方式来达到这个目的。
58 |
59 | 
60 |
61 |
62 | ## [CodingBat](http://codingbat.com/)
63 |
64 | 语言:Java、Python
65 |
66 | 通过解决示例问题以及在线编码实践的形式,来学习Java和Python。
67 |
68 |
69 | 
70 |
71 | ## [PHP Know How](http://www.phpknowhow.com/)
72 |
73 | 语言:PHP
74 |
75 | 这并不是一个互动的学习方式,但它有一个很好的书面教程,包含了大量示例和指南,教你学习PHP和MySQL的基本知识。
76 |
77 |
78 | 
79 |
80 | ## [MongoDB](http://www.mongodb.org/)
81 |
82 | 语言:Java、Python、Go、PHP等主流开发语言
83 |
84 | 这是MongoDB的官方网站。MongoDB是由 C++ 语言编写的一个可扩展、高性能、开源的NoSQL数据库。适用于Java、Python、Go、PHP等主流开发语言。该网站中包含一个教程,让你通过一些命令来开始你的MongoDB学习旅程。
85 |
86 |
87 | 
88 |
89 | ## [学堂在线](https://next.xuetangx.com/)
90 |
91 | 技术:微信小程序开发,算法
92 |
93 | 这是清华大学等机构支撑的在线教育网站。其中包含推荐算法,微信小程序制作等课程。
94 |
95 | 
96 |
97 | ## [keybr](https://www.keybr.com)
98 |
99 | 技术:高速打字
100 |
101 | 简介:工欲善其事,必先利其器!程序员的双手就是最重要的武器之一,因此练习正确的快速输入尤其重要。这个网站画风简洁,在云端保存了你的打字记录,记录你的成长和进步。
102 |
103 | 
104 |
--------------------------------------------------------------------------------
/zh/images/2048-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/2048-1.png
--------------------------------------------------------------------------------
/zh/images/2048-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/2048-2.png
--------------------------------------------------------------------------------
/zh/images/2048-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/2048-3.png
--------------------------------------------------------------------------------
/zh/images/2048-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/2048-4.png
--------------------------------------------------------------------------------
/zh/images/9-useful-CodeCademy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-CodeCademy.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-LifeHacker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-LifeHacker.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-TeamTreeHouse.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-TeamTreeHouse.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-codingBat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-codingBat.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-hackety.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-hackety.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-jqueryAir.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-jqueryAir.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-keybr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-keybr.png
--------------------------------------------------------------------------------
/zh/images/9-useful-mongodb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-mongodb.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-phpKnowHow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-phpKnowHow.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-rubyMonk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-rubyMonk.jpg
--------------------------------------------------------------------------------
/zh/images/9-useful-学堂在线.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/9-useful-学堂在线.png
--------------------------------------------------------------------------------
/zh/images/debug-NetBeans-IDE-7.0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/debug-NetBeans-IDE-7.0.png
--------------------------------------------------------------------------------
/zh/images/debug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/debug.png
--------------------------------------------------------------------------------
/zh/images/keyboard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/keyboard.jpg
--------------------------------------------------------------------------------
/zh/images/pyramid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhuangbiaowei/learn-with-open-source/db0b40286143cf548cc8e44bbbef205c070fe2b2/zh/images/pyramid.jpg
--------------------------------------------------------------------------------