├── .gitignore ├── LICENSE ├── README.md ├── algorithm-structure ├── README.md ├── heap-stack │ └── README.md ├── queue │ └── README.md ├── sequence │ ├── README.md │ ├── bubbling.md │ └── fast │ │ └── README.md ├── tree │ └── README.md └── vs │ └── README.md ├── blog.png ├── container ├── dockerK8s │ ├── README.md │ ├── k8s-diffService-pods.png │ └── k8s-label.png ├── dockerTools │ └── README.md ├── gCentos │ ├── Dockerfile │ └── README.md ├── k8s-node.png ├── k8s-pod.png └── k8s │ └── README.md ├── db ├── mysql │ ├── basic.md │ └── mysqlMacOSTOLinux │ │ └── README.md └── redis │ └── README.md ├── go ├── go-surrounding │ └── gin-middleware │ │ ├── README.md │ │ └── ginMiddlewareDemo.go ├── go │ ├── concurrency │ │ ├── README.md │ │ └── go-goroutine.jpg │ ├── deadlock │ │ └── README.md │ ├── escape-analysis │ │ └── README.md │ ├── ignore-but-important │ │ └── README.md │ ├── important │ │ └── README.md │ └── optimization │ │ └── README.md └── tool │ ├── goMod │ └── README.md │ └── performance-testing │ └── README.md ├── mixtalk ├── all │ ├── README.md │ ├── 一文帮你理清面试知识点 - 小专栏.pdf │ └── 复习大纲副本 (1).svg ├── go-application-question │ ├── README.md │ ├── 面试知识大揭秘.tar.xz │ └── 面试知识大汇总.pdf ├── howToFindYourSchool │ ├── README.md │ └── 各学校考研报录比2015-2019.7z ├── howToJoinGoogle │ └── README.md ├── howToMakeMoreMoney │ ├── README.md │ └── makeMoreMoney1.png ├── m │ ├── README.md │ ├── pplabs │ │ └── README.md │ └── unknow │ │ ├── 1.md │ │ └── README.md ├── macSoftwares.md ├── net │ ├── 4.png │ ├── 5.png │ ├── 7.gif │ ├── GETVsPOST │ │ └── README.md │ ├── README.md │ ├── c.jpeg │ └── tcpd.jpg ├── shipu.md ├── ssr.md └── whyWeChat.md └── system └── linux ├── kid-kid-kid └── README.md └── kill └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.idea 2 | *.idea/** 3 | *.Ds_Store 4 | *.Ds_Store/** 5 | node_modules 6 | node_modules/** 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |

6 |
7 | 8 | 9 | - [go mod](https://github.com/googege/blog/tree/master/go/tool/goMod/README.md) 10 | - [go并发时的死锁问题](https://github.com/googege/blog/tree/master/go/go/deadlock/README.md) 11 | - [go语言的并发模型](https://github.com/googege/blog/tree/master/go/go/concurrency/README.md) 12 | - [go语言的常见优化](https://github.com/googege/blog/tree/master/go/go/optimization/README.md) 13 | - [go语言容易错的几个点](https://github.com/googege/blog/tree/master/go/go/important/README.md) 14 | - [go语言的逃逸分析](https://github.com/googege/blog/tree/master/go/go/escape-analysis/README.md) 15 | - [go语言的一些不容易被注意到的但是又很重要的问题](https://github.com/googege/blog/tree/master/go/go/ignore-but-important/README.md) 16 | - [gin中间件的开发](https://github.com/googege/blog/tree/master/go/go-surrounding/gin-middleware/README.md) 17 | - [堆和栈的解释](https://github.com/googege/blog/tree/master/algorithm-structure/heap-stack/README.md) 18 | - [树系列结构以及相应的算法](https://github.com/googege/blog/tree/master/algorithm-structure/tree/README.md)[waiting] 19 | - [排序算法](https://github.com/googege/blog/tree/master/algorithm-structure/sequence/README.md)[waiting] 20 | - [队列-go语言版](https://github.com/googege/blog/tree/master/algorithm-structure/queue/README.md) 21 | - [go语言的ints算法和各大经典排序算法的对比]((https://github.com/googege/blog/tree/master/algorithm-structure/vs/README.md)) 22 | - [知识架构大总结](https://github.com/googege/blog/tree/master/mixtalk/all/README.md) 23 | - [go 真实公司面试题集锦](https://github.com/googege/blog/tree/master/mixtalk/m/README.md) 24 | - [go语言招聘问题大全](https://github.com/googege/blog/tree/master/mixtalk/go-application-question/README.md) 25 | - [如何给一个进程发送信号](https://github.com/googege/blog/tree/master/system/linux/kill/README.md) 26 | - [孤儿进程,僵尸进程,守护进程](https://github.com/googege/blog/tree/master/system/linux/kid-kid-kid/README.md) 27 | - [网络协议知多少](https://github.com/googege/blog/tree/master/mixtalk/net/README.md) 28 | - [GET vs POST](https://github.com/googege/blog/tree/master/mixtalk/net/GETVsPOST) 29 | - [go 性能测试](https://github.com/googege/blog/tree/master/go/tool/performance-testing/README.md) 30 | - [docker命令检索](https://github.com/googege/blog/tree/master/container/dockerTools/README.md) 31 | - [k8s命令检索](https://github.com/googege/blog/tree/master/container/k8s/README.md) 32 | - [docker + k8s](https://github.com/googege/blog/tree/master/container/dockerK8s/README.md) 33 | - [gCentos](https://github.com/googege/blog/tree/master/container/gCentos/README.md) 34 | - [redis](https://github.com/googege/blog/tree/master/db/redis) 35 | - [mysql在mac上开发 在Linux上发布的过程](https://github.com/googege/blog/tree/master/db/mysql/mysqlMacOSTOLinux/README.md) 36 | - [计算机学科以及临床学科,学科排名](https://github.com/basicExploration/blog/tree/master/mixtalk/howToFindYourSchool/README.md) 37 | - [如何加入谷歌](https://github.com/basicExploration/blog/tree/master/mixtalk/howToJoinGoogle) 38 | - [程序员如何赚更多的钱](https://github.com/basicExploration/blog/tree/master/mixtalk/howToMakeMoreMoney) 39 | ## 欢迎加入算法讨论群 40 | ![p](https://raw.githubusercontent.com/googege/AMAC/master/joinUs.png) 41 | 42 | **嗯,可以给我买杯可乐,我喜欢冰镇的。** 43 | 44 | ![p](https://raw.githubusercontent.com/googege/Files/master/donate.png) 45 | 46 | [推荐vps](https://app.cloudcone.com/?ref=2525) 47 | 48 | [VPS网站使用说明](https://www.bilibili.com/video/av38630366) 49 | 50 | *可支持 **支付宝支付**, 个人提子使用版本 2刀/月,`1T`流量 ,最高`1Gb`带宽, 速度测试:基本上在`1M/s` 以上,最高速度能达到`8M/s`(联通4g)* 51 | --- 52 | 知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。 53 | -------------------------------------------------------------------------------- /algorithm-structure/README.md: -------------------------------------------------------------------------------- 1 | ## 基础知识 2 | 3 | 4 | 5 | ### 算法 - Algorithms 6 | 7 | - 排序算法:[快速排序](./sequence/fast)、归并排序、计数排序 8 | - 搜索算法:回溯、递归、剪枝技巧 9 | - 图论:最短路、最小生成树、网络流建模 10 | - 动态规划:背包问题、最长子序列、计数问题 11 | - 基础技巧:分治、倍增、二分、贪心 12 | 13 | ### 数据结构 - Data Structures 14 | 15 | - 数组与链表:单 / 双向链表、跳舞链 16 | - 栈与队列 17 | - 树与图:最近公共祖先、并查集 18 | - 哈希表 19 | - 堆:大 / 小根堆、可并堆 20 | - 字符串:字典树、后缀树 21 | 22 | 23 | -------------------------------------------------------------------------------- /algorithm-structure/heap-stack/README.md: -------------------------------------------------------------------------------- 1 | # 堆和栈 2 | 3 | - 首先说英文名:堆叫 heap 栈叫 stack 4 | 5 | 数据结构中的堆和栈 6 | 7 | - 栈就是先进后出的一个数据结构,像一个装满盒子的管道一样 8 | - 堆是满足父子节点大小(比如大根堆中规定父节点的值要比子节点大)关系的一种完全二叉树 9 | 10 | 操作系统,编程软件中的堆和栈 11 | 12 | - 栈系统分配 系统回收 局部 不持久 13 | - 堆 程序源分配 程序源回收 全局 持久 14 | 15 | 在go语言中堆和栈,栈当然也是系统分配系统回收的东西,但是堆在go语言中也不需要程序员自己回收,因为有gc,也就是垃圾回收机制。 16 | 17 | 可以将堆视为很多的一块内存,其中有很多被编号的内存单元,用于存储数据。与栈不同,你不可以对这些单元进行标记(即声明定义变量),而必须先申请内存单元的地址,然后将它存储到指针中。具体是什么意思呢?也就是说你在栈里的数据可以直接访问,但是在堆中你必须通过指针才能访问数据不能直接访问。 18 | 19 | -------------------------------------------------------------------------------- /algorithm-structure/queue/README.md: -------------------------------------------------------------------------------- 1 | ### 队列-go语言版 2 | > 原文https://github.com/googege/blog/tree/master/algorithm-structure/queue 3 | 4 | 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加(wiki) 5 | 6 | 7 | -------------------------------------------------------------------------------- /algorithm-structure/sequence/README.md: -------------------------------------------------------------------------------- 1 | ### 排序算法 2 | - [冒泡](./bubbling.md) -------------------------------------------------------------------------------- /algorithm-structure/sequence/bubbling.md: -------------------------------------------------------------------------------- 1 | #### 冒泡算法 2 | -------------------------------------------------------------------------------- /algorithm-structure/sequence/fast/README.md: -------------------------------------------------------------------------------- 1 | ## 快速排序算法 go版本 2 | -------------------------------------------------------------------------------- /algorithm-structure/tree/README.md: -------------------------------------------------------------------------------- 1 | # 树系列算法 2 | - 字典树 3 | - 二叉树 4 | - 红黑树 5 | - 基数树 6 | - b-树 7 | - b+树 8 | 9 | https://www.cnblogs.com/eudiwffe/p/6207196.html 10 | -------------------------------------------------------------------------------- /algorithm-structure/vs/README.md: -------------------------------------------------------------------------------- 1 | ## go ints 使用的算法和各大经典排序算法的对比 2 | 3 | > n 表示 使用go的rand 的 perm随机生成的数据的len 4 | 5 | > 前 go 后 其它算法 6 | 7 | - go ints vs 冒泡法 8 | 9 | ```bash 10 | n = 1 5 10 15 20 25 30 35 11 | 12 | 56.2 ns/op 13 | 5.13 ns/op 14 | 15 | 84.8 ns/op 16 | 25.1 ns/op 17 | 18 | 138 ns/op 19 | 76.7 ns/op 20 | 21 | 248 ns/op 22 | 151 ns/op 23 | 24 | 352 ns/op 25 | 257 ns/op 26 | 27 | 395 ns/op 28 | 402 ns/op 29 | 30 | 599 ns/op 31 | 580 ns/op 32 | 33 | 691 ns/op 34 | 810 ns/op 35 | 36 | ``` 37 | 38 | 基本上 30是分界线,越往后 go越快 39 | 40 | - go ints vs 选择排序 41 | 42 | ```bash 43 | n = 1 5 10 20 21 100 1000 44 | 56.3 ns/op 45 | 5.13 ns/op 46 | 47 | 85.4 ns/op 48 | 26.3 ns/op 49 | 50 | 127 ns/op 51 | 74.6 ns/op 52 | 53 | 323 ns/op 54 | 290 ns/op 55 | 56 | 338 ns/op 57 | 329 ns/op 58 | 59 | 2936 ns/op 60 | 7364 ns/op 61 | 62 | 51202 ns/op 63 | 673224 ns/op 64 | ``` 65 | 66 | 可以看到 在go vs 选择排序的对比中 21是一个分界线。 67 | 68 | 比较起来 冒泡法都比 选择排序优秀 69 | 70 | - go vs 插入算法 71 | 72 | ```go 73 | n= 1 10 20 50 100 74 | 60.4 ns/op 75 | 5.40 ns/op 76 | 77 | 148 ns/op 78 | 17.5 ns/op 79 | 80 | 338 ns/op 81 | 32.4 ns/op 82 | 83 | 1126 ns/op 84 | 75.5 ns/op 85 | 86 | 87 | 3099 ns/op 88 | 132 ns/op 89 | 90 | ``` 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/blog.png -------------------------------------------------------------------------------- /container/dockerK8s/README.md: -------------------------------------------------------------------------------- 1 | ## doker 和 k8s 2 | > [原文-->](https://github.com/googege/blog/container/dokerK8s/README.md) 3 | 4 | 所谓容器,就是一个一个的独立起来的进程,我们都知道进程之间是无法进行沾染的,所以如果使用一个个的容器封装起来的应用就可以独立开来,这就是容器技术。 5 | 6 | 通常我们使用virtual box等虚拟机,这是我们经常使用的虚拟机技术,但是太过于庞大,往往我们要制作整个的包括系统在内的很大的工程,所以,就太繁琐了,而且启动速度, 7 | 占用资源也相对较大,所以才用了容器技术 8 | 9 | 我们拥有了容器技术,往往就可以实现集群技术,什么是集群技术呢,就是一堆。那么我们该怎么控制这些容器呢?这个时候k8s就诞生了。k8s全程太长我没记住,不过他是由 10 | 谷歌开发并且开源的使用GO语言编写的一个系统。ps docker也是GO写的,go大法万岁。😘 11 | 12 | **图文解释k8s** : 13 | 14 | ![p](https://upload-images.jianshu.io/upload_images/13382653-c7872d6a360d9a36?imageMogr2/auto-orient/strip%7CimageView2/2/w/667/format/webp) 15 | 16 | ![p](https://upload-images.jianshu.io/upload_images/13382653-80f2268ac078fbc6?imageMogr2/auto-orient/strip%7CimageView2/2/w/672/format/webp) 17 | 18 | 这里我们要看一下 一个node中有很多内容,但是基本的操作是pod,这里面的docker等就是一个工具一样,所以这个时候又引出来了一句话:docker不是容器,docker是创建容器的工具。 19 | 20 | ![p](https://raw.githubusercontent.com/googege/blog/master/container/k8s-node.png) 21 | ![p](https://raw.githubusercontent.com/googege/blog/master/container/k8s-pod.png) 22 | 23 | 讲述了 不同的抽象符合和pod node的关系 24 | ![p](https://raw.githubusercontent.com/googege/blog/master/container/dockerK8s/k8s-diffService-pods.png) 25 | 讲述了 不同的pod是如何划分组合的 答案就是利用label 26 | ![p](https://raw.githubusercontent.com/googege/blog/master/container/dockerK8s/k8s-label.png) 27 | 28 | 29 | 30 | ### docker 31 | 32 | ### k8s 33 | 34 | ### docker + k8s 35 | 36 | > 感谢 37 | https://blog.csdn.net/huakai_sun/article/details/82378856 38 | -------------------------------------------------------------------------------- /container/dockerK8s/k8s-diffService-pods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/container/dockerK8s/k8s-diffService-pods.png -------------------------------------------------------------------------------- /container/dockerK8s/k8s-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/container/dockerK8s/k8s-label.png -------------------------------------------------------------------------------- /container/dockerTools/README.md: -------------------------------------------------------------------------------- 1 | ## docker命令检索 2 | 3 | Usage: docker [OPTIONS] COMMAND 4 | 5 | A self-sufficient runtime for containers 6 | 7 | Options: 8 | 9 | 选项: 10 | ```bash 11 | --config string客户端配置文件的位置(默认值“/Users/ThomasHuke/.docker”) 12 | 13 | -D, - debug启用调试模式 14 | 15 | -H, - 主机列表要连接的守护程序套接字 16 | 17 | -l, - log-level string设置日志记录级别( “调试” | “信息” | “警告” | “错误” | “致命”)(默认“信息”) 18 | 19 | --tls使用TLS;由--tlsverify暗示 20 | 21 | --tlscacert字符串仅由此CA签名的信任证书(默认值“/Users/[登录用户]/.docker/ca.pem”) 22 | 23 | --tlscert string TLS证书文件的路径(默认值“/Users/xx/.docker/cert.pem”) 24 | 25 | --tlskey string TLS密钥文件的路径(默认值“/Users/xx/.docker/key.pem”) 26 | 27 | --tlsverify使用TLS并验证远程 28 | 29 | -v, - version打印版本信息并退出 30 | ``` 31 | 管理命令 32 | 33 | - [checkpoint](#checkpoint) 管理检查站 34 | - config 管理Docker配置 35 | - container 管理容器 36 | - image 管理镜像 37 | - network 管理网络 38 | - node 管理Swarm节点 39 | - plugin 管理插件 40 | - secret 管理Docker的秘密 41 | - service 管理服务 42 | - stack 管理Docker堆栈 43 | - swarm 管理Swarm 44 | - system 管理Docker 45 | - trust 管理对Docker镜像的信任 46 | - volume 管理数量 47 | 48 | 49 | Commands: 50 | 51 | - [attach](#attach) Attach local standard input, output, and error streams to a running container 52 | - [build](#build) Build an image from a Dockerfile 53 | - commit Create a new image from a container's changes 54 | - cp Copy files/folders between a container and the local filesystem 55 | - create Create a new container 56 | - deploy Deploy a new stack or update an existing stack 57 | - diff Inspect changes to files or directories on a container's filesystem 58 | - events Get real time events from the server 59 | - exec Run a command in a running container 60 | - export Export a container's filesystem as a tar archive 61 | - history Show the history of an image 62 | - images List images 63 | - import Import the contents from a tarball to create a filesystem image 64 | - info Display system-wide information 65 | - inspect Return low-level information on Docker objects 66 | - kill Kill one or more running containers 67 | - load Load an image from a tar archive or STDIN 68 | - login Log in to a Docker registry 69 | - logout Log out from a Docker registry 70 | - logs Fetch the logs of a container 71 | - pause Pause all processes within one or more containers 72 | - port List port mappings or a specific mapping for the container 73 | - ps List containers 74 | - pull Pull an image or a repository from a registry 75 | - push Push an image or a repository to a registry 76 | - rename Rename a container 77 | - restart Restart one or more containers 78 | - rm Remove one or more containers 79 | - rmi Remove one or more images 80 | - run Run a command in a new container 81 | - save Save one or more images to a tar archive (streamed to STDOUT by default) 82 | - search Search the Docker Hub for images 83 | - start Start one or more stopped containers 84 | - stats Display a live stream of container(s) resource usage statistics 85 | - stop Stop one or more running containers 86 | - tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE 87 | - top Display the running processes of a container 88 | - unpause Unpause all processes within one or more containers 89 | - update Update configuration of one or more containers 90 | - version Show the Docker version information 91 | - wait Block until one or more containers stop, then print their exit codes 92 | 93 | Run 'docker COMMAND --help' for more information on a command. 94 | -------------------------------------------------------------------------------- /container/gCentos/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /container/gCentos/README.md: -------------------------------------------------------------------------------- 1 | ## 包含了node go mysql ss 的一个centos 镜像。 2 | ```bash 3 | docker pull imgoogege/gcentos 4 | ``` 5 | -------------------------------------------------------------------------------- /container/k8s-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/container/k8s-node.png -------------------------------------------------------------------------------- /container/k8s-pod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/container/k8s-pod.png -------------------------------------------------------------------------------- /container/k8s/README.md: -------------------------------------------------------------------------------- 1 | ## k8s 命令检索 2 | 3 | 严格记住一点: pod 是k8s中进行操作的基本单位(node并不是) 4 | -------------------------------------------------------------------------------- /db/mysql/basic.md: -------------------------------------------------------------------------------- 1 | ## mysql basic 知识 2 | 3 | Mysql目前主要有以下几种索引类型:`FULLTEXT`,`HASH`(时间复杂度 O(1)),`BTREE`,`RTREE` 4 | -------------------------------------------------------------------------------- /db/mysql/mysqlMacOSTOLinux/README.md: -------------------------------------------------------------------------------- 1 | ## 一个项目在mac上开发然后发布到Linux上该怎么做? 2 | 3 | https://nudao.xyz/ 4 | 5 | 原文:https://github.com/googege/blog/blob/master/db/mysql/mysqlMacOSTOLinux/README.md 6 | 7 | - 首先你先在mac上安装好mysql 然后安装过程 很简单了,因为mysql for mac是有可视工具的。 8 | 9 | - 然后你在你的mac上的设置里最下面会看到一个mysql的标志你打开它然后可以更改信息,例如说 更改密码之类的 10 | 11 | - 关于开发就是开发的过程了巴拉巴拉一堆省略了。 12 | 13 | 下面是关于如何发布的 14 | 15 | 首先我假设你使用一个工具,叫做`mysql workbench ` 这个工具是mysql官方出的,我个人用起来感觉还行,挺不错的,然后你去mysql官方下一个就ok了,用这个东西 16 | 17 | 你就不需要自己一个字一个字的敲sql了,然后这里要说的是如何导出数据, 18 | 19 | 在这个工具里,上面有个 Server 然后里面有个 EXport data 你点开,就会出现一个窗口,然后你配置好导出的路径,以及导出的数据库的表,然后导出即可。就ok了 20 | 21 | ***** 22 | 23 | 其实在这之前都不是很难,我的意思是配置不是说开发,然后真正放到Linux上的时候有一些坑还是要注意的,我发现网上很多的坑,很多资料都是错的。然后我们来一步一步的看看到底该怎么配置 24 | 25 | - 开始安装 mysql community 和mysql community server 26 | 27 | ```bash 28 | sudo yum install mysql-community-server 29 | 30 | ``` 31 | - 然后开始启动mysql的服务器 32 | 33 | ```bash 34 | sudo service mysqld start 35 | 36 | ``` 37 | 38 | - 然后查看一下mysql服务器的状态 看看是不是正在running 39 | 40 | ```bash 41 | sudo service mysqld status 42 | ``` 43 | 44 | - 然后接下来你需要知道mysqlroot服务器的默认root密码 当然我本来也是一位不用密码就能进去 我记得有些教程就是这么写的,但是我貌似进不去总是提示错误, 45 | 所以我是这么做的 我找到了 默认的 初始密码 46 | 47 | ```bash 48 | sudo grep 'temporary password' /var/log/mysqld.log 49 | ``` 50 | 这样你将得到了密码 密码就是 : 后面的那一坨 例如 `: db?/fsdfdsfi ` 51 | 52 | - 接下来你将使用默认密码去更改密码 53 | 54 | ```bash 55 | mysql -uroot -p 56 | 57 | ``` 58 | 59 | 进入 mysql的执行界面 然后 60 | 61 | ```bash 62 | ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!'; 63 | ``` 64 | 谨记一件事 你的密码 必须有大小写 数字和特殊符号,没有任何一项都创建失败 65 | 66 | > mysql document : validate_password 默认安装。实现的默认密码策略validate_password要求密码包含至少一个大写字母,一个小写字母,一个数字和一个 特殊字符,并且总密码长度至少为8个字符。 67 | 68 | - 然后这个时候你已经更改好密码了,mysql会退出然后你直接再次输入新密码即可, 69 | 70 | - 到这一步基本上就快结束了,你只需要把导出来的 数据 也就是 数据和表头(忘了说了,你在workbench导出的数据记得要同时导出表头信息和信息) 71 | 然后倒入信息的时候不能没有数据库 举个例子 假如说你的数据库叫做 `example ` 那么你应该先在这个新的空数据库里 先 CREATE example 创建一个同样 72 | 名称的数据库 然后 退出来 control +d 退出后呢 再开始导入数据 73 | 74 | - 最后一步 导入数据 75 | 76 | ``` 77 | mysql -u用户名 < example.sql -p 78 | 79 | 例如 mysql -uroot < example.sql -p 80 | ``` 81 | 就可以了,我这里要说一下 82 | 83 | 在某网站里它是这么写的 84 | 85 | ``` 86 | mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) 87 | ``` 88 | 这其实会报错,原因是 mysql不允许 使用-p密码 这种 方式 只能使用-p 然后输入密码 才可以 89 | 90 | **** 91 | 如何进行备份你的文件 92 | 93 | ```bash 94 | mysqldump -u root mathcoolEnd > ~/Desktop/tt.sql -p 95 | 96 | ``` 97 | 这会备份 你的所有文件,包括表头和表内容。 98 | 99 | 以上所有言论 均在 mysql community 8.x版本的言论,不涉及到 mariadb 以及 8.0以前的版本. 100 | 101 | 参考资料: https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html 102 | http://www.runoob.com/mysql/mysql-database-import.html 103 | 104 | -------------------------------------------------------------------------------- /db/redis/README.md: -------------------------------------------------------------------------------- 1 | ## redis 基本信息 2 | 3 | |:fire:类型|:book: 简介|:tea: 特征| :car:场景| 4 | |---|---|---|---| 5 | |String(字符串)| 二进制安全 |可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M| ---| 6 | |Hash(字典)| 键值对集合,即编程语言中的Map类型| 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) |存储、读取、修改用户属性| 7 | |List(列表)| 链表(双向链表)| 增删快,提供了操作某一段元素的API| 1,最新消息排行等功能(比如朋友圈的时间线) 2,消息队列| 8 | |Set(集合)| 哈希表实现,元素不重复 |1、添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作| 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐| 9 | |Sorted Set(有序集合)| 将Set中的元素增加一个权重参数score,元素按score有序排列| 数据插入集合时,已经进行天然排序 |1、排行榜 2、带权重的消息队列| 10 | -------------------------------------------------------------------------------- /go/go-surrounding/gin-middleware/README.md: -------------------------------------------------------------------------------- 1 | ## 如果开发一个gin中间件 2 | 3 | [具体看代码](./ginMiddlewareDemo.go) 4 | 5 | 所以说 gin的中间件原理就是,每一次的handle动作,都会通过中间件(你设置中间件的前提下), 6 | 7 | 要想设置中间件,只需要符合 func(*gin.Context) 即可。 -------------------------------------------------------------------------------- /go/go-surrounding/gin-middleware/ginMiddlewareDemo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | // 测试,开发一个关于gin的一个中间件 9 | func main() { 10 | engin := gin.Default() 11 | engin.Use(hui) 12 | engin.GET("/", func(context *gin.Context) { 13 | fmt.Println("/") 14 | }) 15 | engin.GET("/test", func(context *gin.Context) { 16 | fmt.Println("/test") 17 | }) 18 | engin.Run(":8080") 19 | } 20 | 21 | 22 | func hui(ctx *gin.Context){ 23 | fmt.Println("我来测试一下,所有的输出全部都会经过这一层,然后输出我这一句话:😝") 24 | } 25 | 26 | 27 | 28 | //我来测试一下,所有的输出全部都会经过这一层,然后输出我这一句话:😝 29 | /// 30 | //[GIN] 2019/03/16 - 10:19:37 | 200 | 30.598µs | ::1 | GET / 31 | //我来测试一下,所有的输出全部都会经过这一层,然后输出我这一句话:😝 32 | //[GIN] 2019/03/16 - 10:19:37 | 404 | 38.884µs | ::1 | GET /favicon.ico 33 | //我来测试一下,所有的输出全部都会经过这一层,然后输出我这一句话:😝 34 | ///test 35 | //[GIN] 2019/03/16 - 10:19:50 | 200 | 33.662µs | ::1 | GET /test 36 | //我来测试一下,所有的输出全部都会经过这一层,然后输出我这一句话:😝 37 | //[GIN] 2019/03/16 - 10:20:02 | 404 | 29.198µs | ::1 | GET /d 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /go/go/concurrency/README.md: -------------------------------------------------------------------------------- 1 | ## 探究go语言的并发和并行原理。 2 | > 原文地址: https://github.com/googege/blog/tree/master/go/go/concurrency/README.md 3 | 4 | ### goroutine基于线程池的P:M:G协程模型 5 | 首先说明一下go可以有两种并发方式 6 | - csp 7 | 8 | 也就是最常使用的go并发模式,这中模式无信息的直接交换,所以go中运用了chanel来交换数据 9 | - 共享内存 10 | 11 | 通常意义上可以理解为通过共享了内存进而来通信的并发方式,例如加lock 12 | 这种模式可以直接交换数据,但是为了并发安全需要加锁 13 | > 只有cpu中线程之间的数据交换才可以是共享内存,进程之间是无法进行信息交换的 14 | 15 | 首先我们谈谈关于cpu和操作系统线程,进程的那些事: 16 | 我们通常都听过这个一个词,cpu 4核8线程,这里的意思就是cpu实际内核是4核,但是在操作系统看来是8核cpu,这里的8线程就是指的是8个虚拟内核。然后再操作系统层面,划分为进程和线程,这里的进程是cpu资源分配(io储存等)的基本单位,在线程出现之前它也是cpu进行调度分配的基本单位,注意这里的线程是操作系统的概念,跟4核8线程里的概念不是一回事,而协程也就是coroutine是编程语言层面上的最近才有的一个东西,go里面的goroutine也可以看做是能实现并发的协程 17 | 18 | 我们知道,在操作系统的层面上而言,实现并发就是多个线程在一个cpu核心里接替执行,如果是并行呢,就是多个线程在多个cpu内核里同时执行,这里的同时才是真同时,而并发是"肉眼可见的同时但 是光速里的交替执行"如果是高cpu密集计算形式的任务其实不需要那么多个线程,只需要几个线程然后将他们分配到多个核心进行计算,这样上下文调度的时间就少了非常多了,多io形式的不需要多核,单核多线程就足够了,因为在跨线程之间的数据交换上下文切换花费的时间也不少。 19 | 20 | go实现并发的模式是PMG 21 | 22 | 如图: 23 | 24 | ![image](http://upload-images.jianshu.io/upload_images/14356536-739480e7d530b6b9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 25 | 26 | p就是上下文context m就是machine也就是对应着操作系统线程 g就是goroutine 我们来看看对应的关系 27 | 28 | 首先m对应了一个kse也就是操作系统中的一个线程,然后这个m下面有一个p就是上下文调度,然后这个p上面有一个初始的g goroutine和一个队列,这个队列里是一批的goroutine,这个就是PMG模型。这里有无数个想这样的单位,如果谁的活干完了那么它就会去抢夺别的队列的东西,并且分走一半的任务。 29 | 30 | 其实 goroutine 用到的就是线程池的技术,当 goroutine 需要执行时,会从 thread pool 中选出一个可用的 M 或者新建一个 M。而 thread pool 中如何选取线程,扩建线程,回收线程,Go 调度器 进行了封装,对程序透明,只管调用就行,从而简化了thread pool 的使用,它是定义在proc.c中,它维护有存储M和G的队列以及调度器的一些状态信息 31 | 32 | - 问 什么时候会创建另一个kse呢?(操作系统的线程) 33 | 34 | 我们可以这么看这个模型,一个地鼠推着一个车子,车子上是砖头,地鼠就是m车子就是p砖头就是g而m对应了一个kse,那么什么时候会创建另一个m呢?runtime什么时候创建线程?砖(G)太多了,地鼠(M)又太少了,实在忙不过来,刚好还有空闲的小车(P)没有使用 当这个地鼠发现自己的活太多的时候,调度器就会再启动一个m也就是线程池的概念,在操作系统层面从这个池中重新分配一个kse让他继续干活。如果一个m发现自己没活了,那么它会主动去揽活儿,如果发现没活了那么它就会去偷取同伴m的g,直接拿走一半,如果同伴也没了,那么它就去睡觉了,也就是sleep了, 35 | 36 | - go的GOMAXPROCS 是干嘛的? 37 | 38 | 在go语言启动的时候会首先查看gomaxprocs,它会根据设置的数量来创建一批p,然后将他们储存在调度器里,以链表的方式储存。它就是小推车呀 39 | 40 | - 解析goroutine协程和kse的关系 41 | 42 | 上面说了轻量级kse(操作系统线程)才是cpu调度的基本单位,你goroutine算什么?,然后刚说了mpg,m就是这个kse p就是上下文,g就是goruntine,当然除此之外,go还有一个调度器然后go在这个kse中模拟了线程执行的过程,让p负责管理,这个时候p没办法主动去取消g,只能g执行完了主动告诉p说我执行完了然后p把状态保存到栈上,然后执行另一个g,等到所有的g都执行完都返回了,就跟刚才说的一样这个m开始去取新的任务了,或者就是将p还给调度器然后自己休息了。 43 | 44 | - cpu执行的时候能同时执行多个进程吗? 45 | 46 | 答案是不行,cpu去执行进程的时候只能去操作这个进程中的多个线程,然后将这些个线程分配到不同的cpu内核中。它是无法去执行多个进程的 47 | 因为cpu同时只能执行一个进程。 48 | 49 | - cpu同时只能执行一个进程,那么我的计算机里为什么可以同时运行多个程序呢? 50 | 51 | 操作系统调度器(区分于go中的调度器哦) 拆分CPU为一段段时间的运行片,轮流分配给不同的程序。这样的话就仿佛可以同时执行不同的程序进程了,还记得你使用`kill`命令的时候吗?杀的就是进程,这些进程不能同时运行,他们被分配到不同的cpu片段里。 52 | 53 | - 为什么除了操作系统调度器go还有一个自己的调度器 54 | 55 | 单独的开发一个GO得调度器,可以是其知道在什么时候内存状态是一致的,也就是说,当开始垃圾回收时,运行时只需要为当时 56 | 正在CPU核上运行的那个线程等待即可,而不是等待所有的线程。不然如果只有os的调度器,那gc的时候就要全部停下了。 57 | 58 | 综上所述: 59 | 60 | - cpu同时只能执行一个程序(操作系统kse进程)(例如同时执行一个go程序然后接下来再单独执行一个qq)但是操作系统将cpu分为了多时间片段,并且速度够快,所以你看起来就是同时执行喽 61 | 62 | - cpu可以将这个进程中的很多线程分配到不同的cpu核心里。这样就实现了并行,因为它只能识别一个进程,但是进程中有很多线程。 63 | 64 | - 线程池的概念在go中主要是用于分配那个m,并且是go自己的调度器来分配的 65 | 66 | - GOMAXPROCS的功能是为了分配p也就是车子,分配好了车子就储存在调度器中,m可多可少,但是车是一定的。 67 | 68 | - 在这个车子中g的数量可多可少,可以非常多,那么m也就是这个kse是根据GOMAXPROCS来定的,他的数量<= GOMAXPROCS指定的数量,但是最多不能超过256(不论你的gomaxpocs设置的是多少) 69 | 70 | - cpu将这个m也就是操作系统线程分配到多个cpu内核中 71 | 72 | - 如果GOMAXPROCS设置是1 那么只能讲这个线程分配到一个cpu内核中了,因为只有一个线程,(p只有一个,当然m也是只有一个)所以就是并发不能并行了 73 | 74 | - 上下文context 也就是p 管理着这里面一个队列的的很多个的goroutine,所以这么说来,p是控制局部G的调度器也可以这么说,但是它不能主动控制g,是g说我执行完了,告诉它而已。但是和go自己的本身的调度器不是一回事儿。go本身的调度器实现了很多功能例如说分配M. 75 | 76 | - go单独于os的调度器也就是区别于os的调度器 它是管理这个线程池的 --- 管理如何分配m 77 | 78 | ### channel 基于生产者消费者模型的无锁队列 79 | 80 | 首先解释一下什么是生产者消费者模式: 81 | 有三个东西,生产数据的一个任务(可以是线程,进程函数等)一个缓存区域,一个使用数据的任务这个模式基本上可以类比:厨师做饭+把饭放到前台+你去端饭。 82 | 83 | 还记得上文谈的csp模型吗?这里的channel就是csp中通信的部分,上文的goroutine是并发实体 84 | 85 | channel的创建是使用的make,那么这说明了什么?说明了channel的初始值肯定是nil,channel变量是一个引用变量(具体是一个struct的指针) 86 | 87 | channel分为两种:无缓存的channel和有缓存的channel什么区别呢?无缓存的就是有东西就需要读,不读就没法再往里面加东西,有缓存的就是不读也能继续加东西。就这么个区别。Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯。 88 | 89 | ### net.conn 基于epoll的异步io同步阻塞模型 90 | 91 | epoll是Linux为了替代poll模型而打造的支持高并发的产物,net.conn基于这个模型进行打造。其实就是go调用了Linux的epoll模型来打造的net.conn,同步阻塞 其实就是调用多goroutine+非缓存的channel来实现。 92 | 93 | ### syscall 基于操作系统的原生syscall能力 94 | go语言里的读取都可以使用操作系统提供的syscall功能,几乎所有 Linux 文件相关系统调用,Go 都有封装 95 | 96 | 97 | ### net/http基于goroutine的http服务器 98 | 99 | 在看源代码的时候可以看出来每个请求,go都会启动一个goroutine来进行服务。这个就是go net.Listen高并发的关键。 100 | 101 | ### 并发安全的hash map slice 102 | 103 | 在syscall.map中提供了这个并发安全的map,如果不使用这个原生的map在跨goroutine就可能发生资源抢断的问题,没有这个函数的时候,使用lock unlock也可以实现相关的功能。 104 | 105 | ### 可实现cas context基于channel的goroutine流程控制能力 106 | context包,是go新增的一个包,这个包主要的目的是提供一个上下文,我们可以使用这个包来实现goroutine之间的一些调配 107 | 举个例子 当a goroutine里新增一个b groutine,那么当a运行5分钟后要求b结束,该怎么做呢? 108 | 109 | 使用ctx.WitchTimeOut 就给b发送信号,让它关闭,看个例子 110 | 111 | ```go 112 | func main(){ 113 | ctx,cal := context.WithTimeout(context.Background(),5*time.Second) 114 | ctx = context.WithValue(ctx,"12","12") 115 | go b(ctx) 116 | time.Sleep(1e10) 117 | cal()// 执行取消命令 118 | time.Sleep(1e10) 119 | 120 | } 121 | func b(ctx context.Context) { 122 | for { 123 | time.Sleep(time.Second) 124 | select { 125 | case <-ctx.Done(): 126 | fmt.Println(ctx.Value("12")) 127 | return 128 | default: 129 | fmt.Println(".") 130 | } 131 | } 132 | 133 | } 134 | 135 | // output: 136 | 137 | /* 138 | 139 | . 140 | . 141 | . 142 | . 143 | 12 144 | 145 | */ 146 | ``` 147 | 148 | ### 以实现有限的动态性 atomic基于cpu原子操作的包装 149 | atomic包的所有动作都是基于cpu的原子操作,atomic 提供的原子操作能够确保任一时刻只有一个goroutine对变量进行操作 150 | 这样的话就可以避免在程序中出现的大量lock unlock的现象了。你可以理解为atomic是轻量级的锁 151 | 152 | ### gosched 基于阻塞的协程调度 153 | 154 | Gosched产生处理器,允许其他goroutines运行。它不会挂起当前的goroutine,因此执行会自动恢复。 155 | 这句话的意思就是,遇到这个go.Gosched,这个goroutine就会让出执行的机会给其它的goruntine。 156 | 157 | 158 | ### go gc基于三色标记法的并发gc模型 159 | 160 | go的垃圾回收和正在执行的逻辑goruntine不是同一个goroutine,这些goroutine是分别占用cpu时间片段的,这就导致go 的运行中gc的时候go程序并不是都停止的,(gc需要内存保持一致,需要停止)如果一个内存对象在一次GC循环开始的时候无法被访问,则将会被冻结,并在GC的最后将其回收。 161 | 162 | 中心思想就是 163 | 164 | 根节点设置咋白色区域内,然后子程序在灰色区域中,然后gc扫描内存对象,将其设置为黑色,当然他的子程序也是在灰色中,将白色区域中没有任务的变量回收了,然后将灰色区域中没有引用依赖的内存对象移动到黑色区域中,然后灰色区域中的不可达的的程序将会在下一次gc的时候被收回,然后 这个黑色的区域直接变成白色,进行下一次循环。 165 | 166 | 总结 167 | - 根节点在白色区域 168 | - 子程序在灰色区域 169 | - 将白色区域没有用的变量回收 170 | - 将灰色区域中的没有引用依赖的(说白了 无依无靠没有什么指向的)变量或者是什么程序之类的送到黑色区域 171 | - 然后灰色区域的变量如果这次无法回收,就下次gc回收 172 | - 进行下一次循环。 173 | - gc过程和正常运行的逻辑代码并行执行。 174 | -------------------------------------------------------------------------------- /go/go/concurrency/go-goroutine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/go/go/concurrency/go-goroutine.jpg -------------------------------------------------------------------------------- /go/go/deadlock/README.md: -------------------------------------------------------------------------------- 1 | ## go 并发时的死锁问题 2 | 3 | 关键词 `并发并行, chan, goruntine, close, select, time` 4 | 5 | 总结来看,为什么会死锁?***信道上如果发生了流入无流出,或者流出无流入,也就导致了死锁。*** 6 | 7 | 还是那个例子,当一个有缓存的通道,没有close,但是range一次在接受它,那么就符合了,通道流入无流出,通道没有关闭(range遇到关闭的通道自动就跳出了) 8 | 但是没有流出了,但是range一直等待流入,所以就死锁了。 9 | -------------------------------------------------------------------------------- /go/go/escape-analysis/README.md: -------------------------------------------------------------------------------- 1 | ## go语言逃逸分析 2 | 3 | 任何时候,一个值被分享到函数栈帧范围之外,它都会在堆上被重新分配,说道这个问题了,我们就谈谈帧边界,这个名词的作用是在函数执行的时候 4 | 为了函数的上下文所设置的一个边界,它存在在栈中,栈在 Go 语言中是非常重要的,因为它为分配给每个函数的帧边界提供了物理内存空间,所有又有一个名词叫栈帧 5 | 然后有个问题就是在栈的执行过程中,只能执行在这个栈以上的部分,举个例子abc三个函数,a调用b b调用c 那么痛调用机制来说最高的就是a,最低的就是c 6 | 7 | 举个例子: 8 | 栈的就像一个筒子的存钱的东西,你每次需要从下面往上塞硬币,然后用的时候也是从下面往外扣。很形象了哈。 9 | 10 | 然后在go语言执行的过程中,如果传递的是值就不发生堆的问题了,因为不会指向栈帧边界的下面的问题,因为值被复制到了,为了运行b函数而临时在a中开辟的内存空间里了。不存在和下面的b函数的瓜葛了。 11 | 12 | 当你使用的是指针,那么复制过去的也是指针,然后你想要使用这个值就要去取栈帧边界下面的东西,但是又不能去得到,怎么办呢,这个时候就需要将下面的这个指针指向的变量存放到堆里,这不就解决了嘛,当然你免不了要gc啊。所以又是资源时间的浪费,如何掂量你自己看着办吧。 13 | 14 | ```go 15 | 16 | package main 17 | 18 | type user struct { 19 | name string 20 | email string 21 | } 22 | 23 | func main() { 24 | a1 := createUser1() 25 | a2 := createUser2() 26 | 27 | fmt.Println("a1", &a1, "a2", &a2) 28 | } 29 | 30 | func createUser1() user { 31 | u := user{ 32 | name: "Bill", 33 | email: "@.com", 34 | } 35 | 36 | fmt.Println("V1", &u) 37 | return u 38 | } 39 | 40 | //go:noinline 41 | func createUser2() *user { 42 | u := user{// 发生了逃逸分析 43 | name: "Bill", 44 | email: "bill@ardanlabs.com", 45 | } 46 | 47 | fmt.Println("V2", &u) 48 | return &u 49 | } 50 | ``` 51 | 52 | 指针指向了栈下的无效地址空间。当 main 函数调用下一个函数,指向的内存将重新映射并将被重新初始化,这就是逃逸分析将开始保持完整性的地方 53 | 54 | 编译器将检查到,在 createUserV2 的函数栈中构造user值是不安全的,因此,替代地,会在堆中构造相应的值 55 | 56 | 值只有在编译器编译时知道其大小才会将它分配到栈中。这是因为每个函数的栈帧大小是在编译时计算的。如果编译器不知道其大小,就只会在堆中分配。 57 | 例如有一个数组你没有给它分配大小,那么它就没办法放到栈里就会放到堆里。 58 | 59 | 总结: 60 | 61 | - 当函数执行的时候无法执行**帧边界**下面的部分就会发生将数据推入堆的逃逸分析 62 | - 当分配的数据,程序无法知道具体的大小的时候就会放到堆里 63 | 64 | > 例如一个不知道大小的map或者一个不知道大小的slice。 65 | 66 | 逃逸分析的可怕之处就是造成大量的gc,因为堆的数据垃圾回收是go通过gc来回收的。 67 | -------------------------------------------------------------------------------- /go/go/ignore-but-important/README.md: -------------------------------------------------------------------------------- 1 | ### go语言的一些不容易被注意到的但是又很重要的问题 2 | 3 | #### map的最大cap是多少? 4 | 5 | #### map的len和cap map的自动扩容是什么原理? 6 | #### goroutine的最大量是多少? 7 | #### mpg模型中的p最多能有几个?(也就是GOMAXPROCS) -------------------------------------------------------------------------------- /go/go/important/README.md: -------------------------------------------------------------------------------- 1 | ## 关于go语言的几个陷阱,以及我们应该注意的东西 2 | 3 | 1. 闭包 4 | 5 | 所谓闭包就是指一个函数中的函数,并且这个函数可以调用外部的变量并且无论使用多少次, 6 | 都可以一直拥有这个变量不回收,那么这个变量可以称为闭包变量。 7 | 8 | ```go 9 | func test() []func() { 10 | var funs []func() 11 | fmt.Println(funs == nil) 12 | for i:=0;i<2 ;i++ { 13 | //t := i 然后下面改成t就ok了。就是这么简单。因为t就一个值,每个t都是一个新的内存地址而i是一个值,它也是引用变量。 14 | // 闭包只是抓住某个变量不放手 刚好i是引用变量所以抓住i不放手的话 那么所有函数的i都是一眼的,但是t又不一样,抓住不放手也无所谓了。 15 | funs = append(funs, func() { 16 | println(&i,i) 17 | }) 18 | } 19 | return funs 20 | } 21 | 22 | func main(){ 23 | funs:=test() 24 | for _,f:=range funs{ 25 | f() 26 | } 27 | } 28 | ``` 29 | 答案 xxx 2 30 | xxx 2 31 | 32 | 原因就是 闭包是引用变量,所以 他们的最后的i是最后的那个i 33 | 34 | 2. 循环体变量 35 | 36 | ```go 37 | 38 | package main 39 | 40 | import ( 41 | "fmt" 42 | "time" 43 | ) 44 | func main(){ 45 | tt() 46 | } 47 | func tt() { 48 | for i := 0; i < 10; i++ { 49 | go func() { 50 | time.Sleep(1e3) 51 | fmt.Println(i) 52 | }() 53 | } 54 | time.Sleep(1e9) 55 | } 56 | 57 | ``` 58 | 这个函数执行的时候 tt中打印出来的是10 59 | 原因也是很简单,因为go在初始化的时候先初始化参数量,全局先初始参数再看函数,在函数内部先初始参数再进行运算,所以 就造成在for执行完后 这里的i是同样的i 60 | 以为初始化的参数 i一直会变,但是都是这个变量本身,又因为for循环比内部的函数速度快很多,导致,当for循环进行完了,这些函数还没正式开始运行,然后i就取最终值 10了 61 | 62 | 3. return 和 defer 的执行顺序 63 | 64 | 在go里 65 | 66 | ```go 67 | 68 | package main 69 | 70 | import "fmt" 71 | 72 | func tt() int { 73 | var i = 0 74 | defer func() { 75 | fmt.Println(i) 76 | i++ 77 | fmt.Println(i) 78 | }() 79 | 80 | return i 81 | } 82 | 83 | func main() { 84 | tt() 85 | } 86 | 87 | ``` 88 | 在这个函数中 执行顺序是这样的 首先先初始化 i = 0 89 | 然后 defer无法初始化(参数变量)因为它没有 90 | 然后到了return 然后 直接执行了后面的内容 没错 什么都没有就是i而已 91 | 然后 开始了return 直接将值返回了,这时候它没有结束 因为有defer 92 | 所以开始执行了defer,然后defer中i是几?嗯 是0 因为这个时候i是0了 93 | 然后 打印了0 i再次++ i等于1了,然而并没有什么机会去用这个i了,因为 94 | 已经return过了,所以这个i就被收回了,加入return后面是一个闭包,那么这个i 95 | 就有用了,它就不会被收回。 96 | 97 | 然后 这个时候函数就结束了。 98 | 99 | 看一下 这几种特殊情况 100 | 101 | 102 | ```go 103 | // return 1 "defer tt1 0" 104 | func tt1() int { 105 | var i = 0 106 | defer fmt.Println("defer tt1", i) 107 | i++ 108 | return i 109 | } 110 | 111 | // return 1 "defer tt1 0" 112 | func tt2() int { 113 | var i = 0 114 | defer func(i int) {// 参数复制,值的复制。 115 | fmt.Println("defer tt2:", i) 116 | }(i) 117 | i++ 118 | return i 119 | } 120 | 121 | // 1 1 122 | func tt3()int{ 123 | var i =0 124 | defer func() { 125 | fmt.Println("defer tt3",i) 126 | i++ 127 | }() 128 | i++ 129 | return i 130 | } 131 | 132 | //1 2 133 | //2 134 | func tt4() func() int { 135 | var i = 0 136 | defer func() { 137 | fmt.Println("defer tt4:",i) 138 | i++ 139 | }() 140 | 141 | i++ 142 | return func() int { 143 | 144 | return i// 引用变量。 145 | } 146 | } 147 | -------- 148 | package main 149 | 150 | import "fmt" 151 | // 0 13 152 | func tt5() (num int) { 153 | defer func() { 154 | fmt.Println("dd", num) 155 | num++ //这里的num的作用于属于上层的函数体 156 | }() 157 | return 12// 返回值是函数运行最后的num值,很明显是defer中的num值。然后返回1 158 | // 这种形式的返回值,因为return 后面什么都没,所以它就会查找这个函数域内的最后值。因为函数的运行是 159 | //运行return后面的的内容 + defer + 隐藏的os.Exit() 160 | 普通模式下是 运行return后面的内容 +返回return后面的内容 +运行defer + os.Exit() 161 | 162 | } 163 | func main(){ 164 | fmt.Println(tt5()) 165 | } 166 | 167 | func main() { 168 | fmt.Println(tt5()) 169 | fmt.Println(tt6()) 170 | } 171 | //dd 0 dd1 2 return 1 172 | func tt6() (num int) { 173 | defer func(num int) {//// 使用这种形式 defer的函数内部的值已经是num的一个拷贝了,所以它里面怎么改变都不影响外部的return 174 | fmt.Println("dd", num) 175 | num++// 这里的num属于本层函数的作用域,所以它无法改变外层函数的数值。 176 | num++ 177 | fmt.Println("dd1", num) 178 | }(num) 179 | num++ 180 | return 181 | 182 | } 183 | 184 | 185 | 186 | ``` 187 | 188 | 4. 变量的调用和直接改变参数本身 189 | 190 | ```go 191 | func tt(){ 192 | var i 193 | dd(i) 194 | fmt.Println(i) 195 | 196 | } 197 | 198 | func dd(i int){ 199 | i++ 200 | fmt.Println(i) 201 | } 202 | 203 | // 1 0 204 | 205 | ``` 206 | 原因就是dd(i)这个是代表了 赋值,也就是将var的值赋予了dd的形参 207 | 可以看做是 d = i 208 | dd(d) 这个叫做赋值 然后值的拷贝或者是指针的传入以及指针的获取实际值是这个地方的问题 209 | 210 | 然后还有一种是这样的 211 | 212 | ```go 213 | 214 | func tt(){ 215 | var i = 0 216 | { 217 | i = 12 218 | } 219 | fmt.Println(i) 220 | } 221 | ``` 222 | 我之前因为跟赋值搞混所以我总是是用 223 | 指针来更更改i其实是错误的理解,因为这个地方的i = 12 压根就没有赋值 224 | 这一种说法它不过是更改自己的值而已,就像上面的那个函数即使使用指针, 225 | 那么更改指针的实际值的时候也是这么干的,所以i = 12 只是这个参数的在 226 | 调整自己的值罢了,它是改变的自己,这里就不牵涉到 是值的拷贝还是引用的拷贝了 227 | 因为它压根没有拷贝,仅仅是改变自己罢了。 228 | 229 | 5. 值的方法和指针的方法 230 | 231 | 首先 指针的方法和值的方法可以互相调用,因为go会自动帮你 232 | 比如指针的方法g()你使用了值来调用那么go会帮你自动取地址相对的如果是 233 | 值的方法 go自动帮你取 * 234 | 235 | 第二个地方 236 | 首先 值上面可以有方法 指针上面也是有方法,我们谈的是 关于对象的方法这点先阐述 237 | 因为除了struct(对象)其它类型除了 指针和nil都可以有自己的方法 238 | 其它类型不讨论 239 | 240 | 就是指针的方法的时候,那么go会自动帮你取这个对象的*,因为指针没办法取得对象 241 | 里面的value值,只能*去得到,但是go帮你取了,所以你可以使用看似 242 | 指针直接去值。 243 | 244 | 6. 关于实现接口 245 | 246 | 这个地方go很严格,首先就是接口类型的变量不允许取指针,本来它就是引用类型了(初始化是nil)nil取不到method。 247 | 虽然slice这种也是引用类型但是go允许你取它的指针,但是接口类型不允许取(取了也没有意义) 248 | 249 | 而且对于实现一个接口来说如果你是指针类型实现的接口,那么将变量传递给指针类型时 250 | 251 | 也必须是指针类型的变量,值同样,不允许自动取&或者* 252 | 举个例子 253 | 254 | ```go 255 | type a interface{ 256 | 257 | get() 258 | } 259 | type b struct { 260 | c value 261 | } 262 | 263 | func(b1 *b)get(){ 264 | fmt.Print(b1.c)// go帮你自动取了 *b1这个地方不变,go帮你自动取对象的值,在这个地方也可以。 265 | } 266 | func ddc(a1 a){ 267 | a1.get() 268 | } 269 | 270 | func main(){ 271 | b1 := new(b) 272 | var b2 b 273 | ddc(b1)// 正确 274 | ddc(b2)// 错误❌ 275 | } 276 | 277 | 278 | 279 | ``` 280 | 7. 关于slice 281 | 282 | slice赋值的时候可以不用指定类型 283 | 284 | ``` 285 | type t int 286 | slice := make([]t,10) 287 | 288 | slice = [][]int{ 289 | {1}, //不需要使用 t{1} 290 | {2}, 291 | {3}, 292 | } 293 | 294 | ``` 295 | 296 | 如果slice里面还是slice或者是map等这种引用类型的话是这么处理的 297 | 298 | ```go 299 | 300 | slice := make([][]int,10) 301 | slice[0] = make([]int,4) 302 | // 或者 303 | slice[1] = []int{ 304 | 1,2,3,} 305 | 306 | ``` 307 | 因为 引用类型不初始化的话 本身就是nil 所以会panic 308 | 309 | 310 | 8. 关于变量的初始化 311 | 312 | 关于这个地方我也出错过 313 | 314 | ``` 315 | func dd(t *int){ 316 | fmt.Println(*t) 317 | } 318 | func main(){ 319 | var t *int 320 | 321 | dd(t) 322 | 323 | 324 | } 325 | 326 | 327 | ``` 328 | 这样就会出错,因为 所有的变量都会初始化(go没有声明 go会自动初始化) 329 | 但是t是个指针类型,它的初始化就是nil,所以*nil是错误的,正确的方法是 330 | 331 | 332 | ```go 333 | 334 | func dd(t *int){ 335 | fmt.Println(*t) 336 | } 337 | func main(){ 338 | var t int 339 | 340 | dd(&t) 341 | 342 | 343 | } 344 | ``` 345 | 346 | 或者优雅一点 347 | 348 | ``` 349 | func dd(t *int){ 350 | fmt.Println(*t) 351 | } 352 | func main(){ 353 | t := new(int) 354 | 355 | dd(t) 356 | 357 | 358 | } 359 | ``` 360 | 361 | 8. slice 关于他的len和cap 362 | 363 | 不要超过它的len来查找数据。(而不是cap)只要是超过了len就会报错,虽然没有超过cap 364 | 但是它的out of range 错误是根据len来定的。 365 | 366 | 9. 不要获取map的值的地址 367 | 368 | ```go 369 | t := make(map[string]string) 370 | t["12"] = 12 371 | fm.println(&t["12"]) 372 | ``` 373 | 因为map是动态的,所以它的value的值 的地址不是固定的所以go不允许取得 374 | 它的地址。 375 | 376 | 但是 slice可以。 377 | 378 | ```go 379 | 380 | b := make([]int,12) 381 | b[1] = 12 382 | fmt.Println(&b[1])//0xc00001e128 slice 可以 383 | 384 | ``` 385 | 386 | 10. recover的使用只能在 defer中使用(其它地方调用无效果) 387 | 388 | ```go 389 | 390 | func tt(){ 391 | defer func(){ 392 | if t := recover;t { 393 | fmt.Print(t) 394 | } 395 | } 396 | dd()//dd里有panic 397 | } 398 | 399 | ``` 400 | 401 | 11. 关于接口类型的断言 402 | - 接口实例.(接口类型) 403 | - 接口实例.(实际类型) 404 | 405 | 但是这两个的前面 无一例外都需要传入实际的类型也就是变成了 406 | - 实际类型的实例.(接口类型) 407 | - 实际类型的实例.(实例类型) 408 | 409 | 举个例子 410 | ```go 411 | type a struct { 412 | value string 413 | } 414 | 415 | type b interface { 416 | get() 417 | } 418 | type c interface{ 419 | post() 420 | } 421 | 422 | func tt(b1 b){ 423 | // 第一种情况 424 | if v,ok := b1.(c);ok {// 这个实例 相当于实现了这两个interface 425 | fmt.println(v.post()) 426 | fmt.Println(v.get()) 427 | } 428 | 429 | // 第二种情况 430 | if v,ok := b1.(a);ok { 431 | fmt.Println(v.get()) 432 | } 433 | } 434 | ``` 435 | 再看一个实际运用上的例子: 436 | ```go 437 | type a struct { 438 | value string 439 | } 440 | 441 | type ber interface { 442 | get() 443 | } 444 | 445 | type cer interface { 446 | post() 447 | } 448 | 449 | func (a1 a) get() { 450 | fmt.Println(a1.value) 451 | } 452 | 453 | func (a1 a) post() { 454 | fmt.Println(a1.value + "p") 455 | } 456 | 457 | func t(b1 ber){ 458 | // 这个内部的cer必不可少。 459 | type cer interface {// 这就是为了验证 已经实现了ber的变量是否也实现了cer 460 | post() 461 | } 462 | if v, ok := b1.(cer); ok {// 这个地方隐藏的说明了 a的实例是满足ber的,不然它这一步就会panic然后它还得满足cer不然还会panic所以这一步直接验证了两次。 463 | v.post() 464 | } 465 | b1.get() 466 | 467 | } 468 | ``` 469 | 470 | 12. 关于递归, 471 | 递归其实就是在执行函数里的函数,直到所有函数都结束了,然后就结束即可。举个例子 472 | 473 | 474 | ```go 475 | func testVisit(ii int) int { 476 | if ii == 0 { 477 | return 100 478 | } 479 | fmt.Println(ii) 480 | ii = testVisit(ii - 1) 481 | 482 | return ii+1 483 | } 484 | 485 | ``` 486 | 它的执行很明显是从外层的初始栈开始往里执行,然后所有栈执行完毕即可,这里我使用了`ii = testVisit(ii -1)` 目的有两个,1 为了让每下一个的ii都少1,2 就是为了获取上一个栈的返回值,然后每次返回都+1 最后的返回值是109 这也证明了每次返回都是从最上层的栈开始往下调用然后到最下面的然后返回。 487 | 488 | 13. 关于 channel 489 | 490 | chan 的机制是这样的,当一个没有缓存的(有缓存也是一样只是当缓存满了就一样了)chan,显示导入一个数据,这个时候 491 | 这个发送chan的goruntine就睡眠了(阻塞)然后直到这个chan被接受(只要被接收就行,不管是不是在同样一个goruntine)然后这个数据就被获取了,然后开始唤醒这个chan的发送者的那个goruntine。如果没有后续的数据那么这个chan就应该被关闭了可以人工关闭(close)也可能被系统收回。 492 | 493 | 看一个例子 这是一个有缓存的,并且利用缓存来限制 http请求数量的操作 494 | 495 | ```go 496 | var st = make(chan struct{},20)// 将访问的数据限制在20 497 | var sy synv.WaitGroup 498 | func main(){ 499 | dd := []string{"htps://...",",,,,,",",,,"} 500 | sy.Add(len(dd)) 501 | for _,v := range dd { 502 | 503 | go read(dd)// 504 | } 505 | 506 | sy.Wait() 507 | fmt.Println("执行完毕") 508 | } 509 | func read(st){ 510 | defer sy.Done() 511 | st <- struct{}// 因为是有缓存的chan所以可以保证一直有20个gorutine是不阻塞的。 512 | // 只要有一个goruntine不是阻塞的就不会造成死锁 513 | rea(st) 514 | <- st 515 | } 516 | func rea(st string){ 517 | res,err := http.Get(st) 518 | } 519 | ``` 520 | 521 | 只要有一个goruntine不是阻塞的就不会造成死锁,死锁是程序想退出,但是chan内还有东西,没办法退出,但是又没办法运行,造成了无法结束的窘迫,最终就是各个goruntine都是阻塞然而又不能退出的局面。总之 死锁问题有必要再开一个文件来讨论一下。 522 | 523 | 14. 关于 type 524 | 525 | alias的类型和底层可以转化但是不是隐式是显式。 526 | 527 | 这里分几个内容 528 | - 一就是 529 | 530 | ```go 531 | type hand func(http....,http.....) 532 | 533 | // 例如 534 | 535 | httprouter.handle("/",httprouter.handle) 536 | // 这个时候就是 537 | httprouter.Handle("/",func(http....,http....)) 538 | // 即可。 539 | ``` 540 | 541 | 这种类型的尤其是在函数的调用的时候 要满足 一个hand类型也是很简单 就是函数满足后面那个样式即可 542 | 543 | - type hand string 544 | 545 | 这种情况也是 函数满足后面的那个 type即可 也就是 是string即可 。 546 | 547 | 15. 关于引用类型 548 | 549 | 举个 slice说明一下 550 | 551 | ```go 552 | 553 | func main(){ 554 | t := make([]int,0,10) 555 | t = []int{ 556 | "12", 557 | } 558 | visit(t) 559 | fmt.Println(t) 560 | } 561 | 562 | func visit(t []string){ 563 | t = append(s,"1221") 564 | } 565 | ``` 566 | 猜一下 输出的是什么? 567 | 是 ["12","1221"]吗? 568 | 我本来一直以为是,后来我发现其实不是,我们要先证实一个问题,引用类型并不是指针,它是一个数据结构通常是 一个cap 一个len和一个指针对象。所以它本身也是一个实际的值。当这个地方把t传入visit后,其实是值的复制,然后在visit中,t等于了一个append返回的一个新的slice,那么它就不是指向了原来的那个底层数组了,(换言之,这样的话就不是改变底层数组了,是重新分配了一个数组,那么原来的那个slice自然就跟这个新的底层数组没有关系了)那么什么时候会改变呢,也很简单 569 | 570 | ```go 571 | func visit(t []string){ 572 | t [1] = "112" 573 | } 574 | 575 | ``` 576 | 577 | 这就叫做赋值,它是直接操控底层的数组进行了值的改变,这并没有去进行值的拷贝或者是指针传递。到这里我么可以说一下了 578 | 在go里所有的类型只要是传递数据只有两种模式,1 值的拷贝(包括引用类型它的拷贝只不过是拷贝的它的数据组织)2 指针的拷贝,说白了,指针的拷贝也是值的拷贝,因为它本身也是一种值只不过象征了一种钥匙罢了,所以,除了对数据本身进行直接改变,改变他的数据本身,这种行为可以改变它自己,值的传递的话 统统是有拷贝行为。所以我们以后不能把引用类型看成指针,很不一样。如果是指针的话 那么肯定必须要获取值才能去改变,但是引用类型是go的编译器自动的行为。(例如扩容啊,自动获取底层数据的值啊这种) 579 | 580 | 581 | 16. 关于带(bare return)形参及不带形参的返回值和defer的故事 582 | 583 | 带bare的那种 ,最后的栈尾是 包含了defer了的,不带bare的不包含defer 584 | 举个例子 585 | 586 | ```go 587 | 588 | func a(i int)(t int){ 589 | defer func(){ 590 | t+=i 591 | } 592 | return 1 593 | } 594 | a(12) 595 | 那么结局是 13 过程是 在return1的时候这个时候t就是等于1 596 | 的但是因为defer栈还没结束,那么开始执行了最后的defer了,然后return出去了的值,那这个值就是 13 597 | 598 | func a(i int)int{ 599 | defer func(){ 600 | t+=i 601 | } 602 | return 1 // 因为是不带bare的那么 return的栈就直接出来了,defer是不经过这个return栈的 defer之后调用了os.exit() 所以 1 就是最后的返回值。 603 | } 604 | 605 | 606 | ``` 607 | 看两个例子: 608 | 609 | > 之前的例子说过了,defer只是执行滞后但是参数记住是参数也就是将形参传入实参的过程其实是同步的并没有什么区别。 610 | 611 | ```go 612 | // 这个例子中返回值是1 613 | func tt()(t int){ 614 | defer func() { 615 | t ++ 616 | }() 617 | return 618 | } 619 | 620 | // 这个例子中返回值是0 621 | func tt1()int{ 622 | t := 0 623 | defer func() { 624 | t ++ 625 | }() 626 | return t 627 | } 628 | // 0 这个例子证明了 参数顺序执行化。 629 | func tt1()int{ 630 | t := 0 631 | defer func(t int) { 632 | t ++ 633 | }(t) 634 | return t 635 | } 636 | ``` 637 | 638 | 原因也是很简单,首先如果是没有形参的返回值,都是在return后面直接返回的,然后再执行defer然后再执行 os.exit() 但是有形参的就不一样了,它必须返回它形参定义的参数之歌例子中就是t,那么t在哪最后一个出现呢?就是在defer中,所以它的执行过程就变成了,找寻最后出现的t(这里出现在defer中)然后直接执行os.exit() 因为它return后面没有东西,所以它和没有形参的return XXX 很不一样。 639 | 那么如果是这样的呢? 640 | ```go 641 | func age()(n int,err error){ 642 | return 643 | } 644 | ``` 645 | 它会有什么返回结果呢?答案就是`0 nil` ---- 如果只有return 但是却没有出现n和err那么简单 返回值里不是已经初始化了嘛,那么久返回初始化的结果不就好了嘛所以是 `0 nil`(他们的初始化值) 646 | 17. 关于buffered 647 | 648 | 我们在go的执行中经常使用的一种技巧就是限制go并发的速度,那么这个时候buffered变量就可以实现了它的实现是这样的 ` make(chan xxx,number)` 在get请求中一般我都会这么使用`make(chan struct{},20)` 我们定义了一个新的类型就是 struct{} 这个类型是代表了空,当然你也可以使用bool 都可以 struct{} 类型使用的时候 用 struct{}{} 即可。这就代表了这个chan中最多可以暂存number个数据,这就是所谓的缓存技术,也叫做 buffered数据 649 | 650 | 18. 关于 recover和并发(多goruntine) 651 | 652 | 如果是在go的多协程中的panic一定要在这个协程中recover否则在主协程的recover根本无法获取这个panic 653 | 654 | ```go 655 | go func(i int) { 656 | defer sy.Done() 657 | defer func() { // 如果是在外部获取recover可以说压根获取不了,想想也是知道的因为你并不知道主协程和这个协程到底哪个运行到哪了,所以要在这个协程中搞定这个panic 658 | if e := recover();e != nil { 659 | fmt.Println(e) 660 | } 661 | }() 662 | start := time.Now() 663 | resp, err := http.Get(url[i]) 664 | 665 | if err != nil { 666 | fmt.Println(err) 667 | } 668 | n, err := html.Parse(resp.Body) 669 | if err != nil { 670 | fmt.Println("err",err) 671 | return 672 | } 673 | defer resp.Body.Close() 674 | if err != nil { 675 | fmt.Println(err) 676 | } 677 | wor, im := countWordsAndImagesAsync(nums, ch, n) 678 | ma.Store(url[i]+" num", wor) 679 | ma.Store(url[i]+" image", im) 680 | end := time.Now() 681 | timeS := end.Sub(start) 682 | ma.Store(url[i]+"花费的时间是:",timeS.String()) 683 | }(i) 684 | ``` 685 | 19. 关于递归的出栈和进栈 686 | 递归都有一个进出栈的过程, 687 | ```go 688 | func a(){ 689 | visit(start,end) 690 | } 691 | func visit(start,end func()){ 692 | start()//在进栈时执行的函数 693 | for { 694 | visit() 695 | if XXXXXX 然后退出这个栈开始出栈 696 | } 697 | end()// 在出栈时执行的函数。 698 | } 699 | ``` 700 | 701 | 20. 关于 函数内部的函数 702 | 703 | ```go 704 | 705 | func t(){ 706 | var d func()int // 使用这种方式一般都是函数内部有递归,如果不实现 声明一下 函数内部的递归函数将无法运行 707 | 708 | d = func()int{ 709 | //fdffd 710 | } 711 | d() 712 | 713 | // 或者 714 | var d = func(){ 715 | 716 | } 717 | d() 718 | 719 | 总之,不能使用 720 | func()int{ 721 | 722 | } 723 | int() 在go语言中这种行为不允许 724 | 725 | } 726 | ``` 727 | 关于函数内部声明类型 倒是很随意 728 | ```go 729 | 730 | func t(t1 inter){ 731 | type t struct{ 732 | get() 733 | } 734 | if d,ok := t1.(t);ok { 735 | d.get() 736 | } 737 | t1.post() 738 | } 739 | 740 | 741 | 742 | ``` 743 | 21. 只有接口和nil不能拥有方法。 744 | 745 | ```go 746 | invalid receiver type io.Writer (io.Writer is an interface type) // 这是使用了接口的报错。 747 | 748 | nil is not a type// 这是使用了nil的报错 749 | ``` 750 | 751 | > ps: 永远不要去取接口的指针,没有丝毫的意义。如果取 slice的指针还有些许的意义(比如在append的时候)但是接口的指针有什么意义? 752 | 接口本来就没有实际的意义它本来就是一个抽象的东西。而且它本来也就是引用对象。 753 | 754 | 755 | 23. time.After 的用法 756 | 757 | 它的作用是 当这个系统没有东西了,然后在设置后几秒后运行,如果其他的case一直有东西,那么它是不会被执行的。 758 | 因为在select选择的时候只有在其他的case都没有反应了的时候才会去选择time.After 所以它可以用在 比如什么东西都没有数据了以后 759 | 然后按照某时间后去取消这个东西,当然还有一种应用场景就是,无论如何就是要5分钟后取消,打死都要 760 | 那么可以 使用两个select,有一个select就放一个after和一个default即可。 761 | ```go 762 | select{ 763 | case time.After(): 764 | return // 这样就强制 退出了 765 | default: 766 | 767 | } 768 | 769 | select { 770 | // 这个select就是干正事的。 771 | } 772 | ``` 773 | 或则,使用 context包的withcanceltimeout 这个函数厉害 无论如何 只要设置的分钟数到了,就能立马取消。 774 | 因为cancle withcancle那个函数 如果 不执行cancle函数 那么ctx.done 就无法运行,这个时候 cancle的关闭就要在执行这个有ctx的函数之前了。就不能使用defer函数来关闭这个,因为一直有东西运行。 775 | 776 | 24. 关于 string字符串 []byte 以及[]byte的十六进制表示(以string形式储存) 777 | 778 | ```go 779 | // 将string字符串,以unicode编码的形式,找到所有的字符的unicode表示,然后返回位一个数组。 780 | // [72 101 108 108 111] 就是这个数组(slice) 781 | src := []byte("Hello") 782 | // 这个encodeStr 是什么呢?它其实就是把这个数组的所有的数字用16进制表示并且没有加[]而已,而是将这个串变成了字符串的形式储存 783 | // 就是这个“48656c6c6f” 这个字符串其实还是unicode编码只是 用的16进制并且没有[]罢了,一定不要认为它就是"HELLO" 784 | encodedStr := hex.EncodeToString(src) 785 | fmt.Println(src) 786 | // 48656c6c6f -> 48(4*16+8=72) 65(6*16+5=101) 6c 6c 6f 787 | fmt.Println(encodedStr) 788 | byteValue,_ := hex.DecodeString(encodeStr) 789 | string(byteValue) == "Hello" 790 | ``` 791 | 25. 关于json的一个解析的问题 792 | 793 | ```json 794 | {"code":0,"data":{"ip":"173.82.115.125","country":"美国","area":"","region":"加利福尼亚","city":"洛杉矶","county":"XX","isp":"XX","country_id":"US","area_id":"","region_id":"US_104","city_id":"US_1018","county_id":"xx","isp_id":"xx"}} 795 | 796 | ``` 797 | ```go 798 | type Data struct { 799 | Data Values `json:"data"` 800 | } 801 | type Values struct { 802 | Country string `json:"country"` 803 | City string `json:"city"` 804 | } 805 | 806 | ``` 807 | 808 | 定义的时候可以缺少字段,但是,不能跟json字段的格式不符合,举个例子 这里的数据是 在json整个文件下的data对象中,那么你需要两个struct 一个是代表整个的json的数据,第二个struct是代表那个data,你看 那个code和其它字段没有定义吧,没有定义无所谓,但是字段的格式一定要遵守 如果直接把Values传进去就是错误的行为,是不会解析的。 809 | 810 | 26. 关于go template 811 | 812 | 第一点 如果你使用`template.Execute` 那么你在那个最外边的layout那个文件里不能使用`{{define "layout"}}{{end}}` 813 | 如果你想使用`{{define "layout"}}{{end}}` 那么 你需要` tem.ExecuteTemplate(w,"layout",nil)`那个中间的变量要用最外边的那个模块 814 | 所以最好的就是最外边的那个不用模块,然后使用那个没有模块的就ok了 815 | 816 | 第二点 如果如果你的子模块就是小的模块很多人称作是母模块 我当他们是小模块子模块,他们里面有变量,那么你肯定是最后使用的是layout这个最外面的文件或者说是模块 817 | 那么你就要`{{template "son".}}` `.` 看到了吗 这个点没有这个点 你在最外面的模块也就是最终使用的时候你发现你的变量压根没有导入,这个就是 变量导入的标志 818 | 也就是是 你的子有了 如果不导入 那么这个数据就消失了,我被这个地方坑了几个小时。我的天~~~~。 819 | 820 | 27. 关于iota 821 | 822 | 这个东西是有几个特点的其中 823 | - 从0开始自动计数 824 | - 中间可以有间隔,然后重启计数,并且仍然是按照原先的顺序进行计数 825 | ```go 826 | package main 827 | 828 | import "fmt" 829 | 830 | const( 831 | a = iota // 从0开始 832 | b // 按照iota的特性可以继续往下计数,并且继承它的类型 833 | c 834 | d 835 | e 836 | f = "1" // 可以中断 837 | tew // 在没有重启之前一直是按照中断时候的定量来进行赋值 838 | weew 839 | we 840 | r 841 | t 842 | h 843 | cd = iota // 直到继续重启,数字是重启了, 但是值类型变成了系统默认值 int 844 | gt 845 | ut 846 | yyt 847 | tyy 848 | ) 849 | 850 | 851 | func main() { 852 | fmt.Println(a,b,c,d,e,f,tew,weew,we,r,t,h,cd ,gt,ut,yyt,tyy) 853 | fmt.Println(reflect.TypeOf(a),reflect.TypeOf(b),reflect.TypeOf(f),reflect.TypeOf(gt)) 854 | 855 | } 856 | // output: 857 | //0 1 2 3 4 1 1 1 1 1 1 1 12 13 14 15 16 858 | //int64 int64 string int 859 | 860 | ``` 861 | 862 | ### 关于range使用的是复制值的 陷阱 863 | 864 | ```go 865 | package main 866 | 867 | import "fmt" 868 | 869 | func main() { 870 | a := []int{1, 2, 3} 871 | for k, v := range a { // range后面的a 是对于 上面的a的复制值 ,但是由于slice底层array连带变了,所以v值就会产生变化 872 | if k == 0 { 873 | a[0], a[1] = 100, 200 874 | fmt.Print(a) 875 | } 876 | a[k] = 100 + v 877 | } 878 | fmt.Print(a) 879 | 880 | a1 := [3]int{1, 2, 3} 881 | for k, v := range a1 { // 这里的a1 是上面a1的复制值,所以v永远就跟之前的那个样子一样,纵然 真实的a1发生了变化但是复制值是不会变化的 882 | if k == 0 { 883 | a1[0], a1[1] = 100, 200 884 | fmt.Print(a1) 885 | } 886 | a1[k] = 100 + v 887 | } 888 | } 889 | 890 | //[100 200 3][101 300 103][100 200 3] 891 | 892 | 893 | ``` 894 | 895 | ### 关于range时的指针问题 -- 动态数据问题 896 | 897 | 898 | 899 | ```go 900 | func pase_student() { 901 | m := make(map[string]*student) 902 | stus := []student{ 903 | {Name: "zhou", Age: 24}, 904 | {Name: "li", Age: 23}, 905 | {Name: "wang", Age: 22}, 906 | } 907 | // 错误写法 908 | for _, stu := range stus { 909 | // 关键的地方就是在于 range后面的那个stus是上面的那个的复制值,所以stu也是一个复制的值它怎么变都不会改变上面那个真实的stus的结果所以应该 910 | // 使用 i := 0 stus[i] i++ 这样的方式来改变range的这种复制的结果。这样就可以真实改变status的值了。 911 | m[stu.Name] = &stu 问题出在哪个地方了? 很简单 所有的 m[xxx] = "同样称呼的动态地址" 也就是说 大家都是等于 &stu 除非每次等于的东西不一样否则 那最后取得的值肯定一样。 除非是 等 &stu+i i++ 就是这么个问题,为什么 stu.name 没问题原因人不是动态类型啊 直接取得到真实值了呗。 912 | } 913 | 914 | for k,v:=range m{ 915 | println(k,"=>",v.Name) 916 | } 917 | 918 | // 正确 919 | for i:=0;i",v.Name) 924 | } 925 | } 926 | 927 | 928 | ``` 929 | ### 关于defer和参数函数的问题 930 | 931 | ```go 932 | func main() { 933 | a := 1 934 | b := 2 935 | defer calc("1", a, calc("10", a, b)) //我们还记得 不管是不是defer 他们的参数初始化是顺序执行的,那么 里面的calc 作为参数就会先执行所以“10” 就会先执行 然后再是 “20” 然后 defer的真实执行 又开始是 “2” “1” 所以 他们的顺序是 10 20 2 1 反正记住一条就哦了 就是 参数的初始化是顺序执行的。 936 | 937 | a = 0 938 | defer calc("2", a, calc("20", a, b)) 939 | b = 1 940 | } 941 | 942 | ``` 943 | 10 1 2 3 944 | 20 0 2 2 945 | 2 0 2 2 946 | 1 1 3 4 947 | 948 | ### 关于copy的地方 949 | 950 | ```go 951 | 952 | s := []int{1,2,3,4} 953 | copy(s,[]int{10,332,22}) 954 | 955 | 结果就是 [10,332,22,4]被覆盖了 956 | 957 | copy(s,[]int{11,21,31,41,51,61,7,8}) 958 | [11,21,31,41] 按照小的那个的len 所以就被丢弃了。 959 | 960 | 所以一般前面的那个slice就应该是空的。 961 | ``` 962 | 963 | ### append的容易错的地方 964 | 965 | ```go 966 | append 是添加到前面的那个slcie的后面 967 | 968 | 举个例子 如果是 969 | d := make([]int,5) 970 | t := append(d,[]int{1,2}) 971 | o: [0,0,0,0,0,1,2] 就是这样了。 跟copy不同 972 | ``` 973 | ### 结构体的比较 974 | 975 | 进行结构体比较时候,只有相同类型的结构体才可以比较,结构体是否相同不但与**属性类型**以及**个数**有关,还与**属性顺序**相关。 976 | 还有一点需要注意的是结构体是相同的,但是结构体属性中有**不可以比较的类型,如map,slice**。那么也不能比较, 如果该**结构属性都是可以比较的**,那么就可以使用`“==”`进行比较操作。 977 | 978 | ### go 的定量const 的值是无法取得到地址的。因为它的存在是在编译期间就获得了,不是在运行期间。 979 | 980 | ### goto不能跳转到*其他函数*或者内层代码 981 | 982 | ```go 983 | func main(){ 984 | 985 | for { 986 | loop: // 内层 987 | } 988 | goto loop 989 | } 990 | ``` 991 | ### 关于panic和defer 992 | 993 | 结论: 同一个作用域中的panic会相互的覆盖,所以recover显示的是最后的那个结果 994 | 995 | ```go 996 | func a(){ 997 | defer func() { 998 | if r := recover();r != nil { 999 | fmt.Println("hhahah",r) 1000 | } 1001 | }() 1002 | defer func() { 1003 | panic("1") 1004 | }() 1005 | panic("2") // 2 就被1覆盖了。 1006 | } 1007 | 1008 | 1009 | ``` 1010 | 1011 | ### go中通道发送完以后一定要关闭通道,不然就会死锁 1012 | 1013 | ```go 1014 | package main 1015 | 1016 | import ( 1017 | "fmt" 1018 | "sync" 1019 | ) 1020 | 1021 | var wg sync.WaitGroup 1022 | 1023 | func main() { 1024 | var line string 1025 | fmt.Scanln(&line) 1026 | ch := make(chan string, 1000) 1027 | wg.Add(2) 1028 | for _, value := range line { 1029 | ch <- string(value) 1030 | } 1031 | close(ch) // 这里 如果不关闭ch就会造成死锁。 1032 | go func() { 1033 | for n := range ch { 1034 | fmt.Println("读者1range:", n) 1035 | } 1036 | wg.Done() 1037 | }() 1038 | go func() { 1039 | for n := range ch { 1040 | fmt.Println("\t读者2range:", n) 1041 | } 1042 | wg.Done() 1043 | }() 1044 | wg.Wait() 1045 | } 1046 | 1047 | ```` 1048 | 1049 | 没close的不能用for range 也就是说你如果想range一个通道,那么这个通道需要时close的通道 1050 | 1051 | 如果一个chan的输入不一定那么就不能关闭了,所以就不能用range了,直接使用for就ok了。 1052 | 1053 | 综上 1054 | 1055 | 如果输入是一定的值 直接输入完close即可,然后使用range 如果 不一定那么不能close 使用for{}的一般形式去读取即可。 1056 | 1057 | ### 不能修改字典中value为结构体的属性值。 1058 | 1059 | map中的value其实是指向value的指针,指针可以读取结构体的属性值,但是无法更改值,需要一个新的struct,然后让map的value值等于这个struct即可。 1060 | 1061 | ### 关于go的多重循环体 [for, select, switch] 1062 | 1063 | > https://golang.org/ref/spec#Break_statements 1064 | 1065 | 因为他们之间的嵌套因为并不知道要跳出的是哪一层,所以这个时候,我们需要加上标签,也就是跟goto那个标签很像的那个标签 1066 | ````go 1067 | LOOP: //注意 Loop是放到for上面的,我们再看goto 1068 | for{ 1069 | select{ 1070 | case: 1071 | break LOOP 1072 | } 1073 | } 1074 | 1075 | for { 1076 | select { 1077 | case: 1078 | goto Loop 1079 | } 1080 | } 1081 | Loop: // 应该放到for下面,因为goto是直接跳转。而多重的循环体是为了指定break哪一层。所以break和continue都是放到上面、 1082 | 1083 | ```` 1084 | -------------------------------------------------------------------------------- /go/go/optimization/README.md: -------------------------------------------------------------------------------- 1 | ### go语言中的常见优化 2 | 3 | - 如果你有一个数量很大的struct请记住要传递指针而不是值 4 | - go中slice和map都可以自动的进行扩容,但是要记得扩容就要浪费时间,甚至slice还是要重新指向一个新的底层array,也就是重新分配内存空间,这都要消耗大量的时间。所以能判断多少空间的,自己给定一个len和cap就好了,map中只能给定一个len不能设定cap因为map可以自动扩容。而且它也不能使用cap方法来测定他的cap,只能用len()方法 5 | - 为什么不不让你乱用指针?原因很简单,如果发生了[逃逸机制](https://github.com/googege/blog/tree/master/go/go/escape-analysis/README.md)以后,那么你就面临了一个问题,大量的数据被存储在了堆里,而系统是无法管控你的堆空间的,你需要使用gc进行控制,而gc势必要发生时间上的消耗,和"stop the world",所以不能所有数据统统使用指针,得不偿失! 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /go/tool/goMod/README.md: -------------------------------------------------------------------------------- 1 | ## go mod go官方的module管理工具 2 | > youtube https://www.youtube.com/watch?v=saJ2c006vp4 3 | #### 用法: 4 | 5 | 在一个非go path的路径中新建一个项目,然后使用`go mod init` 就可以初始化一个新的包(要开启这个 `export GO111MODULE=on`写入.bash_profile即可 win的同学自己找找设置 GO111MODULE的win版本设置方法哈),其实跟github(gitlab都行)用在一起更好 6 | 7 | 1. 在github上新建一个项目,例如说 test 8 | 2. 在本地将这个远程包给clone过来,然后这个文件夹里面就是一个.git 隐藏的文件项目这个就是git的管理文件包 9 | 3. 将此包放在远离 go path的文件路径里,然后使用 `go mod init` 就可以创建一个名为 github.com/XXX/test的包 10 | 记住,这个包名不能随意称呼,你的文件夹的名称就是你的包名然后里面的XX.go的名字无所谓,只要`package test`用对就可以了,然后你会发现你的包内出现了两个文件 **go.sum** 和 **go.mod** 这个sum包你可以忽略,主要是go.mod包这里的包 首先开头是 module github.com/XXX/test 声明了 这个包的具体名称是 **"github.com/XXX/test"** 但是在调用的时候 包的名称是 test为什么module后面要加上所有的路径呢,原因也是很简单,就是当你 `go get github.com/xxx/test`的时候用,不然你只有一个test go get是没办法下载这个包的。 11 | 4. 将这个包发布到github即可。 12 | 13 | ## 版本 14 | > 在`go.mod`中的包后面手动输入latest `github.com/nfnt/resize latest`,go将自动(go list)帮你生成一个版本号 `github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646` 15 | 16 | - 你本地的项目引用别人的包的时候可以在go.mod 中指定version的版本,但是什么都不指定也可以,默认是latest,也就是你直接`go get github.com/xx/app`的时候它自动就是引入latest的版本了,要指定某个版本,你在go.mod 改了就行了。当包中未使用具体version的时候,第三个人用你的包时候然后默认下载你的包引用的包的版本,indirect的包(非直接引用的包)的版本是最新的那个版本,这里的最新就跟你的最新不是一回事了,如果引用的包的go.mod中明确指明了version而不是latest这种形式,那么你引用它的时候它的间接包的版本默认跟你的是相同的,不过你自己也可以更改的哦(能明白吧我感觉有点绕,😝) 17 | 举例子: 18 | 19 | 这是gin的go.mod摘选 20 | ```go 21 | github.com/gin-contrib/sse v0.0.0-20190124093953-61b50c2ef482 22 | github.com/golang/protobuf v1.2.0 23 | 24 | ``` 25 | 这是我本地项目的go.mod摘选: 26 | ```go 27 | github.com/gin-contrib/sse v0.0.0-20190125020943-a7658810eb74 // indirect 28 | github.com/golang/protobuf v1.2.0 // indirect 29 | ``` 30 | 你会发现同样都是v1.2.0 但是上面的那个 一个是 20190124 一个是20190125,我们看一下下载包的时候的bash的截图 31 | ```bash 32 | finding github.com/stretchr/testify/assert latest 33 | ``` 34 | 如果你用的包它用的包,它没有指定具体的版本,那么你的latest跟他的就可能不是一回事了,这个要清楚。因为go get 下载的时候是此时此刻的latest。 35 | 36 | `require github.com/coastroad/test v0.0.0-20190216094021-0555a706efff // indirect` 37 | 这里 后面就是指定的版本 // indirect就是间接引用的意思。 38 | - 你的包的具体version其实是 git来管理的 1 你可以使用 git push -tag 来指定某一个version. 39 | 第二你可以选择不写version 40 | 然后别人用你的包的时候就不能指定这个version了只能用 latest来引入包 通常来说是你最后编辑的日期例如`v0.0.0-20190216094-55a706efff` 41 | 42 | - 版本 version2.X version 3.X该怎么办?go mod官方推荐的方法如下 43 | 44 | ```go 45 | module github.com/xxx/test/v2 46 | 47 | ``` 48 | 也就是说你的包的名字还是test但是因为版本是v2.X 所以要在包名后面加入大版本号 /v2(一定是v+数字 比如 v2 v3 v4 v5不能改变写法也不能用v2.3这种写法) 49 | 然后 调用的时候是这样的 50 | 51 | ```go 52 | 53 | package dd 54 | 55 | import( 56 | "github.com/xxx/test/v2" 57 | ) 58 | 59 | func dd(){ 60 | 61 | test.Test() 62 | } 63 | ``` 64 | 也就是说使用imprt的时候 也要加 v2大版本号,但是在函数内调用的时候 还是test 比如这个时候你的版本是v2.45 65 | 那么 你的mod文件里最后的标注就是v2.45 66 | 67 | > 就算不是v2.45 不通过打tag的方式来发布 比如还是默认的数字,那么只要你在mod中指定是v2 你的版本大号就是v2 68 | 在import中引入还是需要加上v2 只是在mod中 显示的信息是你的最后编辑时间。 69 | 70 | 还有种写法是 71 | ```go 72 | module github.com/xx/app.v2 73 | ``` 74 | 这种写法也是类似,只是官方不推荐这种写法。 75 | > 作为一种特殊情况,以gopkg.in/开头的模块路径继续使用,在该系统上建立的惯例:主要版本始终存在,它前面有一个点而不是斜杠:gopkg.in/yaml.v1和gopkg.in/yaml.v2,而不是gopkg.in/yaml和gopkg.in/yaml/v2。 76 | 77 | 综上: 78 | 79 | ```go 80 | // 你的包 81 | go.mod 文件写法 : module github.com/xxx/test/v2 82 | 83 | 别人用你的包的写法 import( 84 | "github.com/xxx/test/v2" 85 | ) 86 | 87 | func dd(){ 88 | test.Test() 89 | } 90 | ``` 91 | ### 包的存放位置 92 | 93 | 再使用了go mod后你的go path将没有用了,但是存放的包的位置还是在 老的go path 更明确来说是在 $gopath/src路径 94 | 这个路径会有两个文件 pkg bin 前面这个包是存放的非可执行的包 后面的bin放置的就是可执行的包,你可以把path指向这个bin即可。 95 | 96 | ### go mod tidy 97 | 98 | 这个命令很有用 首先我们看看它的官方解释 **tidy: add missing and remove unused modules** 99 | 也就是说 你的go.mod中多引入的或者是少引入的 使用 `go mod tidy` 它可以帮你处理 100 | 101 | ### 我的包是可执行的文件,我发布到github上让人使用我的mod该怎么办 102 | 你的go.mod 可以写成 `github.com/xxx/test`但是你的文件的package 应该写成main 或者目前而言在github上的 103 | 可执行文件的包没有go.mod也可以,你只需要在本地开发的时候有go.mod即可。然后这个go.mod 中的名称不跟package一样也可以 104 | 因为别人是不会再引用你的包的了。但是如果你的包有子包,那么你还是应该把你的包go.mod文件里的 module 后面规规矩矩的写例如 105 | ```go 106 | module github.com/XXX/add 107 | 108 | 然后别人引用的时候 109 | import( 110 | "gitub.com/xxx/ddd/app" // app 是子包 即可。 111 | ) 112 | ``` 113 | ### 我go get的包,但是并没有在我的项目中使用,我该怎么处理我的go.mod 114 | 举个例子,你要拉取一个在github上的包,这个包呢,是一个可执行的包(main包)然后你需要在一个有go.mod的项目中使用go get才能拉下来,然后不出意外你的这个拉取记录就会出现在go.mod上,你不想让他出现该怎么办呢?很简单使用 `go mod tidy `就可以从go.mod 中删除。 115 | 116 | ### 我无法使用goalng.org/x的包我该怎么办 117 | 118 | 例如: 119 | 你本地的包要引入 golang.org/x/net/html 120 | 但是被封了,那么你可以使用github上的镜像包 例如说是 github.com/golang/x/net/html 121 | 122 | 在你的项目的go.mod 中 加入 replace golang.org/x/net/html => github.com/golang/x/net/html 123 | 但是一般你科学上网不就行了吗。。 124 | ### 我该怎么处理我的子包和我的包的关系 125 | - 本地 126 | 在本地 比如说你的大包要引用子包的内容你可以go.mod 中使用replace,比如github.com/app/中 127 | 要引入 github.com/app/app的东西,你可以 在go.mod 中 用 replace github.com/app/app => ./app 即可 128 | 当,你发布的时候你把这个replace删掉即可。(仅限 *Unix系统,就是改变路径而已,win的同学自己看看咋弄就ok了,反正发布的时候要删除) 129 | 130 | ### 当我的文件夹的名称跟我的package写的包名不一样怎么办 131 | 132 | 要记得 一个文件夹(包)内的package 名称必须相同,但是可以不跟文件夹的名称一样,使用的时候其实很不爽就是了 133 | 不过也可以用 用法是 134 | 135 | 比如一个包 它的文件夹是 app 但是 package中的名称是 app1 那么可以这么用 136 | 137 | ```go 138 | imoirt "github.com/xxx/app" // 这个地方要跟文件夹的名称保持一致 其实就是跟路径保持一致 139 | func dd(){ 140 | app1.xxx// 这里要跟真实的package保持一致 你看 得不偿失吧 所以 文件夹的名称要跟package的名称保持一致 141 | 142 | } 143 | ``` 144 | ### 当我想忽略掉某包的时候我该怎么做? 145 | 146 | ```go 147 | 148 | module github.com/x/x 149 | exclude github.com/test/test latest // 或者把latest换成其它的版本比如v1.23.1 都可以。 150 | 151 | ``` 152 | ### 该如何配置包的路径 153 | 举个例子,你有一个域名 `please.io`,有服务器,你想让被人下载的时候不使用github.com/xx/xx 而是使用自己的路径进行下载,那么你可以这么做 154 | 155 | - 首先将你的go mod 中的module命名为你自己设定的路径 例如 `module please.io/tt` 然后还是放在github上, 156 | - 在你的服务器上增加一个route,`/tt`然后在打开的这个页面的html的meta标签里添加上`` 157 | - 搞定了。 158 | ### 注意 159 | 160 | 你的包如果存放在github上 你的包的go.mod module后面一定是github.com/xxx/xxx不能直接写成 xxx 这样的话 161 | go mod 无法获得包 错误是`parsing go.mod: unexpected module path "test" 162 | go: error loading module requirements 163 | ` 164 | 总结: 165 | - 也就是说 go.mod 的module 要跟go get xx/xxx 保持一致 例:`module github.com/app/app` 在使用 166 | 开启 go mod后 使用go get 的时候也是 `go get github.com/app/app` 167 | 168 | - 文件夹可以不跟package的具体包名保持一致,import的时候是用的文件夹名(路径), 函数中时候是用的package的名字 169 | 170 | - 有main包的时候 go.mod 要跟文件夹的名称保持一致,子包该怎么引入就怎么引入 例如 github.com/app/dd 171 | dd是子包 app这个路径中是main包。 172 | 173 | ### ⚠️ 174 | 175 | - 文件包的名称和package的名称要保持一致(main包除外) 176 | - 要用go mod 代替 go path 和dep 大势所趋 177 | - go mod中的module名称一定要跟gitub上的路径(其实是git的路径,这个路径没有github上的tree/master)保持一致。不然没办法拉取 178 | - 子包和包不能互相引用可以小引大也可以大引小但是不能互相。 179 | - 不要把项目放到go path中了,go path要取消了。(我猜的) 180 | - 最后 使用 `go help mod `有几个命令上面有提示。就不一一解释了。 181 | 182 | ```go 183 | The commands are: 184 | 185 | download download modules to local cache 186 | edit edit go.mod from tools or scripts 187 | graph print module requirement graph 188 | init initialize new module in current directory 189 | tidy add missing and remove unused modules 190 | vendor make vendored copy of dependencies 191 | verify verify dependencies have expected content 192 | why explain why packages or modules are needed 193 | 194 | 195 | ``` 196 | -------------------------------------------------------------------------------- /go/tool/performance-testing/README.md: -------------------------------------------------------------------------------- 1 | ## go 性能测试 2 | 3 | 有以下几个工具需要知道 4 | - go tool pprof 也就是pprof性能测试工具 5 | - alloc_space 选项替代默认的 -inuse_space 选项。这将会向你展示每一次分配发生在哪里,不管你分析数据时它是不是还在内存中 6 | (使用 go tool pprof 查看所有的帮助信息参数信息啥的 go tool trace等go tool命令也是一样,输入命令不带任何的tag就可以查看 7 | 所有的命令,但是如果是一级命令 比如 go build 该如何查看help呢?使用go help build 这种形式即可) 8 | - 进入命令中 使用help查看命令中的全部信息,使用help 具体命令可以显示更详细的信息 例如 help list 9 | - google's pprof工具 10 | - go tool trace 工具 11 | - go test 压力测试 -bench(压测对象 可以使用. 来测试全部的对象也可以单独制定函数) -benchtime (压测时间) -benchmem(压力测试中的内存占用启动标签,不需要制定=谁,这个标签是开启内存测试的标志) -memprofile(将生成适用于pprof的测试文件) 12 | - go build -gcflags "-m -m" 这个标签可以测试何时何物逃逸分析了。(就是从栈逃到堆了) 13 | 14 | ### go tool pprof 15 | 首先pprof进行分析是有前提的那就是需要有数据,如何来提供数据?go提供了三种办法 16 | - http/pprof包 将测试单独列为一个独立的goroutine然后单独监听,此包就可以单独的在浏览器中打开一个数据分析的html页面 17 | - runtime/pprof包 将这包的 类似 start 和stop函数放到数据中间,就可以对这段数据进行测试,进而生成某些测试数据 18 | - go test 使用 memprofile标签就可以得到一个函数的数据,所以它的数据只有那种写了测试数据的函数才有。 19 | ### google's pprof 20 | 21 | `go get github.com/google/pprof` 22 | 使用测试数据,可将此数据更加可视化的显示在html中 23 | ### go tool trace 24 | 更pprof 类似可使用 http/httptrace包和runtime/trace包进行数据的测试得到测试数据,然后是用go tool trace + 数据即可 25 | 26 | go tool trace更适合于找出程序在一段时间内正在做什么,而不是总体上的开销。总体的话就是 go tool pprof 27 | ### go test 28 | 跟上文一致,具体的就不展开了就是那个意思。 29 | ### go build 30 | 如上 31 | 32 | 我将使用一个我实际开发的案例来分析如何运用以上的工具来进行具体的数据分析,静待更新吧。 33 | 34 | -------------------------------------------------------------------------------- /mixtalk/all/README.md: -------------------------------------------------------------------------------- 1 | # 复习大纲(转发) 2 | > http://naotu.baidu.com/file/be0f61015fccab0c0b29f3e042174cb1?token=65092c0c03d17a8a 3 | 4 | ## 资料 5 | 6 | - [CS-Notes](https://cyc2018.github.io/CS-Notes/#/) 7 | - [后端面试进阶指南](https://xiaozhuanlan.com/topic/2167809435) 8 | 9 | ## 协议 10 | 11 | 分享或者修改演绎时请保留本协议,并署名 [@CyC2018](https://dwz.cn/ZGWCOICD)。 12 | 13 | [CC BY - Creative Commons Attribution](http://creativecommons.org/licenses/by-nc-sa/4.0) 14 | 15 | ![](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png) 16 | 17 | 18 | ## README 19 | 20 | 21 | ### 协议 22 | 23 | 分享或者修改演绎时请保留本协议,并署名 [@CyC2018](https://dwz.cn/ZGWCOICD)。 24 | 25 | [CC BY - Creative Commons Attribution](http://creativecommons.org/licenses/by-nc-sa/4.0) 26 | 27 | ![](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png) 28 | 29 | ### 目的 30 | 31 | 方便大家系统梳理知识点,并且针对每个知识点可以在本脑图中写 Markdown 笔记。 32 | 33 | 每个知识点也有相应的完成度和优先级,对于不同重要程度的知识点应该采取不同的复习方法,从而提高学习效率。 34 | 35 | 你应该把这个脑图当做最基本的复习材料,每天都要大概地过一遍,保持短期记忆,一定要知道,短期记忆对面试来说至关重要。 36 | 37 | 也可以将收集的资料整理在本脑图中,从而方便复习。 38 | 39 | ### 来源 40 | 41 | [知识总结方法](https://xiaozhuanlan.com/topic/4150387926) 42 | 43 | ### 关于我 44 | 45 | https://dwz.cn/ZGWCOICD 46 | 47 | ### 样式修改 48 | 49 | 百度脑图自带的样式效果不佳,建议安装以下样式脚本:[百度脑图](https://userstyles.org/styles/163774/theme)。 50 | 51 | ### 保存方法 52 | 53 | 点击左上角菜单,然后另存为“我的文档”。 54 | 55 | 56 | 57 | 58 | 59 | 60 | ## 数据结构与算法 61 | 62 | 63 | ### 资料 64 | 65 | - [剑指 Offer 题解](https://cyc2018.github.io/CS-Notes/#/notes/剑指%20offer%20题解) 66 | - [Leetcode 题解](https://cyc2018.github.io/CS-Notes/#/notes/Leetcode%20题解) 67 | - [算法](https://cyc2018.github.io/CS-Notes/#/notes/算法) 68 | - 《算法》 69 | - 《剑指 Offer》 70 | - 《程序员代码面试指南》 71 | - 《挑战程序设计竞赛》 72 | - [Leetcode](https://leetcode.com/problemset/algorithms/) 73 | - [玩转算法面试 从真题到思维全面提升算法思维](https://coding.imooc.com/class/82.html) 74 | 75 | 76 | ### 算法思想 77 | 78 | #### 排序 79 | 80 | ##### 选择排序 81 | 82 | ##### 冒泡排序 83 | 84 | ##### 插入排序 85 | 86 | ##### 希尔排序 87 | 88 | ##### 归并排序 89 | 90 | ##### 堆排序 91 | 92 | #### 字符串 93 | 94 | ##### 指纹 95 | 96 | ##### KMP 97 | 98 | ##### AC 自动机 99 | 100 | ##### 排序 101 | 102 | ##### Trie 103 | 104 | #### 树 105 | 106 | ##### 红黑树 107 | 108 | 109 | ###### 回答 110 | 111 | - JDK 中 TreeMap 和 TreeSet,1.8 之后的 HashMap 和 ConcurrentHashMap 112 | - 介绍二叉查找树、23查找树,再介绍红黑树原理 113 | - 与 B+ 树进行比较 114 | 115 | ###### 资料 116 | 117 | - [红黑树 - 维基百科](https://zh.wikipedia.org/zh-hans/%E7%BA%A2%E9%BB%91%E6%A0%91) 118 | 119 | 120 | ##### B+ 树 121 | 122 | ##### LSM 123 | 124 | ##### AVL 125 | 126 | #### 图 127 | 128 | ##### 最短路径 129 | 130 | ##### 最小生成树 131 | 132 | ##### 拓扑排序 133 | 134 | ##### 并查集 135 | 136 | ##### 网络流 137 | 138 | #### 散列表 139 | 140 | ##### 拉链法 141 | 142 | ##### 线性探测法 143 | 144 | #### 其它 145 | 146 | ##### 汉诺塔 147 | 148 | ##### 哈夫曼编码 149 | 150 | ### 海量数据处理 151 | 152 | #### TOP-K 153 | 154 | #### 海量数据判重 155 | 156 | #### 海量数据排序 157 | 158 | #### MapReduce 159 | 160 | ### 数学与逻辑 161 | 162 | #### 概率题 163 | 164 | ##### 抢红包 165 | 166 | ##### 洗牌 167 | 168 | ##### 蓄水池抽样 169 | 170 | ##### Rand7 171 | 172 | #### 智力题 173 | 174 | ## 操作系统 175 | 176 | 177 | ### 资料 178 | 179 | - 《现代操作系统》 180 | - 《深入理解计算机系统》 181 | - 《UNIX 环境高级编程》 182 | - 《Unix/Linux 编程实践教程》 183 | - 《鸟哥的 Linux 私房菜》 184 | - 《The Linux Command Line》 185 | 186 | 187 | ### 基础 188 | 189 | #### 进程与线程 190 | 191 | #### 进程状态 192 | 193 | #### 进程调度算法 194 | 195 | #### 线程实现方式 196 | 197 | #### 协程 198 | 199 | #### 进程同步问题 200 | 201 | #### 进程通信 202 | 203 | #### 死锁 204 | 205 | - 死锁必要条件、解决死锁策略,能写出和分析死锁的代码,能说明在数据库管理系统或者 Java 中如何解决死锁。 206 | 207 | #### 虚拟内存 208 | 209 | #### 页面置换算法 210 | 211 | 特别是 LRU 的实现原理,最好能手写,再说明它在 Redis 等作为缓存置换算法。 212 | 213 | #### 分页与分段 214 | 215 | #### 静态链接与动态链接 216 | 217 | ### Linux 218 | 219 | #### 文件系统 220 | 221 | - 从文件系统的角度分析数据恢复原理 222 | 223 | #### 硬链接与软链接 224 | 225 | #### 常用命令 226 | 227 | - 能够使用常用的命令,比如 cat 文件内容查看、find 搜索文件,以及 cut、sort 等管线命令。了解 grep 和 awk 的作用。 228 | 229 | #### 僵尸进程与孤儿进程 230 | 231 | - 僵尸进程与孤儿进程的区别,从 SIGCHLD 分析产生僵尸进程的原因。 232 | 233 | ## 网络 234 | 235 | 236 | ### 资料 237 | 238 | - 《计算机网络 自顶向下方法》 239 | - 《计算机网络》 240 | - 《TCP/IP 详解 卷 1:协议》 241 | - 《UNIX 网络编程 卷 1:套接字联网 API》 242 | - 《Linux 多线程服务端编程》 243 | - 《图解 HTTP》 244 | 245 | 246 | ### 基础 247 | 248 | - [计算机网络](https://cyc2018.github.io/CS-Notes/#/notes/计算机网络) 249 | 250 | #### 体系结构 251 | 252 | #### 以太网 253 | 254 | #### 网络硬件设备 255 | 256 | - 集线器、交换机、路由器的作用,以及所属的网络层。 257 | 258 | #### IP 数据报 259 | 260 | #### ARP 协议 261 | 262 | #### ICMP 协议 263 | 264 | #### UDP 与 TCP 265 | 266 | #### TCP 连接 267 | 268 | - 理解三次握手以及四次挥手具体过程,三次握手的原因、四次挥手原因、TIME_WAIT 的作用。 269 | 270 | #### TCP 可靠传输 271 | 272 | - 设计可靠 UDP 协议 273 | 274 | #### TCP 拥塞控制 275 | 276 | #### DNS 277 | 278 | - 279 | 280 | ### HTTP 281 | 282 | - [HTTP](https://cyc2018.github.io/CS-Notes/#/notes/HTTP) 283 | 284 | #### GET 与 POST 285 | 286 | #### 状态码 287 | 288 | #### Cookie 289 | 290 | #### 缓存 291 | 292 | - [Expires 和 max-age 的区别](https://www.cnblogs.com/yinhaiming/articles/1490811.html) 293 | - [Expires vs max-age, which one takes priority if both are declared in a HTTP response? 294 | ](https://stackoverflow.com/questions/7549177/expires-vs-max-age-which-one-takes-priority-if-both-are-declared-in-a-http-resp) 295 | 296 | #### 连接管理 297 | 298 | #### HTTPs 299 | 300 | #### HTTP/2 301 | 302 | #### 版本比较 303 | 304 | #### HTTP 与 FTP 305 | 306 | ### Socket 307 | 308 | - [Socket](https://cyc2018.github.io/CS-Notes/#/notes/Socket) 309 | 310 | #### I/O 模型 311 | 312 | #### 多路复用 313 | 314 | #### Java NIO 315 | 316 | ## 数据库 317 | 318 | 319 | ### 资料 320 | 321 | - 《MySQL 必知必会》 322 | - [Leetcode](https://leetcode.com/problemset/database/) 323 | - 《高性能 MySQL》 324 | - 《MySQL 技术内幕》 325 | - 《Redis 设计与实现》 326 | - 《Redis 实战》 327 | - 《大规模分布式存储系统》 328 | 329 | 330 | ### SQL 331 | 332 | #### 手写分组查询 333 | 334 | #### 手写连接查询 335 | 336 | #### 连接与子查询 337 | 338 | #### drop、delete、truncate 339 | 340 | #### 视图 341 | 342 | - 视图的作用,以及何时能更新视图。 343 | 344 | #### 存储过程 345 | 346 | #### 触发器 347 | 348 | ### 系统原理 349 | 350 | #### ACID 351 | 352 | #### 隔离级别 353 | 354 | 四大隔离级别,以及不可重复读和幻影读的出现原因。 355 | 356 | #### 封锁 357 | 358 | 封锁的类型以及粒度,两段锁协议,隐式和显示锁定。 359 | 360 | #### 乐观锁与悲观锁 361 | 362 | #### MVCC  363 | 364 | #### 范式 365 | 366 | #### SQL 与 NoSQL 367 | 368 | ### MySQL 369 | 370 | #### B+ Tree 371 | 372 | #### 索引以及优化 373 | 374 | #### 查询优化 375 | 376 | #### InnoDB 与 MyISAM 377 | 378 | #### 水平切分与垂直切分 379 | 380 | #### 主从复制 381 | 382 | #### 日志 383 | 384 | ### Redis 385 | 386 | #### 字典和跳跃表 387 | 388 | #### 使用场景 389 | 390 | #### 与 Memchached 的比较 391 | 392 | #### RDB 和 AOF 持久化机制 393 | 394 | #### 数据淘汰机制 395 | 396 | #### 事件驱动模型 397 | 398 | #### 主从复制 399 | 400 | #### 集群与分布式 401 | 402 | #### 事务 403 | 404 | #### 线程安全问题 405 | 406 | ## 面向对象 407 | 408 | 409 | ### 资料 410 | 411 | - 《Head First 设计模式》 412 | 413 | 414 | ### 思想 415 | 416 | #### 三大特性 417 | 418 | #### 设计原则 419 | 420 | ### 设计模式 421 | 422 | #### 单例模式 423 | 424 | 手写单例模式,特别是双重检验锁以及静态内部类。 425 | 426 | #### 工厂模式 427 | 428 | 手写工厂模式。 429 | 430 | 431 | #### MVC 432 | 433 | 理解 MVC,结合 SpringMVC 回答。 434 | 435 | #### 代理模式 436 | 437 | 结合 Spring 中的 AOP 回答。 438 | 439 | #### JDK 中常用的设计模式 440 | 441 | 例如装饰者模式、适配器模式、迭代器模式等。 442 | 443 | ## 系统设计 444 | 445 | 446 | #### 资料 447 | 448 | - 《大型网站技术架构》 449 | - 《从 Paxos 到 Zookeeper》 450 | - 《微服务设计》 451 | 452 | 453 | ### 基础 454 | 455 | - [系统设计基础](https://cyc2018.github.io/CS-Notes/#/notes/系统设计基础) 456 | 457 | #### 性能 458 | 459 | #### 伸缩性 460 | 461 | #### 扩展性 462 | 463 | #### 可用性 464 | 465 | #### 安全性 466 | 467 | ### 分布式 468 | 469 | - [分布式](https://cyc2018.github.io/CS-Notes/#/notes/分布式) 470 | 471 | #### 分布式事务 472 | 473 | #### CAP 474 | 475 | #### BASE 476 | 477 | #### Paxos 478 | 479 | #### Raft 480 | 481 | #### 分布式锁 482 | 483 | #### 分布式 ID 484 | 485 | ### 集群 486 | 487 | - [集群](https://cyc2018.github.io/CS-Notes/#/notes/集群) 488 | 489 | #### 负载均衡 490 | 491 | #### Session 管理 492 | 493 | ### 缓存 494 | 495 | - [缓存](https://cyc2018.github.io/CS-Notes/#/notes/缓存) 496 | 497 | #### 缓存特征 498 | 499 | #### LRU 500 | 501 | #### 缓存位置 502 | 503 | #### CDN 504 | 505 | #### 缓存问题 506 | 507 | #### 一致性哈希 508 | 509 | ### 攻击技术 510 | 511 | - [攻击技术](https://cyc2018.github.io/CS-Notes/#/notes/攻击技术) 512 | 513 | #### XSS 514 | 515 | #### CSRF 516 | 517 | #### SQL 注入 518 | 519 | #### DDoS 520 | 521 | ### 消息队列 522 | 523 | - [消息队列](https://cyc2018.github.io/CS-Notes/#/notes/消息队列) 524 | 525 | #### 消息模型 526 | 527 | #### 使用场景 528 | 529 | #### 可靠性 530 | 531 | ### 高并发系统 532 | 533 | #### 秒杀系统 534 | 535 | #### 限流算法 536 | 537 | #### 服务熔断与服务降级 538 | 539 | ### 服务拆分 540 | 541 | #### 幂等性 542 | 543 | #### 远程服务访问方法 544 | 545 | #### 微服务 546 | 547 | #### SOA 548 | 549 | ### 系统设计 550 | 551 | #### Web 页面请求过程 552 | 553 | #### 二维码登录 554 | 555 | #### TinyURL 556 | 557 | #### KV 存储系统 558 | 559 | #### 搜索引擎 560 | 561 | ## Java 562 | 563 | 564 | ### 资料 565 | 566 | - 《JAVA 核心技术》 567 | - 《Java 编程思想》 568 | - 《Effective java 中文版》 569 | - 《深入理解 Java 虚拟机》 570 | - 《Java 并发编程实战》 571 | - 《精通 Spring 4.x》 572 | - 《Spring 揭秘》 573 | 574 | 575 | ### 基础 576 | 577 | - [Java 基础](https://cyc2018.github.io/CS-Notes/#/notes/Java%20基础) 578 | 579 | ### 虚拟机 580 | 581 | - [Java 虚拟机](https://cyc2018.github.io/CS-Notes/#/notes/Java%20虚拟机) 582 | 583 | ### 并发 584 | 585 | - [Java 并发](https://cyc2018.github.io/CS-Notes/#/notes/Java%20并发) 586 | 587 | ### 容器 588 | 589 | - [Java 容器](https://cyc2018.github.io/CS-Notes/#/notes/Java%20容器) 590 | 591 | ### I/O 592 | 593 | - [Java IO](https://cyc2018.github.io/CS-Notes/#/notes/Java%20IO) 594 | 595 | ### Web 596 | 597 | - [69 道 Spring 面试题和答案](http://ifeve.com/spring-interview-questions-and-answers/) 598 | - [Spring 面试题](https://github.com/Homiss/Java-interview-questions/blob/master/%E6%A1%86%E6%9E%B6/Spring%20%E9%9D%A2%E8%AF%95%E9%A2%98.md) 599 | - [Spring 面试问答 Top 25](http://www.importnew.com/15851.html) 600 | - [Spring 总结以及在面试中的一些问题.](https://www.cnblogs.com/wang-meng/p/5701982.html) 601 | 602 | 603 | ## C++ 604 | 605 | ## 中间件 606 | 607 | ### RabbitMQ 608 | 609 | ### ZooKeeper 610 | 611 | ### Dubbo 612 | 613 | ### Nginx 614 | 615 | ## 其它知识 616 | 617 | ### 新技术 618 | 619 | ### 开源项目 620 | 621 | ## 项目 622 | 623 | ## 面试相关 624 | 625 | ### 简历 626 | 627 | ### 投递 628 | -------------------------------------------------------------------------------- /mixtalk/all/一文帮你理清面试知识点 - 小专栏.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/all/一文帮你理清面试知识点 - 小专栏.pdf -------------------------------------------------------------------------------- /mixtalk/go-application-question/README.md: -------------------------------------------------------------------------------- 1 | ### GO语言面试知识考点总汇 2 | > 答案参考1:https://github.com/googege/blog/tree/master/go/go/concurrency/README.md 3 | 4 | > 答案参考2 https://github.com/googege/blog/tree/master/go/tool/pprof/README.md 5 | - goroutine 基于线程池的P:M:G协程模型 6 | - channel 基于生产者消费者模型的无锁队列 7 | - net.conn 基于epoll的异步io同步阻塞模型 8 | - syscall 基于操作系统的原生syscall能力 9 | - gosched 基于阻塞的协程调度 10 | - gc 基于三色标记法的并发gc模型 11 | - io.reader/writer unix文件哲学升级版 12 | - net/http 基于goroutine的http服务器 13 | - 开箱即用error基于c风格的if(erron ! = 0)错误处理机制 14 | - panic 传统的exception异常机制可配合coredumprecover可用于恢复异常的堆栈, 15 | - 以进行排错map传统的hashmap 16 | - 并发安全的hash map slice 17 | - 基于内存复用和读优化设计的数据结构 18 | - defer函数返回前清理各种垃圾,防止内存泄露 19 | - go tool asm go专用汇编, 20 | - 可选性能优化手段cgo非并发安全的c调用能力, 21 | - 可选性能优化手段unsafe非并发安全的指针调用, 22 | - 可选性能优化手段reflect提供反射能力, 23 | - 以实现有限的动态性atomic基于cpu原子操作的包装, 24 | - 可实现cas context基于channel的goroutine流程控制能力 25 | - interface提供高级语言的抽象和多态能力闭包提供主流编程语言的闭包设计 26 | - 逃逸分析提供主流编程语言的逃逸优化能力指针提供并发安全的指针 27 | - 非并发安全的指针 28 | - pprof自带的性能分析工具用于调优和查错 29 | 30 | *** 31 | 32 | 后端工程师 面试重点算法和数据结构重点 33 | 34 | 算法与数据结构是面试考察的重中之重,也是大家日后学习时需要着重训练的部分。简单的总结一下,大约有这些内容: 35 | 36 | 37 | - 算法 - Algorithms 38 | 39 | 排序算法:快速排序、归并排序、计数排序 40 | 41 | 搜索算法:回溯、递归、剪枝技巧 42 | 43 | 图论:最短路、最小生成树、网络流建模 44 | 45 | 动态规划:背包问题、最长子序列、计数问题 46 | 47 | 基础技巧:分治、倍增、二分、贪心 48 | 49 | - 数据结构 - Data Structures 50 | 51 | 数组与链表:单 / 双向链表、跳舞链 52 | 53 | 栈与队列 54 | 55 | 树与图:最近公共祖先、并查集 56 | 57 | 哈希表 58 | 59 | 堆:大 / 小根堆、可并堆 60 | 61 | 字符串:字典树、后缀树 62 | 63 | -------------------------------------------------------------------------------- /mixtalk/go-application-question/面试知识大揭秘.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/go-application-question/面试知识大揭秘.tar.xz -------------------------------------------------------------------------------- /mixtalk/go-application-question/面试知识大汇总.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/go-application-question/面试知识大汇总.pdf -------------------------------------------------------------------------------- /mixtalk/howToFindYourSchool/README.md: -------------------------------------------------------------------------------- 1 | # 计算机和临床学科排名,以及如何选择考研的学校 2 | 3 | ## 计算机学科排名 4 | 1. 北大 5 | 2. 清华 6 | 3. 浙大 7 | 4. 国防科大 8 | 5. 北航 9 | 6. 北邮 10 | 7. 哈工大 11 | 8. 上交 12 | 9. 南京大学 13 | 10. 华科 14 | 11. 电子科大 15 | 12. 北京交通大学 16 | 13. 北京理工 17 | 14. 东北大学 18 | 15. 吉林大学 19 | 16. 同济大学 20 | 17. 中科大 21 | 18. 武大 22 | 19. 中南大学 23 | 20. 西安交大 24 | ## 临床学科排名 25 | 1. 上交 26 | 2. 中山 27 | 3. 复旦 28 | 4. 北京协和 29 | 5. 北大 30 | 6. 首都医科大 31 | 7. 浙大 32 | 8. 川大 33 | 9. 南京医科大 34 | 10. 华科 35 | 11. 中南 36 | 12. 第二军医 37 | 13. 山东大学 38 | 14. 第四军医 39 | 15. 南京大学 40 | 16. 天津医科大 41 | 17. 南方医科大 42 | 18. 中国医科大学 43 | 44 | 其中两者都有的是 45 | 46 | 1. 北大 47 | 2. 清华 48 | 3. 浙大 49 | 4. 中南大学 50 | 5. 华科 51 | 6. 上交 52 | -------------------------------------------------------------------------------- /mixtalk/howToFindYourSchool/各学校考研报录比2015-2019.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/howToFindYourSchool/各学校考研报录比2015-2019.7z -------------------------------------------------------------------------------- /mixtalk/howToJoinGoogle/README.md: -------------------------------------------------------------------------------- 1 | # 如何加入谷歌 2 | 3 | 谷歌要求的几种能力 4 | 5 | - 算法和数据结构的能力 6 | - 设计模式的能力 7 | - 系统设计,架构设计的模式(例如高并发架构,微服务架构,分布式架构等) 8 | - 数据库的能力 9 | - 网络协议的能力 10 | - 操作系统的知识 11 | - 代码审查,代码测试的能力 12 | - 阅读源码 13 | - 英语能力 14 | -------------------------------------------------------------------------------- /mixtalk/howToMakeMoreMoney/README.md: -------------------------------------------------------------------------------- 1 | # 如何去赚更多的钱 2 | > [更多1](./makeMoreMoney1.png) 3 | 4 | - 写公众号,以及个平台技术类科技类文章,以及拥有自己的技术类个人网站,首先微信公众号是有广告收入的,其次还可以接洽广告的投入,写软文等。 5 | 6 | - 拍技术类,科技类等视频,做一个YouTuber,bilibiliber youkuer 等 视频博主,当然做一个优秀的博主将视频上传到比如YouTube bilibili 微博等平台 7 | 就会获得一定的曝光率,在YouTube你将直接获取金钱,在起它平台你可以接洽广告,关键是以后创业,这些粉丝可以当做一个巨大的人口流量红利!只要产品过硬,想公司上道非常容易。 8 | 9 | - 知识付费领域,例如知识星球,极客时间等,可以享受收费的快乐。 10 | 11 | - 出版技术类的书籍,这个途径增加身份含金量的意味更大,因为出书如果出版量不是很大的话,收入其实不是特别多。不过如果说起来你的身份是某某书籍的作者, 12 | 提升自己的身份这个作用还是很大的。 13 | 14 | - 维护一个优秀的开源项目,首先可以靠项目的某些版权收费,例如项目的名字,项目的logo,别人出视频啊,出书啊要想你获取授权,支付费用。然后你还可以维护一个 15 | 官方网站,上面招募广告以及引入谷歌广告等,再有,作为项目的作者,你可以去各地讲座赚钱,你想想如果公司培训Linux,没有比请Linus更让人兴奋的吧,哈哈。 16 | 还有,作为官网的维护着以及创始人,你可以自己再开发一些优质资源,然后这些资源是付费的即可。你的开源项目可以给你带来流量,然后推动你的优质周边的变现力度。 17 | 18 | - 作为著名程序员,开设补习班,无论是线上或者线下,都将有巨大的市场 19 | 20 | - 移动互联网时代已经过去。现在是技术互联网的时代,例如大数据啊 云计算啊,机器学习啊,作为一个算法等基础牢靠的程序员,深入到某个领域,积累一定的人脉,然后在这个领域 21 | 进行创业是一个非常好的尝试,成功了,那么你的收入将是百倍 万倍甚至几十万倍的增长。 22 | 23 | - 写通用软件,开淘宝卖软件卖服务也是一种门道 24 | 25 | 26 | -------------------------------------------------------------------------------- /mixtalk/howToMakeMoreMoney/makeMoreMoney1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/howToMakeMoreMoney/makeMoreMoney1.png -------------------------------------------------------------------------------- /mixtalk/m/README.md: -------------------------------------------------------------------------------- 1 | ## 真实面试公司测试题集锦 2 | 3 | 按照公司排列 4 | 5 | ## :car: 公司的名字 6 | 7 | - [pplabs](./pplabs) 8 | - [unknow](./unkonw) 9 | -------------------------------------------------------------------------------- /mixtalk/m/pplabs/README.md: -------------------------------------------------------------------------------- 1 | ## pplabs 真实面试题 2 | 3 | 4 | 5 | ¶ 第一题: 6 | 下面显示了当前 PPIO 测试链上每个钱包地址所包含的余额数排行榜信息(数据为测试数据,仅供参考),如下所示: 7 | 8 | ```bash 9 | A total of 100000 accounts found 上一页 < 1/200 >下一页 10 | 11 | Rank Address Balance TxCount 12 | 1 ppio1SDKRLjDALmN7kV874JLhZAv4Q9TKVhrhg 30000 PPCoin 2000 13 | 2 ppio1ZoKAKZftwkdAVXSuPnz2TLJp14pSfhvMj 29990 PPCoin 1999 14 | 3 ppio1Yd4y3cYYZZ3pZqxnmn6xydrE4VmvWiX3d 29980 PPCoin 1998 15 | 16 | ... 17 | ``` 18 | 19 | 如果上面所示的排行榜数据都是放在 redis 数据库中维护的,为了实现以上功能,需要用到 redis 的哪些数据结构及相应的方法? 20 | 21 | 提示有以下几个功能点: 22 | 23 | 获取当前排行榜中的总地址(Address)数。 24 | 分页获取当前排行榜数据(根据余额数倒序排序)。包含 Rank(名次)、Address(钱包地址)、Balance(余额)、 TxCount(参与事务的总数)。 25 | 请给出详细的设计文档。 26 | 27 | 文档内容示例: 需要使用 String 数据结构来存储各个钱包地址的余额信息,键名为:PPIO:Wallet:ppio1SDKRLjDALmN7kV874JLhZAv4Q9TKVhrhg,键值为该账户的余额。 通过 GET PPIO:Wallet:ppio1SDKRLjDALmN7kV874JLhZAv4Q9TKVhrhg 来获取账户 ppio1SDKRLjDALmN7kV874JLhZAv4Q9TKVhrhg 的余额信息。 28 | 29 | ¶ 第二题: 30 | 下面给出某个文件(https://resource.testnet.pp.io/demo/release/macos/latest/ppio-demo.dmg)在下载过程中所涉及的 HTTP 请求包头及响应包头。 31 | 32 | 请求包头: 33 | ```bash 34 | :authority: resource.testnet.pp.io 35 | :method: GET 36 | :path: /demo/release/macos/latest/ppio-demo.dmg 37 | :scheme: https 38 | accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 39 | accept-encoding: gzip, deflate, br 40 | accept-language: zh-CN,zh;q=0.9,en;q=0.8 41 | cookie: ppio_uid=testuid; ppio_token=testtoken 42 | if-range: "2c1210c6567c9278985062f9dac53e57-10" 43 | range: bytes=15332307-15332307 44 | upgrade-insecure-requests: 1 45 | user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36 46 | 响应包头: 47 | 48 | accept-ranges: bytes 49 | content-length: 1 50 | content-range: bytes 15332307-15332307/78696231 51 | content-type: application/x-apple-diskimage 52 | date: Mon, 08 Apr 2019 16:14:42 GMT 53 | etag: "2c1210c6567c9278985062f9dac53e57-10" 54 | last-modified: Wed, 27 Feb 2019 11:53:53 GMT 55 | server: AmazonS3 56 | status: 206 57 | via: 1.1 3245d45aedf7a8621aabe6b30d2f5a48.cloudfront.net (CloudFront) 58 | x-amz-cf-id: EbYLgTsiNOC2U1GOqYMozH0eGMwkj94dNuD8asrjiZrE2wzOIFwd4w== 59 | x-cache: Miss from cloudfront 60 | ``` 61 | 请问:如果该文件的 HTTP 下载服务器对每个请求的下载限速为 10 KB/s,有什么办法让下载速度达到 100 KB/s?(请给出伪码以及必要的说明)。 62 | 63 | ¶ 第三题: 64 | 请实现一个简单的 Linux Shell 脚本,用于监控机器上的某个进程,如果进程退出,则需要重新拉起该进程,并输出新的进程 ID。 65 | 66 | 进程启动命令: 67 | ```bash 68 | /usr/local/bin/ppio-demo start 69 | ``` 70 | ¶ 第四题: 71 | 72 | 现在有一个需求,需要你去爬取微博用户的详细数据,其中包括用户的 nickname(昵称,具有唯一性)、follow_num(关注数)、follower_num(粉丝数)、weibo_num(微博数),以及每个用户发布的所有微博信息,其中包括微博的 content(内容,只需考虑文本内容)、post_time(发布时间)、repost_num(转发数)、comment_num(评论数)、like_num(点赞数)。爬取的数据需要通过 MySQL 数据库进行存储。 73 | 74 | 请你设计出用于存储以上数据所需要的建立的 MySQL 数据库表结构及表之间的关联关系。(用 SQL 语句表示) 75 | 在已爬取的数据中,如果要统计用户(昵称:PPlabs2019)历史微博的总点赞数,请你写出对应的 SQL 查询语句。 76 | 在已爬取的数据中,需要按用户历史微博的总点赞数进行倒序排序,选出前 50 名用户,并显示其昵称、关注数、粉丝数。请你写出对应的 SQL 查询语句。 77 | 当数据量较大时,请合理地建立索引来优化你在第 2、3 个问题中给出的 SQL 语句查询效率。 78 | 提示: 这个属于开放性试题,没有严格的答案。下面给出几个注意点。 79 | 80 | 命名规范。 81 | 表的各字段的数据类型合理。 82 | SQL 语句没有明显的语法错误。 83 | bs笔试题目.html 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /mixtalk/m/unknow/1.md: -------------------------------------------------------------------------------- 1 | ## ip 访问问题 2 | 3 | 场景:在一个高并发的web服务器中,要限制IP的频繁访问。现模拟100个IP同时并发访问服务器,每个IP要重复访问1000次。每个IP三分钟之内只能访问一次。修改以下代码完成该过程,要求能成功输出 success:100 4 | 5 | 方法- : 6 | 7 | ```go 8 | 9 | package main 10 | 11 | import ( 12 | "fmt" 13 | "sync" 14 | "time" 15 | ) 16 | 17 | type Ban struct { 18 | visitIPs map[string]time.Time // 访问的ip记录池 19 | } 20 | 21 | func NewBan() *Ban { 22 | return &Ban{visitIPs: make(map[string]time.Time)} 23 | } 24 | func (o *Ban) visit(ip string) bool { // visit 是为了判断 这个ip是否有权限能访问我的服务器。 25 | now := time.Now() 26 | if lastTime, ok := o.visitIPs[ip]; ok {//非首次访问 27 | if now.Sub(lastTime) >=time.Minute *3 { // 判断这个map中是否存在ip也就是说判断是否这个ip访问过,如果没有那么就是新的ip直接返回true 28 | // 如果是老的ip,那么判断它自带的那个结果,跟这次的now的时间间隔是否大于等于3分钟,没有的话,那么对不起你不能再次访问我的服务器,如果有的话, 29 | //ok,你经过了我的考研你可以访问我的服务器了。 30 | return true 31 | }else { 32 | return false 33 | } 34 | }else { // 首次访问 35 | o.visitIPs[ip] = now 36 | return true 37 | } 38 | 39 | } 40 | func main() { 41 | success := 0 // 成功访问的次数。 42 | ban := NewBan()// new a ban => ip writer. 43 | lock := new(sync.Mutex) // 锁 44 | wait := new(sync.WaitGroup)// waitgroup 45 | for i := 0; i < 10000; i++ { // 访问1000次 46 | for j := 0; j < 100; j++ { // 100个ip 47 | wait.Add(1) 48 | go func(j int) { 49 | lock.Lock() 50 | defer lock.Unlock() 51 | ip := fmt.Sprintf("192.168.1.%d", j) 52 | if ban.visit(ip) { 53 | success++ 54 | } 55 | wait.Done() 56 | }(j) 57 | } 58 | 59 | } 60 | wait.Wait() 61 | fmt.Println("success:", success) 62 | } 63 | 64 | 65 | 66 | ``` 67 | -------------------------------------------------------------------------------- /mixtalk/m/unknow/README.md: -------------------------------------------------------------------------------- 1 | ## 找不到具体出处的面试题 2 | 3 | - [ip访问问题](./1.md) 4 | -------------------------------------------------------------------------------- /mixtalk/macSoftwares.md: -------------------------------------------------------------------------------- 1 | # mac 必备软件集锦 2 | 3 | - 聊天工具 4 | - mac qq 5 | - 微信 6 | - 压缩工具 7 | - keka 8 | - 万能视频播放器 9 | - INA 10 | - GIF制作 11 | - kap 12 | - 删除软件 13 | - AppCleaner 14 | - 软件开发软件 15 | - postman 16 | - Mongodb Compass 17 | - docker 18 | - k8s 19 | - golang 20 | - atom 21 | - Virtul Box 22 | - android studio 23 | - ssr 24 | - bestTrace 25 | - 万能视频下载软件 26 | - Aria2GUI 27 | - 媒体软件 28 | - 爱奇艺 29 | - 网易云 30 | - 办公软件 31 | - wps office 32 | - 邮箱 33 | - spark 34 | - 抢票软件 35 | - 万人抢票联盟 36 | - android模拟器 37 | - 网易mumu 38 | 39 | -------------------------------------------------------------------------------- /mixtalk/net/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/net/4.png -------------------------------------------------------------------------------- /mixtalk/net/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/net/5.png -------------------------------------------------------------------------------- /mixtalk/net/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/net/7.gif -------------------------------------------------------------------------------- /mixtalk/net/GETVsPOST/README.md: -------------------------------------------------------------------------------- 1 | GET和POST两种基本请求方法的区别 2 | 3 | GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。 4 | 5 | 6 | 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。 7 | 8 | 9 | 10 | 你可能自己写过无数个GET和POST请求,或者已经看过很多权威网站总结出的他们的区别,你非常清楚知道什么时候该用什么。 11 | 12 | 13 | 14 | 当你在面试中被问到这个问题,你的内心充满了自信和喜悦。 15 | 16 | 17 | 18 | 你轻轻松松的给出了一个“标准答案”: 19 | 20 | 21 | GET在浏览器回退时是无害的,而POST会再次提交请求。 22 | 23 | 24 | 25 | GET产生的URL地址可以被Bookmark,而POST不可以。 26 | 27 | 28 | 29 | GET请求会被浏览器主动cache,而POST不会,除非手动设置。 30 | 31 | 32 | 33 | GET请求只能进行url编码,而POST支持多种编码方式。 34 | 35 | 36 | 37 | GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 38 | 39 | 40 | 41 | GET请求在URL中传送的参数是有长度限制的,而POST么有。 42 | 43 | 44 | 45 | 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 46 | 47 | 48 | 49 | GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。 50 | 51 | 52 | 53 | GET参数通过URL传递,POST放在Request body中。 54 | 55 | (本标准答案参考自w3schools) 56 | 57 | 58 | 59 | “很遗憾,这不是我们要的回答!” 60 | 61 | 62 | 63 | 请告诉我真相。。。 64 | 65 | 66 | 67 | 如果我告诉你GET和POST本质上没有区别你信吗? 68 | 69 | 70 | 让我们扒下GET和POST的外衣,坦诚相见吧! 71 | 72 | 73 | 74 | 75 | GET和POST是什么?HTTP协议中的两种发送请求的方法。 76 | 77 | 78 | 79 | HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。 80 | 81 | 82 | 83 | HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。 84 | 85 | 86 | 87 | 那么,“标准答案”里的那些区别是怎么回事? 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。 96 | 97 | 98 | 99 | 但是,我们只看到HTTP对GET和POST参数的传送渠道(url还是requrest body)提出了要求。“标准答案”里关于参数大小的限制又是从哪来的呢? 100 | 101 | 102 | 103 | 104 | 105 | 106 | 在我大万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。 107 | 108 | 109 | 110 | 好了,现在你知道,GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。 111 | 112 | 113 | 114 | 你以为本文就这么结束了? 115 | 116 | 117 | 118 | 119 | 120 | 我们的大BOSS还等着出场呢。。。 121 | 122 | 123 | 124 | 这位BOSS有多神秘?当你试图在网上找“GET和POST的区别”的时候,那些你会看到的搜索结果里,从没有提到他。他究竟是什么呢。。。 125 | 126 | 127 | 128 | GET和POST还有一个重大区别,简单的说: 129 | 130 | GET产生一个TCP数据包;POST产生两个TCP数据包。 131 | 132 | 133 | 134 | 长的说: 135 | 136 | 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); 137 | 138 | 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。 139 | 140 | 141 | 142 | 也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。 143 | 144 | 145 | 146 | 因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么? 147 | 148 | 1. GET与POST都有自己的语义,不能随便混用。 149 | 150 | 2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。 151 | 152 | 3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。 153 | 154 | 155 | 156 | 现在,当面试官再问你“GET与POST的区别”的时候,你的内心是不是这样的? 157 | 158 | 159 | 160 | 结束!!! 161 | -------------------------------------------------------------------------------- /mixtalk/net/README.md: -------------------------------------------------------------------------------- 1 | ## 网络协议知多少 2 | 3 | 总体来说可以分为这么几层 4 | 5 | 业界有三种划分方法,分别为7层,5层和四层 6 | 我们来看几个图 7 | 8 | ### 7层: 9 | 7层是指OSI七层协议模型,主要是:应用层(Application)、表示层(Presentation)、会话层(Session)、传输层(Transport)、网络层(Network)、数据链路层(Data Link)、物理层(Physical) 10 | ![七层](./7.gif) 11 | ### 5层 12 | 5层只是OSI和TCP/IP的综合,是业界产生出来的非官方协议模型,但是很多具体的应用。实际应用还是TCP/IP的四层结构。为了方便可以把下两层称为网络接口层。五层体系结构包括:应用层、运输层、网络层、数据链路层和物理层。 13 | ![5](./5.png) 14 | ### 4层 15 | 4层是指TCP/IP四层模型,主要包括:应用层、运输层、网际层和网络接口层。 16 | ![4](./4.png) 17 | ### 传输过程 18 | ![c](./c.jpeg) 19 | ### 什么是http协议的三次握手 20 | 其实是tcp协议中的三次握手,具体可以看这个图 21 | ![tcp3](./tcpd.jpg) 22 | 参考资料(感谢这些作者们): 23 | https://blog.csdn.net/cc1949/article/details/79063439 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /mixtalk/net/c.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/net/c.jpeg -------------------------------------------------------------------------------- /mixtalk/net/tcpd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basicExploration/blog/b0c3d0432e6c0d4cfd825c7fc1dd45b2affb88e7/mixtalk/net/tcpd.jpg -------------------------------------------------------------------------------- /mixtalk/shipu.md: -------------------------------------------------------------------------------- 1 | # 食谱 2 | 3 | 蔬菜: 西红柿 黄瓜 芹菜 柠檬(少量)胡萝卜 4 | 5 | 6 | - 早上: 蔬菜 200g 鸡蛋两个,豆腐100g 7 | 8 | - 中午 蔬菜 300g 鸡蛋一个,豆腐100g 鸡胸肉100g 洋葱适量 大蒜适量 9 | 10 | - 晚上 蔬菜 300g 鸡蛋一个,豆腐100g 鸡胸肉100g 洋葱适量 大蒜适量 11 | 12 | 禁忌:茶 咖啡 奶茶 饮料 烟 酒 13 | 14 | 热量计算: 15 | 16 | |名称|热量(大卡/100g)| 17 | |:---:|:---:| 18 | |豆腐| 80| 19 | |鸡胸肉| 105| 20 | |鸡蛋| 154| 21 | |番茄| 18| 22 | |黄瓜 |15| 23 | |芹菜| 14| 24 | |胡萝卜 |41| 25 | |洋葱| 39| 26 | |大蒜| 126| 27 | |柠檬| 35| 28 | |馒头|219| 29 | 30 | 对于需要的热量每个人,每种状态下都是不一样的。依照性别、年龄、身高、体重计算一日所需的卡路里,计算方式如下: 31 | 32 | 男性:`[665+1.38x体重(kg)+5x高度(cm)-6.8x年龄]x活动量` 33 | 34 | 女性:`[665+9.6x体重(kg)+l.9x高度(cm)-4.7x年龄]x活动量` 35 | 36 | 活动量:一般人的活动量由`.1-1.3`不等,平日只坐在办公室工作的女性,活动量约`1.1`,运动量高的人约为`1.3`。 37 | 38 | 对我自己的计算: 39 | 40 | 这里的体重我使用的是理想体重 41 | 42 | `[665+1.38x 136/2 + 5 x 178 - 6.8 x 24]x1.1 = 1634 大卡` 43 | 44 | -------------------------------------------------------------------------------- /mixtalk/ssr.md: -------------------------------------------------------------------------------- 1 | # 如何科学上网 2 | 3 | - 选择一家服务器厂商 例如谷歌云 或者[cloudcone](https://app.cloudcone.com/?ref=2525) 4 | 5 | - 购买服务器(vps,或者叫做虚拟机都有) 6 | 7 | - 服务器请安装Linux,版本不限 8 | 9 | - 安装 git 10 | 11 | - 安装ssr-server:git clone github.com/shadowsocks/shadowsocks-go/ 12 | 13 | - 在这个路径下 找到cmd/shadowsocks-server 即可 14 | 15 | - 在同一个路径下新建一个config.json的文件文件内容[为](https://github.com/shadowsocks/shadowsocks-go/blob/master/config.json) 16 | 17 | - 使用root去运行shadowsockets-server即可 `sudo nohup ./shadowsocks-server &` 18 | 19 | - 本地下载好一个ssr的客户端配置信息后即可科学上网 20 | -------------------------------------------------------------------------------- /mixtalk/whyWeChat.md: -------------------------------------------------------------------------------- 1 | # 为什么要开这个微信公众号? 2 | 3 | - 我的背景 4 | 5 | - 我的计划 6 | 7 | - 提供给大家的东西 8 | -------------------------------------------------------------------------------- /system/linux/kid-kid-kid/README.md: -------------------------------------------------------------------------------- 1 | ## 孤儿进程 僵尸进程 守护进程 2 | 3 | - 孤儿进程 : 子进程尚未结束,父进程退出,子进程将托付给init进程 4 | 5 | - 僵尸进程 子进程结束,发出结束信号给父进程,但是父进程没有接收到,子进程就变成了僵尸进程。并且会消耗一定的资源 6 | 7 | - 守护进程,守护进程就是在后台运行,不跟任何终端关联的进程。 8 | -------------------------------------------------------------------------------- /system/linux/kill/README.md: -------------------------------------------------------------------------------- 1 | ## 如何发送信号给进程? 2 | 3 | Linux/Unix中向一个进程发送信号用kill命令,不要以为kill命令只是用来杀死进程的, 4 | 5 | 它可以发送各种信号给进程,杀死进程只是用到了其中的一个SIGKILL信号,kill命令的格式其实是这样的: 6 | 7 | 8 | ```bash 9 | kill 信号参数 进程PID 10 | ``` 11 | 12 | > 例如 :kill -1 9987 13 | 14 | 15 | 其中常见的信号参数(英文横杠加阿拉伯数字)有如下几个,更多的信号信息参考可以用man命令查看手册页(man 7 signal): 16 | 17 | |参数|代表的意义| 18 | |---|---| 19 | |-1|这个参数代表SIGHUP信号,作用类似重新启动进程;| 20 | |-2|这个参数代表SIGINT信号,作用相当于在命令行输入Ctrl+C组合键中断进程的运行| 21 | |-9|这个参数代表SIGKILL信号,代表强制中断进程| 22 | |-15|这个参数代表SIGTERM信号,表示正常的终止进程| 23 | |-17|这个参数代表SIGSTOP信号,相当于在终端输入Ctrl+Z组合键来暂停进程的运行| 24 | --------------------------------------------------------------------------------