赵东炜:Erlang助你迎接多核挑战

本文探讨了多核时代软件面临的并发挑战,介绍了Erlang语言如何通过独特的编程模型解决这些问题,包括无锁并发、容错性和分布式计算。
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="ProgId" content="Word.Document"> <meta name="Generator" content="Microsoft Word 12"> <meta name="Originator" content="Microsoft Word 12"> <link rel="File-List" href="file:///C:%5CUsers%5Cerway%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> <link rel="Preview" href="file:///C:%5CUsers%5Cerway%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_preview.wmf"> <link rel="Edit-Time-Data" href="file:///C:%5CUsers%5Cerway%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso"> <!--[if !mso]> <style> v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} w/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Version>12.00</o:Version> </o:DocumentProperties> </xml><![endif]--><link rel="themeData" href="file:///C:%5CUsers%5Cerway%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> <link rel="colorSchemeMapping" href="file:///C:%5CUsers%5Cerway%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml"> <!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>EN-US</w:LidThemeOther> <w:LidThemeAsian>ZH-CN</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:DontVertAlignCellWithSp/> <w:DontBreakConstrainedForcedTables/> <w:DontVertAlignInTxbx/> <w:Word11KerningPairs/> <w:CachedColBalance/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="--><smallfrac m:val="off"><dispdef><lmargin m:val="0"><rmargin m:val="0"><defjc m:val="centerGroup"><wrapindent m:val="1440"><intlim m:val="subSup"><narylim m:val="undOvr"></narylim></intlim></wrapindent><!--[endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true" DefSemiHidden="true" DefQFormat="false" DefPriority="99" LatentStyleCount="267"> <w:LsdException Locked="false" Priority="0" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Normal"/> <w:LsdException Locked="false" Priority="9" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="heading 1"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/> <w:LsdException Locked="false" Priority="39" Name="toc 1"/> <w:LsdException Locked="false" Priority="39" Name="toc 2"/> <w:LsdException Locked="false" Priority="39" Name="toc 3"/> <w:LsdException Locked="false" Priority="39" Name="toc 4"/> <w:LsdException Locked="false" Priority="39" Name="toc 5"/> <w:LsdException Locked="false" Priority="39" Name="toc 6"/> <w:LsdException Locked="false" Priority="39" Name="toc 7"/> <w:LsdException Locked="false" Priority="39" Name="toc 8"/> <w:LsdException Locked="false" Priority="39" Name="toc 9"/> <w:LsdException Locked="false" Priority="0" Name="header"/> <w:LsdException Locked="false" Priority="0" Name="footer"/> <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/> <w:LsdException Locked="false" Priority="0" Name="page number"/> <w:LsdException Locked="false" Priority="10" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Title"/> <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/> <w:LsdException Locked="false" Priority="11" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/> <w:LsdException Locked="false" Priority="0" Name="Hyperlink"/> <w:LsdException Locked="false" Priority="22" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Strong"/> <w:LsdException Locked="false" Priority="20" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/> <w:LsdException Locked="false" Priority="59" SemiHidden="false" UnhideWhenUsed="false" Name="Table Grid"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/> <w:LsdException Locked="false" Priority="1" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 1"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 1"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 1"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/> <w:LsdException Locked="false" Priority="34" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/> <w:LsdException Locked="false" Priority="29" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Quote"/> <w:LsdException Locked="false" Priority="30" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 1"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 1"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 2"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 2"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 2"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 2"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 2"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 3"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 3"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 3"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 3"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 3"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 4"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 4"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 4"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 4"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 4"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 5"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 5"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 5"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 5"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 5"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 6"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 6"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 6"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 6"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 6"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/> <w:LsdException Locked="false" Priority="19" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/> <w:LsdException Locked="false" Priority="21" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/> <w:LsdException Locked="false" Priority="31" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/> <w:LsdException Locked="false" Priority="32" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/> <w:LsdException Locked="false" Priority="33" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Book Title"/> <w:LsdException Locked="false" Priority="37" Name="Bibliography"/> <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/> </w:LatentStyles> </xml><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 680460288 22 0 262145 0;} @font-face {font-family:黑体; panose-1:2 1 6 9 6 1 1 1 1 1; mso-font-alt:SimHei; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-2147482945 953122042 22 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face {font-family:楷体; panose-1:2 1 6 9 6 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-2147482945 953122042 22 0 262145 0;} @font-face {font-family:楷体_GB2312; mso-font-alt:"Arial Unicode MS"; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:0 135135232 16 0 262144 0;} @font-face {font-family:"Lucida Sans Typewriter"; mso-font-alt:Consolas; mso-font-charset:0; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 680460288 22 0 262145 0;} @font-face {font-family:"/@黑体"; panose-1:2 1 6 9 6 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-2147482945 953122042 22 0 262145 0;} @font-face {font-family:"/@楷体"; panose-1:2 1 6 9 6 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-2147482945 953122042 22 0 262145 0;} @font-face {font-family:"/@楷体_GB2312"; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:0 135135232 16 0 262144 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; text-indent:10.0pt; mso-char-indent-count:2.0; mso-pagination:none; mso-layout-grid-align:none; punctuation-trim:leading; text-autospace:none; font-size:10.0pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman","serif"; mso-fareast-font-family:宋体; mso-font-kerning:10.0pt;} p.MsoHeader, li.MsoHeader, div.MsoHeader {mso-style-noshow:yes; mso-style-unhide:no; mso-style-link:"页眉 Char"; margin:0cm; margin-bottom:.0001pt; text-align:center; text-indent:10.0pt; mso-char-indent-count:2.0; mso-pagination:none; tab-stops:center 207.65pt right 415.3pt; layout-grid-mode:char; mso-layout-grid-align:none; punctuation-trim:leading; text-autospace:none; border:none; mso-border-bottom-alt:solid windowtext .75pt; padding:0cm; mso-padding-alt:0cm 0cm 1.0pt 0cm; font-size:9.0pt; font-family:"Times New Roman","serif"; mso-fareast-font-family:宋体; mso-font-kerning:10.0pt;} p.MsoFooter, li.MsoFooter, div.MsoFooter {mso-style-noshow:yes; mso-style-unhide:no; mso-style-link:"页脚 Char"; margin:0cm; margin-bottom:.0001pt; text-indent:10.0pt; mso-char-indent-count:2.0; mso-pagination:none; tab-stops:center 207.65pt right 415.3pt; layout-grid-mode:char; mso-layout-grid-align:none; punctuation-trim:leading; text-autospace:none; font-size:9.0pt; font-family:"Times New Roman","serif"; mso-fareast-font-family:宋体; mso-font-kerning:10.0pt;} a:link, span.MsoHyperlink {mso-style-noshow:yes; mso-style-unhide:no; color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; mso-themecolor:followedhyperlink; text-decoration:underline; text-underline:single;} span.Char {mso-style-name:"页眉 Char"; mso-style-noshow:yes; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:页眉; mso-ansi-font-size:9.0pt; mso-bidi-font-size:9.0pt; mso-font-kerning:10.0pt;} span.Char0 {mso-style-name:"页脚 Char"; mso-style-noshow:yes; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:页脚; mso-ansi-font-size:9.0pt; mso-bidi-font-size:9.0pt; mso-font-kerning:10.0pt;} span.5 {mso-style-name:5号代码; mso-style-unhide:no; mso-ansi-font-size:9.0pt; font-family:"Lucida Sans Typewriter"; mso-ascii-font-family:"Lucida Sans Typewriter"; mso-fareast-font-family:宋体; mso-hansi-font-family:"Lucida Sans Typewriter"; letter-spacing:0pt;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt; mso-ascii-font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-hansi-font-family:"Times New Roman"; mso-font-kerning:0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:515.95pt 728.6pt; margin:76.55pt 46.8pt 110.55pt 52.45pt; mso-header-margin:48.2pt; mso-footer-margin:65.2pt; mso-page-numbers:1; mso-paper-source:0; layout-grid:15.0pt;} div.Section1 {page:Section1; mso-footnote-numbering-style:decimal-enclosed-circle-chinese; mso-footnote-numbering-restart:each-page;} --> </style> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} </style> <![endif]--><p class="MsoNormal" style="text-align: center; text-indent: 32pt;" align="center"><span style="font-size: 16pt; font-family: 黑体;">赵东炜:</span><span style="font-size: 16pt;" lang="EN-US">Erlang</span><span style="font-size: 16pt; font-family: 黑体;">助你迎接多核时代的挑战</span><span style="font-size: 16pt;" lang="EN-US"><p></p></span></p> <p class="MsoNormal" style="margin-bottom: 15pt; text-align: right; text-indent: 20pt;" align="right"><span style="font-family: 楷体; color: red;">——写在</span><span style="color: red;" lang="EN-US"><a href="http://www.china-pub.com/301677"><span style="font-family: 楷体; color: red;" lang="EN-US"><span lang="EN-US">《</span></span><span style="color: red;">Erlang</span><span style="font-family: 楷体; color: red;" lang="EN-US"><span lang="EN-US">程序设计》</span></span></a></span><span style="font-family: 楷体; color: red;">出版之际</span><span style="color: red;" lang="EN-US"><p></p></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">另辟蹊径——从容面对容错、分布、并发、多核的挑战。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">作为一名程序员,随着工作经验的增长,如果足够幸运的话,终有一日,我们都将会直面大型系统的挑战。最初的手忙脚乱总是难免的,经历过最初的迷茫之后,你会惊讶地发现这是一个完全不同的“生态系统”。要在这样的环境中生存,我们的代码需要具备一些之前我们相当陌生或者闻所未闻的“生存技能”。容错、分布、负载均衡,这些词会频繁出现在搜索列表之中。经历过几轮各种方案的轮番上阵之后,我们会开始反思这一系列问题的来龙去脉,重新审视整个系统架构,寻找瓶颈所在。你可能会和我一样,最终将目光停留在那些之前被认为是无懈可击的优美代码上。开始琢磨:究竟是什么让它们在新的环境中“水土不服”,妨碍其更加有效地利用越来越膨胀的计算资源?</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">其实,早在多年以前硬件领域上的革命就已经开始,现在这个浪潮终于从高端应用波及常规的计算领域——多核芯片已经量产,单核芯片正在下线——这场革命正在我们的桌面上演。时代已经改变,程序员们再也不能继续稳坐家中装作什么事情也没发生,问题已经自己找上门来了。由单核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">频率提升带来软件自动加速的时代已经终止,性能的免费大餐已经结束,“生态环境的变化”迫使代码也必须“同步进化”。锁、同步、线程、信号量,这些之前只是在教科书中顺带提及的概念,越来越多地出现在我们日常的编程中,接踵而至的各类问题也开始折磨我们的神经。死锁、竞态,越来越多的锁带来了越来越复杂的问题。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;" align="center"><span lang="EN-US"><p> <img alt="" src="http://album.hi.youkuaiyun.com/app_uploads/turingbooks/20081023/150450828.p.jpg?d=20081024164938363" align=""></p></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;"><br></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">中国互动出版网首发:</span><span lang="EN-US"><a href="http://www.china-pub.com/301677">http://www.china-pub.com/301677</a></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;"><br></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">在多核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">的系统上,程序的性能不增反降,或者暴露出隐藏的错误?</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">在更强的硬件平台上,程序的并发处理能力却没有得到提升,瓶颈在哪里?</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">在分布式计算网络中,不得不对程序结构进行重大调整,才能适应新的运行环境?</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">在系统的关键应用上,不得不为软件故障或者代码升级,进行代价高昂的停机维护?</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">……</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">这一系列的问题,归根结底,都是因为主流技术体系在基本模型上存在着与并发计算相冲突的设计。换句话说,问题广泛地存在于我们所写的每一行代码中。在大厦初具规模时,却猛然发现每一块砖石都不牢固,这听来很有一些耸人听闻,但这种事并不罕见。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">比如:</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">x = x + n</span></span><span style="font-family: 宋体;">,即使是这个再常见不过的语句,也暗藏着烦恼的根源(你也可以把它称<span style="letter-spacing: -0.1pt;">做共享内存陷阱)。从机器指令的角度来思考,这个语句可能做了这么几件事(仅仅只是在概念上)。</span></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">(1) </span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">mov ax, [bp+x]</span></span><span style="font-family: 宋体;">;将寄存器</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">ax</span></span><span style="font-family: 宋体;">赋值为变量</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">x</span></span><span style="font-family: 宋体;">所指示的内存中的数据。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">(2) </span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">mov bx, n</span></span><span style="font-family: 宋体;">;将寄存器</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">bx</span></span><span style="font-family: 宋体;">赋值为</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">n</span></span><span class="5"><span style="font-size: 9pt; line-height: 150%; font-family: 宋体;">。</span></span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">(3) </span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">add ax, bx</span></span><span style="font-family: 宋体;">;将寄存器</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">ax</span></span><span style="font-family: 宋体;">加</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">n</span></span><span style="font-family: 宋体;">。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">(4) </span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">mov [bp+x],ax</span></span><span style="font-family: 宋体;">;将变量</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">x</span></span><span style="font-family: 宋体;">所指示的内存赋值为寄存器</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">ax</span></span><span style="font-family: 宋体;">中的数据。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">理论上,这是一个原子操作,在单核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">下情况也确实如此,但在多核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">下,就全然不同了。如果在每个核心上都有一个正在执行上述代码的进程(也就是试图对这个代码执行并行计算),问题就出现了。这里的</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">x</span></span><span style="font-family: 宋体;">是在两个进程之间共享的内存。很明显,在第</span><span lang="EN-US">(1)</span><span style="font-family: 宋体;">步到第</span><span lang="EN-US">(4)</span><span style="font-family: 宋体;">步之间,需要某种机制来保证“某一时刻”只有一个进程正在执行,否则就会破坏数据的完整性。这也就意味着,这样的代码无法充分利用多核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">的运算能力。也罢,咱们不加速就是了,但更糟糕的是,为了保证不出错,还需要引入锁的机制来避免数据被破坏。现有的主流技术体系全都建立在共享内存的模型之上,像</span><span class="5"><span style="font-size: 9pt; line-height: 150%;" lang="EN-US">x = x + n</span></span><span style="font-family: 宋体;">这样的代码几乎无处不在,但在多核环境下,每一处这样的代码(逻辑上的或者事实上的)都需要小心地处理锁。更糟糕的是,大量的锁彼此互相影响又会导致更为复杂的问题。这迫使程序员们在实现复杂的功能之余,还要拿出极度的耐心和娴熟的技巧来处理好这些沉闷和易错的锁,且不说是否可能,但这至少也是一个极为繁重的额外负担。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">为了并发而生。</span><span lang="EN-US">20</span><span style="font-family: 宋体;">多年前,它的创建者们就已经意识到了这一问题,转而选择了一条与主流语言完全不同的路(还有为数不多的另外几种语言也是如此)。它采用的是消息模型,进程之间并不共享任何数据,因而也就完全地避免了引入锁的必要。对于多核系统而言,完全无锁,也就意味着相同的代码在更多核心的</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">上会很容易具有更高的性能,而对于分布式系统,则意味着尽可能地避免了顺序瓶颈,可以把更多的机器无缝地加入到计算网络中来。甩掉了锁的桎梏,无疑是对程序员们的解放。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">不仅如此,</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">在编程模型上走得更远。它在语言级别提供了一系列的并发原语,通过这些原语,我们可以用进程+消息的模型来建模现实世界中多人协作的场景。一个进程表示一个人,人与人之间并不存在任何共享的内存,彼此之间的协作完全通过消息(说话、打手势、做表情,等等)交互来完成。这正是我们每一个人生而知之的并发模式!软件模拟现实世界协作和交互的场景——这也就是所谓的</span><span lang="EN-US">COP</span><span style="font-family: 宋体;">(面向并发编程)思想。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">在错误处理上,</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">也有与众不同的设计决策,这使得实现“容错系统”不再遥不可及。</span><span lang="EN-US">COP</span><span style="font-family: 宋体;">假设进程难免会出错——不像其他某些语言一样假设程序不会出错。它假设程序随时可能会出错,如果发生出错的情况,则不要尝试自行处理,而是直接退出,交给更高级的进程来对这种情况进行处理。通过引入“速错”和“进程监控”的概念,我们将错误分层,并由更高层的进程来妥善处理(比如,重启进程,或重启一系列进程)。有了这样的概念作为支撑,构造“容错系统”就会变得易如反掌。在这样的系统之下,软件错误不会导致整个系统的瘫痪,发现错误也无须停机就可直接更新代码,在配置了备份硬件之后,硬件的错误也不会影响服务的正常运行。这么做的结果相当惊人,使用</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">的电信关键产品,达到了传说中的</span><span lang="EN-US">99.9999999%</span><span style="font-family: 宋体;">可用性(即</span><span lang="EN-US">9</span><span style="font-family: 宋体;">个</span><span lang="EN-US">9</span><span style="font-family: 宋体;">的最高可用性标准)。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">采用虚拟机技术实现,用它编写的程序可以不经修改直接运行在从手机到大型机几乎所有的计算平台之上。这是一项有着</span><span lang="EN-US">20</span><span style="font-family: 宋体;">多年历史的成熟技术,有着相当多的成熟库(</span><span lang="EN-US">OTP</span><span style="font-family: 宋体;">)和开源软件,这些资产使得它有极高的实用价值。</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">本身也是开源软件,这扫清了对于语言本身生命力的疑惑。</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">还是一个充满活力的语言,在它的社区,常常能够见到</span><span lang="EN-US">Joe Armstrong</span><span style="font-family: 宋体;">等语言的创建者在回答问题,这一点尤其宝贵。在熟悉了</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">的思维方法和社区之后,很多人都发出了相见恨晚的感慨。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">虽说对于并发而言,</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">确实是非常好的选择,但这么多年以来,业界对于并发预料之中的增长却一直没有真正发生。此前,这类应用更多地局限在一些相对高端的领域,而</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">身上浓厚的电信背景,又使得第一眼看来它似乎只适用于电信行业(实际情况远非如此)。长期以来</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">的使用群体仅局限在一个狭小的技术圈子之内,它处于“非主流语言”的边缘位置已经很久了。这种情况直到最近才有所改观,最近两年,</span><span lang="EN-US">Google</span><span style="font-family: 宋体;">的成功使得其引为核心的大规模分布式应用模式广为人知,而多核</span><span lang="EN-US">CPU</span><span style="font-family: 宋体;">进入桌面也迫使“工业主流”开始认真对待并发计算。直到此时,解决这类问题最为成熟的</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">技术,才因为其难以忽视的优势而引起人们的广泛关注。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">从历史的眼光来看,在计算机语言的荣誉堂内,上演着一代又一代程序设计语言的繁荣和更替,潮来潮往让人难以捉摸。这与其说是技术,还不如说是时尚。对于</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">这种有些怪异的小众语言来说,是否真的会成为“下一个</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">”?实难预测,而且也不重要。但是有一点已经毫无疑问,那就是“下一代语言”至少也要像</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">一样,处理好与并发相关的一系列问题(或者做得更好)。也许将来的</span><span lang="EN-US">X++</span><span style="font-family: 宋体;">(或</span><span lang="EN-US">X#</span><span style="font-family: 宋体;">)语言在吸收了它的精髓之后,又会成为新的工业主流语言。但即便如此,先跟随本书作者开辟的小径信步浏览这些饶有趣味的问题肯定也会大有帮助。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">对于想要学习</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">的读者,虽说语言本身相当简单,但想要运用自如也有一些难度。比如,在适应</span><span lang="EN-US">COP</span><span style="font-family: 宋体;">之后会觉得非常自然,但对于有</span><span lang="EN-US">OOP</span><span style="font-family: 宋体;">背景的程序员而言,从固有的思维习惯转换到</span><span lang="EN-US">COP</span><span style="font-family: 宋体;">和</span><span lang="EN-US">FP</span><span style="font-family: 宋体;">上(主要是和自己的思维惯性较劲)需要有一个过程。此外</span><span lang="EN-US">OTP</span><span style="font-family: 宋体;">和其他</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">社区多年积累的财富(这些好比</span><span lang="EN-US">JDK</span><span style="font-family: 宋体;">、</span><span lang="EN-US">EJB</span><span style="font-family: 宋体;">之于</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">)也需要一些时间才能被充分地理解和吸收。但这些有价值的资料大多零星地散落于邮件列表和独立的文档之中,给学习造成了很多不必要的麻烦。现在好了,有了</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">创建者</span><span lang="EN-US">Joe Armstrong</span><span style="font-family: 宋体;">为我们撰写的“官方教程”,这些问题都已迎刃而解。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">一般而言,由语言的创建者亲自撰写的教程,常常都是杰作。在翻译的过程中,译者也常常会发出这种赞叹。在本书中,</span><span lang="EN-US">Joe Armstrong</span><span style="font-family: 宋体;">不仅全面地讲述了</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">语言本身,还详细交代了这些语言特性的来龙去脉。为什么要这么设计?除了掌握语言本身之外,能有幸窥见大师精微思辨的轨迹,也是难得的机缘。书中的例子,还会将你为之惊异的那些</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">特性一一解密。通常是从一个不起眼的小问题开始,从宏观分析到微观实现,层层深入细细道来。问题是什么?要如何建模?该怎么重构?各个版本之间的精微演化全然呈现,但这些微小的改进,最终演化出了那些让人惊喜的特性,整个过程可谓相当精彩。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">本书由</span><span lang="EN-US">Erlang</span><span style="font-family: 宋体;">中文社区(</span><span lang="EN-US">erlang-china.org</span><span style="font-family: 宋体;">)组织翻译。其中,第</span><span lang="EN-US">1</span><span style="font-family: 宋体;">章到第</span><span lang="EN-US">14</span><span style="font-family: 宋体;">章由金尹翻译,第</span><span lang="EN-US">15</span><span style="font-family: 宋体;">章到附录</span><span lang="EN-US">F</span><span style="font-family: 宋体;">由赵东炜翻译,全书由赵东炜统稿润色和审校。</span></p> <p class="MsoNormal" style="text-indent: 20pt; line-height: 150%;"><span style="font-family: 宋体;">由于时间仓促,加之译者水平有限,译文难免会有不足之处,欢迎读者批评指正。</span></p> <p class="MsoNormal" style="text-indent: 20pt;"><span lang="EN-US"><p></p></span></p> <p class="MsoNormal" style="text-align: center; text-indent: 336.6pt;" align="center"><span style="font-family: 楷体_GB2312;">赵东炜</span><span style="" lang="EN-US"><p></p></span></p> <p class="MsoNormal" style="text-align: right; text-indent: 20pt;" align="right"><span style="" lang="EN-US">2008</span><span style="font-family: 楷体_GB2312;">年</span><span style="" lang="EN-US">3</span><span style="font-family: 楷体_GB2312;">月于北京</span><span style="" lang="EN-US"><p></p></span></p></defjc></rmargin></lmargin></dispdef></smallfrac>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值