??xml version="1.0" encoding="utf-8" standalone="yes"?>激情综合色综合久久综合,久久人爽人人爽人人片AV,久久99精品国产http://www.shnenglu.com/sunicdavy/category/21050.html讨论?309800774 知乎x:http://zhihu.com/people/sunicdavy 开源项?https://github.com/davyxuzh-cnMon, 27 Dec 2021 16:46:30 GMTMon, 27 Dec 2021 16:46:30 GMT60但是GPU的性能依然q是DrawCall优化那一?/title><link>http://www.shnenglu.com/sunicdavy/archive/2021/12/27/217892.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Mon, 27 Dec 2021 11:01:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2021/12/27/217892.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/217892.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2021/12/27/217892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/217892.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/217892.html</trackback:ping><description><![CDATA[ Entitas的ECSpȝ 1. 本来在一个对象中d一个类字段的过E,ECS需要添加一个类代表ComponentQƈ且代码生成? q个字段一般用于描q对象的资源Q处理显C的GameObjectQ?表示对象的类型等? 2. 本来一个对象的业务逻辑处理q程直接用方法解决的Q?ECS需要新加一个SystemQ而操作对象需要用Filter或Group查询获得? 3. 一pd的操作, 需要拆分ؓ多个System和Component拆分处理。如果System序不对Q?会造成一些诡异的bug? 4. Component不仅仅是Model承蝲体, 也可以是参数的数据结构。参数Component通过Entity传递到System处理?例如Q?通过ECS创徏一个方块的q程Q用CreateTileComponentQ包含创建Tile的位|, 创徏Entityq添加CreateTileComponentQ?在CreateTileSystem中处理就创徏了TileQ处理完成时Q?需要将传入的Entity.Destroy掉? 6. Entity上修改Component的过E, 会触发事件。修改的q程需要用RelaceXXXQXXX表示lg名。组件可以频J修改, 不用担心d和删除组件过E的性能Q?Entitas底层处理性能只相当于指针赋值的性能? ECS像什么? 1. ECS中的SystemcM触发器系l(Event-Condition-ActionQ,其中QEvent对应Entitas的GetTrigger+CollectorQ表C发事件。Condition对应Filter表示在事件来源对象中扑ֈ需要的对象?Action对应ExecuteQ表C实际的操作? 2. ECS中的ComponentcM不用lua扩展的Redis或者不用存储过E的MySQLQ?UaU数据, 而不能对数据有Q何封装操作。没有lua和存储过E支持的db写v来还是比较费劲的Q但ECS是那么的纯? 3. ECS中的Entity很尴,因ؓComponent是按cdq箋存储的以保证性能?逻辑又需要Entityl合成逻辑需要的复合对象?两边都要照顾Q所以这U设计就让代码量巨增Q可L下降? ECS企图用一套框架灭掉设计模? 1. 单gQSingletonQ在Entitas用Unique标签标记ComponentQ?在Context中就是唯一的, 其实也就是Singleton? 2. ECSq掉了传l的工厂模式Q底层统一对对象(EntityQ和属性(ComponentQ统一理。需要按Component中的值找回EntityӞ 可以使用EntityIndex? 3. Entity携带不同的组件时Q整个创建和销毁过E被记录q恢复,其实是Command模式 ECS适合做UI框架Q类似MVVMQMVC,MVPQ么Q? ECS不是专用的UI框架Q但是可以对不同pȝ和数据间解耦。传l代码中数据修改后的CallbackQECS也可以用Listener做, 但Listener因ؓ能保存数据, 需要用Component保存?所以你需要面对的是,一个ButtonQ响应创Z个参数用的Component和SystemQ还要ؓ数据改变写一套ListenComponent和Listener处理的SystemQ酸爽吧Q? Minecraft适合ECS来做么? 可以Q性能应该能提升不,但是代码会更J琐Q特别像Javaq种啰嗦语言配上ECSq种啰嗦框架Q估计代码量ȝq是很轻杄。MC属于Ҏcd的游戏,适合Ҏ领域特别优化Q也是专门为方块做出特别的设计来做优化。ECS属于通用框架Q即便性能OKQ但是代码未必能有良好的可读性? 体量的游戏适合用ECS来做么? 可以Q但不徏议。特别是只有几个人维护的工程QN然上ECSpȝQ会让系l变的极为复杂。当然你会说Q如果开发到后期Q传l开发模式会D代码会ؕQECS会好些吧。掌握ECS也不是一天两天的事情Q不熟悉ECS的程序员设计出来的系l获得的优势可能q不如用传统设计Ҏ好呢? 架构解决的是人的问题Q?人都有问题,用什么框枉没办法? 到底什么项目适合用ECSQ? 1. 大量的小个体不断的生成和销毁以及显C,例如Q?d战中Q要体现每个角色的移动,战斗? 2. 多于5个h~写核心战斗逻辑。互相协作和模块切分Q需要一个大安能信服的框架QECS可以选择? P.S. 不要造ECS的轮子! 很多同学看了ECS基本原理Q在没有深入使用qQ何ECSpȝ旉上操刀造轮子。ECSpȝ实看v来简单。实际造下来你会发玎ͼ性能非常p糕以及不知道一些逻辑如何用ECS来解冟? ȝQ? 1. ECS实为性能而生Q没有ƈ发加持性能的ECS都是耍流氓,要快p快到极致? 2. Unity中,ECSq发能扩展CPU的利用率Q但是GPU的性能依然q是DrawCall优化那一套,别期望ECS会颠覆UnityQ性能也不会快到飞P关键q是要看具体的项目和人? 3. ECS是万能框Ӟ但不全能。传l架构和设计思想也不是一无是处,熟啥用啥Q怎么快怎么来! https://mip.bmlink.com/wu19870821/news/2611408.html https://mip.bmlink.com/wu19870821/news/2611409.html https://mip.bmlink.com/wu19870821/news/2611410.html https://mip.bmlink.com/wu19870821/news/2611411.html https://mip.bmlink.com/wu19870821/news/2611412.html https://mip.bmlink.com/wu19870821/news/2611413.html https://mip.bmlink.com/wu19870821/news/2611414.html https://mip.bmlink.com/wu19870821/news/2611415.html https://mip.bmlink.com/wu19870821/news/2611416.html https://mip.bmlink.com/wu19870821/news/2611417.html https://m.bmlink.com/wu19870821/news/2611408.html https://m.bmlink.com/wu19870821/news/2611409.html https://m.bmlink.com/wu19870821/news/2611410.html https://m.bmlink.com/wu19870821/news/2611411.html https://m.bmlink.com/wu19870821/news/2611412.html https://m.bmlink.com/wu19870821/news/2611413.html https://m.bmlink.com/wu19870821/news/2611414.html https://m.bmlink.com/wu19870821/news/2611415.html https://m.bmlink.com/wu19870821/news/2611416.html https://m.bmlink.com/wu19870821/news/2611417.html https://wu19870821.bmlink.com/news/2611408.html https://wu19870821.bmlink.com/news/2611409.html https://wu19870821.bmlink.com/news/2611410.html https://wu19870821.bmlink.com/news/2611411.html https://wu19870821.bmlink.com/news/2611412.html https://wu19870821.bmlink.com/news/2611413.html https://wu19870821.bmlink.com/news/2611414.html https://wu19870821.bmlink.com/news/2611415.html https://wu19870821.bmlink.com/news/2611416.html https://wu19870821.bmlink.com/news/2611417.html https://www.bmlink.com/wu19870821/news/2611408.html https://www.bmlink.com/wu19870821/news/2611409.html https://www.bmlink.com/wu19870821/news/2611410.html https://www.bmlink.com/wu19870821/news/2611411.html https://www.bmlink.com/wu19870821/news/2611412.html https://www.bmlink.com/wu19870821/news/2611413.html https://www.bmlink.com/wu19870821/news/2611414.html https://www.bmlink.com/wu19870821/news/2611415.html https://www.bmlink.com/wu19870821/news/2611416.html https://www.bmlink.com/wu19870821/news/2611417.html https://mip.bmlink.com/chaoweifensuiji/news/2611407.html https://mip.bmlink.com/chaoweifensuiji/news/2611406.html https://mip.bmlink.com/chaoweifensuiji/news/2558756.html https://mip.bmlink.com/chaoweifensuiji/news/2558753.html https://mip.bmlink.com/chaoweifensuiji/news/2558748.html https://mip.bmlink.com/chaoweifensuiji/news/2558743.html https://mip.bmlink.com/chaoweifensuiji/news/2558740.html https://mip.bmlink.com/chaoweifensuiji/news/2558737.html https://mip.bmlink.com/chaoweifensuiji/news/2558731.html https://m.bmlink.com/chaoweifensuiji/news/2611407.html https://m.bmlink.com/chaoweifensuiji/news/2611406.html https://m.bmlink.com/chaoweifensuiji/news/2558756.html https://m.bmlink.com/chaoweifensuiji/news/2558753.html https://m.bmlink.com/chaoweifensuiji/news/2558748.html https://m.bmlink.com/chaoweifensuiji/news/2558743.html https://m.bmlink.com/chaoweifensuiji/news/2558740.html https://m.bmlink.com/chaoweifensuiji/news/2558737.html https://m.bmlink.com/chaoweifensuiji/news/2558731.html https://chaoweifensuiji.bmlink.com/news/2611407.html https://chaoweifensuiji.bmlink.com/news/2611406.html https://chaoweifensuiji.bmlink.com/news/2558756.html https://chaoweifensuiji.bmlink.com/news/2558753.html https://chaoweifensuiji.bmlink.com/news/2558748.html https://chaoweifensuiji.bmlink.com/news/2558743.html https://chaoweifensuiji.bmlink.com/news/2558740.html https://chaoweifensuiji.bmlink.com/news/2558737.html https://chaoweifensuiji.bmlink.com/news/2558731.html https://www.bmlink.com/chaoweifensuiji/news/2611407.html https://www.bmlink.com/chaoweifensuiji/news/2611406.html https://www.bmlink.com/chaoweifensuiji/news/2558756.html https://www.bmlink.com/chaoweifensuiji/news/2558753.html https://www.bmlink.com/chaoweifensuiji/news/2558748.html https://www.bmlink.com/chaoweifensuiji/news/2558743.html https://www.bmlink.com/chaoweifensuiji/news/2558740.html https://www.bmlink.com/chaoweifensuiji/news/2558737.html https://www.bmlink.com/chaoweifensuiji/news/2558731.html https://mip.bmlink.com/towercrane/news/2541940.html https://mip.bmlink.com/towercrane/news/2541945.html https://mip.bmlink.com/towercrane/news/2541950.html https://mip.bmlink.com/towercrane/news/2541966.html https://mip.bmlink.com/towercrane/news/2541991.html https://mip.bmlink.com/towercrane/news/2541992.html https://mip.bmlink.com/towercrane/news/2541993.html https://mip.bmlink.com/towercrane/news/2541994.html https://mip.bmlink.com/towercrane/news/2541995.html https://m.bmlink.com/towercrane/news/2541940.html https://m.bmlink.com/towercrane/news/2541945.html https://m.bmlink.com/towercrane/news/2541950.html https://m.bmlink.com/towercrane/news/2541966.html https://m.bmlink.com/towercrane/news/2541991.html https://m.bmlink.com/towercrane/news/2541992.html https://m.bmlink.com/towercrane/news/2541993.html https://m.bmlink.com/towercrane/news/2541994.html https://m.bmlink.com/towercrane/news/2541995.html https://towercrane.bmlink.com/news/2541940.html https://towercrane.bmlink.com/news/2541945.html https://towercrane.bmlink.com/news/2541950.html https://towercrane.bmlink.com/news/2541966.html https://towercrane.bmlink.com/news/2541991.html https://towercrane.bmlink.com/news/2541992.html https://towercrane.bmlink.com/news/2541993.html https://towercrane.bmlink.com/news/2541994.html https://towercrane.bmlink.com/news/2541995.html https://www.bmlink.com/towercrane/news/2541940.html https://www.bmlink.com/towercrane/news/2541945.html https://www.bmlink.com/towercrane/news/2541950.html https://www.bmlink.com/towercrane/news/2541966.html https://www.bmlink.com/towercrane/news/2541991.html https://www.bmlink.com/towercrane/news/2541992.html https://www.bmlink.com/towercrane/news/2541993.html https://www.bmlink.com/towercrane/news/2541994.html https://www.bmlink.com/towercrane/news/2541995.html https://mip.bmlink.com/xxmjhw888/news/2611429.html https://mip.bmlink.com/xxmjhw888/news/2611428.html https://mip.bmlink.com/xxmjhw888/news/2611427.html https://mip.bmlink.com/xxmjhw888/news/2611426.html https://mip.bmlink.com/xxmjhw888/news/2611425.html https://mip.bmlink.com/xxmjhw888/news/2611424.html https://mip.bmlink.com/xxmjhw888/news/2611423.html https://mip.bmlink.com/xxmjhw888/news/2611422.html https://mip.bmlink.com/xxmjhw888/news/2611421.html https://mip.bmlink.com/xxmjhw888/news/2611420.html https://mip.bmlink.com/xxmjhw888/news/2611419.html https://mip.bmlink.com/xxmjhw888/news/2611418.html https://m.bmlink.com/xxmjhw888/news/2611429.html https://m.bmlink.com/xxmjhw888/news/2611428.html https://m.bmlink.com/xxmjhw888/news/2611427.html https://m.bmlink.com/xxmjhw888/news/2611426.html https://m.bmlink.com/xxmjhw888/news/2611425.html https://m.bmlink.com/xxmjhw888/news/2611424.html https://m.bmlink.com/xxmjhw888/news/2611423.html https://m.bmlink.com/xxmjhw888/news/2611422.html https://m.bmlink.com/xxmjhw888/news/2611421.html https://m.bmlink.com/xxmjhw888/news/2611420.html https://m.bmlink.com/xxmjhw888/news/2611419.html https://m.bmlink.com/xxmjhw888/news/2611418.html https://xxmjhw888.bmlink.com/news/2611429.html https://xxmjhw888.bmlink.com/news/2611428.html https://xxmjhw888.bmlink.com/news/2611427.html https://xxmjhw888.bmlink.com/news/2611426.html https://xxmjhw888.bmlink.com/news/2611425.html https://xxmjhw888.bmlink.com/news/2611424.html https://xxmjhw888.bmlink.com/news/2611423.html https://xxmjhw888.bmlink.com/news/2611422.html https://xxmjhw888.bmlink.com/news/2611421.html https://xxmjhw888.bmlink.com/news/2611420.html https://xxmjhw888.bmlink.com/news/2611419.html https://xxmjhw888.bmlink.com/news/2611418.html https://www.bmlink.com/xxmjhw888/news/2611429.html https://www.bmlink.com/xxmjhw888/news/2611428.html https://www.bmlink.com/xxmjhw888/news/2611427.html https://www.bmlink.com/xxmjhw888/news/2611426.html https://www.bmlink.com/xxmjhw888/news/2611425.html https://www.bmlink.com/xxmjhw888/news/2611424.html https://www.bmlink.com/xxmjhw888/news/2611423.html https://www.bmlink.com/xxmjhw888/news/2611422.html https://www.bmlink.com/xxmjhw888/news/2611421.html https://www.bmlink.com/xxmjhw888/news/2611420.html https://www.bmlink.com/xxmjhw888/news/2611419.html https://www.bmlink.com/xxmjhw888/news/2611418.html https://www.ixueyi.com/qinggan/a_Tl9sM38K.html https://www.ixueyi.com/falv/a_2I2ewPSh.html https://www.ixueyi.com/falv/a_Y1Un4tSK.html https://www.ixueyi.com/falv/a_9Q3N5R3R.html https://www.ixueyi.com/falv/a_A9E8Pvl3.html https://www.ixueyi.com/falv/a_2jy4G07C.html https://www.ixueyi.com/falv/a_W5r2as2P.html https://www.ixueyi.com/falv/a_a20P8p3T.html https://www.ixueyi.com/falv/a_5jl15mkU.html https://www.ixueyi.com/falv/a_C646nFN4.html https://www.ixueyi.com/falv/a_n71xa7a2.html https://www.ixueyi.com/falv/a_VCxaehV6.html https://www.ixueyi.com/falv/a_7JhXF2L0.html https://www.ixueyi.com/falv/a_y5tA5IdR.html https://www.ixueyi.com/falv/a_qn722hR8.html https://www.ixueyi.com/falv/a_yX5W85yK.html https://www.ixueyi.com/renshi/a_r569sY1C.html https://www.ixueyi.com/renshi/a_472EFKfF.html https://www.ixueyi.com/renshi/a_umemPeiO.html https://www.ixueyi.com/renshi/a_9o6T89n3.html https://www.ixueyi.com/renshi/a_GX26np9Q.html https://www.ixueyi.com/falv/a_4CAdyV14.html https://www.ixueyi.com/falv/a_i28019yM.html https://www.ixueyi.com/falv/a_b2fyO1od.html https://www.ixueyi.com/falv/a_oq1MYAeY.html https://www.ixueyi.com/falv/a_XSVSuYNm.html https://www.ixueyi.com/falv/a_LUxNT8oA.html https://www.ixueyi.com/falv/a_agNvlmr3.html<img src ="http://www.shnenglu.com/sunicdavy/aggbug/217892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2021-12-27 19:01 <a href="http://www.shnenglu.com/sunicdavy/archive/2021/12/27/217892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏与Web的服务器Ҏhttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.html战魂筑战魂筑Wed, 29 Aug 2018 03:16:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.htmlhttp://www.shnenglu.com/sunicdavy/comments/215887.htmlhttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/215887.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/215887.htmlZ~写Zcellnet的新一代游戏服务器框架Q最q深入研I微服务QServiceMesh{概c研I过E中对Web和游戏两U服务器架构设计有一些心得,~写q记录下来?下文中,Game表示游戏服务器,Web表示Web服务? ``
状态缓?/span>
所谓状态缓存,是在内存而非专业数据~存服务器(如redisQ中保存和处理逻辑数据Q手动编写此q程较ؓJ琐但是效率较高Q但随着状态逻辑复杂性和q发、扩定w题提出,状态同步会变得来复杂?/span>
Game:
Z互性的服务器类型需要在服务器做~存Q逻辑~写也较为容易,无需处理事务q发问题。例如:l队Q匹配,战斗逻辑。服务器不能随意重启?/span>
׃互性的服务器类型可配合redis做成无状态服务器Q例如:LQ技能升U,领取物品{。服务器随时支持重启?/span>
游戏服务器ؓ了提高性能Q早期所有服务器都是使用状态缓存写法编写,特别是MMORPGq类Z互的游戏服务器尤Z重?/span>
Web:
均ؓ无状态服务器Q弱交互。用事务方式处理ƈ发逻辑Q例如:交易Q下单等?/span>
推送,单独发?/span>
q里提到的所谓推送,单独发送是与RPC区别的通讯Ҏ。RPC要求h必须有回应。而推送单独发送则更像是通知和广播,无需目的方返回Q何消息?/span>
Game:
扑ֈ服务器的SessionQ直接Send
通过中{服务器,或称Z心服务器q行注册/q播
客户端的model数据需要更新时Q服务器会主动推送消息?/span>
游戏服务器没有严格的RPC设计需求,推送和单独发送较Web服务器更多。而且游戏服务器多使用长连接,所以主动推送也比Web服务器来的方便一些?/span>
Web:
推送做成专有的服务Qƈ做排队和q发处理?/span>
可用?/span>
听说q游戏停服更斎ͼ支付宝服务器在刷二维码时停服了可一定被骂惨吧。WebҎ务器高可用性要求很高,游戏虽然也注重服务器E_性和可用性,但是׃版本q代更新频繁Q停服更新反而能获得玩家接受?/span>
Game:
游戏对可用性要求不高?/span>
游戏大版本更新时需要停服更新。支持热更新技术的服务器(例如ErlangQSkynetQ仅使用热更C复bugQ很直接更新新版本?/span>
不是所有的游戏服务器支持动态添加服务器?/span>
Web:
极高的可用性,服务不允许停服更斎ͼ使用蓝绿及灰度方式更新服务器?/span>
随时可以横向扩展服务器,提高服务器容量和承蝲?/span>
q接及传?/span>
均用TCP传输协议Q游戏服务器注重性能Q自有协议及二进制协议用较多?/span>
Web注重兼容和接口友好,使用JSON格式较多?/span>
Game:
使用长连接,需要从逻辑层维护连接状态及处理服务器不在线情况
使用自有包格式Q大部分使用protobuf或二q制格式?/span>
Web:
微服务大部分使用短连接,grpc支持http2长连?/span>
使用json~码方便调试和版本兼宏V?/span>
量限制
人数多了QQ何服务器都扛不住Q流量限制和d限制能有效保护服务器E_?/span>
Game:
单服有h数限Ӟ可以通过GM后台讄挡墙Q超q无法进?/span>
Web:
限流器中间gQ可以精到服务控制量
断流Q防止雪?/span>
Game:
游戏没有Q也不需要这U概念,游戏h不会H然升高Q即便有Q也通过GM后台Zؓ控制
Web:
断流器中间g
服务发现
如何扑ֈ服务器地址?/span>
服务有变化时Q通过Watchpȝ通知订阅者更新本地缓?/span>
服务器没有变化时Q用本地缓存找到服务地址
Game:
游戏服务器互怾赖复用只在很的范围内,因此无需在不同语a不同q程服务间获得地址Q大部分在配|文件中填写各服务的IP及地址卛_互相讉K?/span>
早期游戏自己~写服务器状态及地址发现服务?/span>
有用redis做服务发?/span>
Web:
使用服务发现pȝQ分布式部v。无需依赖配置文g
|关需?/span>
Game:
|关处理客户端上下线通知Q心跻Il持q接Q{发,q播上下行封?/span>
Web:
Ҏh地址路由Q无上下U概念,无心跟뀂广播通过消息推送系l完?/span>
׃W者从事游戏行业,对Web服务器概念在逐渐熟悉中,若有错误和不各位大{指出?/span>
本hC《Go语言从入门到q阶实战》,生动的语aQ例子带有各U彩蛋,L了解Go语言Ҏ,更有cellnet框架剖析解密
https://search.jd.com/Search?keyword=go%E8%AF%AD%E8%A8%80%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E5%AE%9E%E6%88%98&enc=utf-8&suggest=1.def.0.V02&wq=Go%E8%AF%AD%E8%A8%80%E4%BB%8E&pvid=145d55a92cab4b07b71326f8beb1700b


战魂筑 2018-08-29 11:16 发表评论
]]>
Golang 热更新研I笔?/title><link>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 06 Jul 2017 04:47:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/215057.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/215057.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/215057.html</trackback:ping><description><![CDATA[<p data-source-line="1" style="box-sizing: border-box; margin-bottom: 16px; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff; margin-top: 0px !important;">本文主要研究游戏服务器带状态的热更新需?http的无状态热更新需求已l有成熟Ҏ, 故不在本文描q范?/p><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#基本概念" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>基本概念</h1><ul data-source-line="6" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">Golang的热更新采用什么机?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用go1.8提供的plugin包机制实?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包本w设计的目的是热更新?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包其实只是支持将代码分别~译为多个动态库,动态加载后q行 q不能完全支持类似C/C++的动态库方式处理代码</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">带状态的q程热更新的基本概念及范围是什?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">数据部分(model)不更? 只更新逻辑部分(函数)</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">表格和配|更新算热更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">? 但不是本文描q范?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">热更新能在windows上用么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不支?/p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#代码及结? style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>代码及结?/h1><ul data-source-line="29" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">我能原来一个exe的代码编译ؓso提供lplugin使用?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 但是必须仍然保留main包作为插件入? q在main包内d提供lplugin调用入口.</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果动态库中没有main? ~译出的so能用?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不能, 包必d含main, 否则输出的是.a的文? plugin包加载会报错</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">动态库? 非main包的的代码修改能做热更新?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">不能</span>!(崩溃了吧, 我提了一个issue: <a style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/20554</a>)</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果实做了修改, 底层会报? plugin was built with a different version of package</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">解决Ҏ: 修改plugin包底层实现ƈ重新~译 打开runtime/plugin.go, 注释以下代码 for _, pkghash := range md.pkghashes { if pkghash.linktimehash != *pkghash.runtimehash { return "", nil, pkghash.modulename } } 执行/usr/local/go/run.bash 重编?试</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">代码中哪些可以被更新? Ҏ可以被更C? 闭包?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">只能更新拥有静态地址的结?例如: 包别函?cM于静态函?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">例如: svc_0.so里有一个Foo函数, svc_1.so修改了Foo函数实现, 热更新可实现</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">闭包=函数+捕获变量</span>, 实际上是一个动态结? 没有静态地址, 无法被更?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">各种包别变? l构体变? l构体方? 局部变量均不能被热更新, 但是变量g会被影响</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">新增l构可以被运?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用l构体方法调用了包别函? 包别函数能被更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 虽然Ҏ不能被更? 但方法被调用的包U别函数的地址是固定的, 所以可以被热更?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">init包初始化函数能用? 能被热更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">官方q样描述:</p><pre data-source-line="71" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;"><span style="box-sizing: border-box; font-weight: 700;">When</span> a plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> first opened, the init functions <span style="box-sizing: border-box; font-weight: 700;">of</span> <span style="box-sizing: border-box; font-weight: 700;">all</span> packages <span style="box-sizing: border-box; font-weight: 700;">not</span> already part <span style="box-sizing: border-box; font-weight: 700;">of</span> the program are called. The main <span style="box-sizing: border-box; font-weight: 700;">function</span> <span style="box-sizing: border-box; font-weight: 700;">is</span> <span style="box-sizing: border-box; font-weight: 700;">not</span> run. A plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> only initialized once, <span style="box-sizing: border-box; font-weight: 700;">and</span> cannot be closed</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">插gW一ơ被打开? 其关联的, 没有成ؓE序的一部分的所有的包的init函数被调用. 插g的main函数不会被调? 插g只会被初始化一? 不能被关?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">因此, 需要手动将init函数Ҏ自己的函? l一在so的main包里调用</p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#~译" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>~译</h1><ul data-source-line="80" style="box-sizing: border-box; margin-top: 0px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff; margin-bottom: 0px !important;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如何~译获得plugin包支持的动态库</p><pre data-source-line="82" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;">SVCNAME=<span style="box-sizing: border-box; color: teal;">$1</span> SVCVER=<span style="box-sizing: border-box; color: teal;">$2</span> TIMESTAMP=`date <span style="box-sizing: border-box; color: #dd1144;">'+%Y%m%d_%H%M%S'</span>` go build -v -buildmode=plugin --ldflags=<span style="box-sizing: border-box; color: #dd1144;">"-pluginpath=${SVCNAME}_${TIMESTAMP}"</span> -o ${SVCNAME}<span style="box-sizing: border-box; color: teal;">_</span>${SVCVER}.so ${SVCNAME}</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">-buildmode=plugin是重要参?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">--ldflags里的-pluginpath的作用是: 每次~译的内部识别\径都是不同的, 避免重复加蝲的警?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">参? <a style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/19004</a></p></li></ul><img src ="http://www.shnenglu.com/sunicdavy/aggbug/215057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2017-07-06 12:47 <a href="http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Visual Studio Code调试Golang工程http://www.shnenglu.com/sunicdavy/archive/2017/04/20/214874.html战魂筑战魂筑Thu, 20 Apr 2017 04:52:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2017/04/20/214874.htmlhttp://www.shnenglu.com/sunicdavy/comments/214874.htmlhttp://www.shnenglu.com/sunicdavy/archive/2017/04/20/214874.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/214874.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/214874.html使用Visual Studio Code调试Golang工程

  • 最单的调试ȝ
  • 多项目调? 适用个h开发和目开?/li>
  • 无需修改pȝ环境变量
  • 准备VSCode

    在官|下载最新版的VSCode:

    https://code.visualstudio.com/

    安装Golang插g

    • 打开扩展面板

      VSCode->查看->扩展

    • 扑ֈGo插g 在搜索框里输入Go, 扑ֈW二行写?Rich Go language support for Visual Studio Code的插? 点击安装

      注意不是排名最高的

    • 重启~辑?/p>

  • 打开调试面板

    VSCode->查看->调试

  • d调试目标

    ?没有调试"的下拉框中点?d配置.."

  • d目标调试配置

    例子:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch",
                "type": "go",
                "request": "launch",
                "mode": "debug",
                "remotePath": "",
                "port": 2345,
                "host": "127.0.0.1",
                "program": "${fileDirname}",
                "env": {
                    "GOPATH":"D:/Develop/vscodegolang"
                },
                "args": [],
                "showLog": true
            }
        ]
    }
  • 其中: "port", "host"都是go插g自动生成?/p>

    "env"|环境变? 讄Z的工E目录就可以(包含bin, src的文件夹)

    准备调试插g

    此时扑ֈmain.go按F5, 会报错提C?

    Failded to continue:"Cannot find Delve debugger. Install from https://github.com/derekparker/delve & ensure it is in your "GOPATH/bin" or "PATH"

    我们使用go命o行编译调试器

    go get github.com/derekparker/delve/cmd/dlv

    dlv调试器放在GOPATH(工程目录)的bin目录?/p>

    选中要调试的main.go, 点击F5, 既可以开始调?/p>

    调试快捷键和Visual StudiopM?/p>

    • F9 切换断点
    • F10 Step over
    • F11 Step in
    • Shift+F11 Step out

    注意?/p>

    • 某些l构体成员无法直接显C时, 可以直接选中变量? d到监? 或者右键点? "调试:求?

    在launch.json中可以添加多l调试入? 通过调试面板中选中对应的配|开启不同目标的调试

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "client",
                "type": "go",
                "request": "launch",
                "mode": "debug",
                "remotePath": "",
                "port": 2345,
                "host": "127.0.0.1",
                "program": "${fileDirname}",
                "env": {
                    "GOPATH":"D:/Develop/vscodegolang"
                },
                "args": [],
                "showLog": true
            },
    
            {
                "name": "server",
                "type": "go",
                "request": "launch",
                "mode": "debug",
                "remotePath": "",
                "port": 2345,
                "host": "127.0.0.1",
                "program": "${workspaceRoot}/src/server",
                "env": {
                    "GOPATH":"D:/Develop/vscodegolang"
                },
                "args": [],
                "showLog": true
            }
        ]
    }

    "program"中的"${fileDirname}"是以当前选中文g作ؓ启动?/p>

    更徏议?program"?${workspaceRoot}", 以包名作为启动点的方式进行配|?/strong>

    https://code.visualstudio.com/Docs/editor/debugging



    战魂筑 2017-04-20 12:52 发表评论
    ]]>Go语言与构造函?/title><link>http://www.shnenglu.com/sunicdavy/archive/2016/12/01/214457.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 01 Dec 2016 02:45:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2016/12/01/214457.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/214457.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2016/12/01/214457.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/214457.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/214457.html</trackback:ping><description><![CDATA[<p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;">Golang中没有设计构造函? 取而代之的, 设计Golang的大师希望你用普通函数去实现构造的d. <br />一直只是觉得这只是体现Golangq门新语a的精设计之道, 直到自己实现~译器后才发现构造函数的设计本n是值得商榷?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">我们先看下构造函数的规则</p><h1>构造函数调用规?/h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造参数量: 0表示没有构造函? 1表示有构造函?个参?/p><table style="margin: 10px 0px; border-collapse: collapse; border-style: solid; border-color: #bbbbbb; padding: 0px; color: #000000; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><thead><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">本类构?/th><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">父类构?/th><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">处理Ҏ</th></tr></thead><tbody><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">不处?/td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本cctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调父cctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本cctor, 本类ctor调父cctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本cctor, 本类ctor调父cctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">报错, 手动调父cctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">报错, 手动调父cctor</td></tr></tbody></table><h1>普通函数重载规?/h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">实际只用考虑最典型的一U行? 实例化子c? 转ؓ父类调用Ҏ, q个时?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果Ҏ是override, 调用的是子类</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果Ҏ是virutal或者不指明, 调用的是父类</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">整个重蝲q程, 子类l对不会隐式调用父类的行?/p><h1>需要构造函C?</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造函数的优点</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;">本n属于一U特D的成员函数</li><li style="margin: 5px 0px;">~译器帮你自动传D用父U?/li></ul><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造函数的~点</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;">隐式的调用规?/li><li style="margin: 5px 0px;">虽然属于成员函数, 但是与其他成员函数调用规则完全不? 需要特D记?/li><li style="margin: 5px 0px;">带参数的构造函? 在父cd数多于子cL, 需要引用复杂语法来实现父构造调?/li></ul><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">其实我们对初始化函数的需求只?? 自定?/p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;">所? 可以理解Golang不加入构造函数的设计是正的 <br />? ? 清晰, 有规?/p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/214457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2016-12-01 10:45 <a href="http://www.shnenglu.com/sunicdavy/archive/2016/12/01/214457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Go语言的冷知识http://www.shnenglu.com/sunicdavy/archive/2016/11/02/214375.html战魂筑战魂筑Wed, 02 Nov 2016 03:09:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/11/02/214375.htmlhttp://www.shnenglu.com/sunicdavy/comments/214375.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/11/02/214375.html#Feedback1http://www.shnenglu.com/sunicdavy/comments/commentRss/214375.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/214375.htmlappend, map, len不是关键?/h1>

    他们其实q是cd功能, 都在buildin包里? pȝ默认l你做了?/p>

    1. import(
    2. . "buildin"
    3. )

    buildin的包内容都映到全局而已, 其实你也可以用自q包这么做

    打印的另一U写?/h1>

    惌脚本一栯试打印数据么?

    1. println("hello world")

    无需包含M? 因ؓ它在buildin包里

    iota不是黑科技

    q是在buildin包里的定?/p>

    1. // iota is a predeclared identifier representing the untyped integer ordinal
    2. // number of the current const specification in a (usually parenthesized)
    3. // const declaration. It is zero-indexed.
    4. const iota = 0 // Untyped int.

    其实go是有泛型概念?/h1>

    xmap和数l的定义 
    只是泛型没有开攄用户用而已(只许XX攄,不许XX点灯)

    map是支持多个key? 而且很方?/h1>

    q在为多个key转id的复杂算法而头g?

    1. type myKey struct{
    2. number int
    3. str string
    4. }
    5. func main(){
    6. t := map[ myKey] int {
    7. myKey{ 2, "world"}: 1,
    8. }
    9. fmt.Println(t[myKey{2, "world"}])
    10. }
    11. 输出: 1

    枚D是可以{成string?/h1>

    默认定义一个枚?/p>

    1. type MyConst int
    2. const (
    3. MyConst_A MyConst = iota
    4. MyConst_B MyConst = iota
    5. )
    6. func main(){
    7. fmt.Println(MyConst_A)
    8. }

    输出: 0 
    如果我们惌动化输出MyConst_A字符串时 
    需要用golang的一个工具链:golang.org/x/tools/cmd/stringer 
    其下蝲, ~译成可执行工具? 对代码进行生?nbsp;
    生成的代码会多出一个xx_string.go 
    里面是枚D的String()string 函数

    临时转换一个接口ƈ调用的方?/h1>
    1. type love struct{
    2. }
    3. func (self*love)foo(){
    4. fmt.Println("love")
    5. }
    6. func main(){
    7. var chaos interface{} = new(love)
    8. chaos.(interface{
    9. foo()
    10. }).foo()
    11. }

    Golang的receiver实际上就是this的变U实?/h1>
    1. func( self*MyStruct) foo( p int ){
    2. }

    写不惯receiver的写? 如果q样改下?

    1. func foo( self *MyStruct, p int ){
    2. }

    所以ؓ什么说Golangq是一个C语言?/p>

    关于内存分配…

    • new 传入Typecd, q回*Typecd
    • make 可以在分配数l时讄预分配大? new不可?/li>
    • make 能分配数l?map, 但不能分配结构体和原始类?/li>
    • new 能分配数l? map, l构体和原始cd{的所有类?/li>
    • &Type{效于new
    • 切片不需要分配内?make,new), 直接声明可以了…

    Golang的反无法通过一个类型名, 创徏其实?/h1>

    C#有Assembly概念, 可以在一个Assembly里搜? 创徏实例

    Golang是静态类型语a, 如果需? 只能注册你需要创建的l构? 然后注册好的map用于创徏

    Golang可以替换Python来进行复杂的工具程处理

    如果你需要跨q_的工hE处? 对Python不熟? 可以使用

    1. go run yourcode.go 参数1 参数2

    方式来进行工具处?nbsp;
    觉得? 可以~译成可执行文g

    q样做的好处: 如果有些cd本n是go写的, Python想用是很麻烦的, 而Golang来写则轻而易?/p>

    例子: 通过go的protobuf? 对一些文件进行处?/p>

    Golang可以自动持有Ҏ的接收者实?/h1>
    1. type myType struct{
    2. }
    3. func (self*myType) foo( p int){
    4. fmt.Println("hello", p )
    5. }
    6. func main(){
    7. var callback func( int )
    8. ins := new(myType)
    9. callback = ins.foo
    10. callback( 100 )
    11. }

    做过lua的C++代码l定的童鞋都清楚: lua只支持外部静态或者全局函数调用 
    如果要进行C++cL员函数调用时, 要自己处理this和成员函?nbsp;
    q种技巧因为早L译器的虚表不同^台实现细节不l一需要专门处?nbsp;
    后面跨^台虚表统一? cL员函数的调用写法也是很恶心复杂的 
    但是Golang的小白式用法, 直接吊打C++, 甚至C#复杂的delegate

    LiteIDE? 多开U籍

    • 扑ֈ 菜单->查看->选项->通用->存储->存储讄到本地ini文g

    • 关闭LiteIDE

    • 复制LiteIDE整个目录, 命名文g夹ؓ你的工程?/p>

    • 每个工程所在的LiteIDE的配|将是独立的, 不会互相q扰

    LiteIDE? 试E序也是可以调试?/h1>

    别以为程序一定要是main开始的才可以调?/p>

    Golang的测试程序虽焉是一个个Test开头的函数,但执行go test? q是有main入口

    在LiteIDE? 可以?调试->开始调试测试程序里q行试E序调试

    LiteIDE? 在Windows上可以输出linux可执行文?/h1>

    go的工具链默认支持交叉~译 
    在LiteIDE? 可以通过切换输出q_, 输出不同q_的可执行文g



    战魂筑 2016-11-02 11:09 发表评论
    ]]>使用delve调试GolangE序技?/title><link>http://www.shnenglu.com/sunicdavy/archive/2016/09/03/214254.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Sat, 03 Sep 2016 10:12:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2016/09/03/214254.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/214254.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2016/09/03/214254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/214254.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/214254.html</trackback:ping><description><![CDATA[<p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;"></p><p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;">Google官方为Golang的调试例子默认用了gdb</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">然? 使用gdb调试goE序会遇到goroutine的各c问? 因ؓgdb不懂go</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">因此, q里使用delve黑科技来进行Golang的程序调?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">U命令行调试Ҏ在网上很Ҏ搜烦? 本文主要以LiteIDE来进行程序调?/p><h1>关闭~译器优?/h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">正常go build/install出的goE序是完全优化过? 使用调试器挂接调试时, 某些local变量/lamda表达式捕L变量会直接进入寄存器, 无法使用调试器查?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">删掉所有的pkg, 为build或install参数加入关闭~译器优化的参数 -gcflags "-N -l"</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">例如:</p><pre linenums="" prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;"> go install </span><span style="color: #93a1a1;">-</span><span style="color: #48484c;">gcflags </span><span style="color: #dd1144;">"-N -l"</span><span style="color: #48484c;"> svc\gamesvc</span></code></li></ol></pre><h2>delve调试器安装方?/h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE自带了gdb, 但是没有delve调试? 需要自行安? 命o如下</p><pre linenums="" prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">go </span><span style="color: #1e347b;">get</span><span style="color: #48484c;"> github</span><span style="color: #93a1a1;">.</span><span style="color: #48484c;">com</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">derekparker</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">delve</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">cmd</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">dlv</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">delve调试器会被放C的GOPATH/bin?/p><h1>LiteIDE中的delve调试器配|?/h1><h2>选择调试?/h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">在LiteIDE菜单中选择 调试->debugger/delve</p><h2>delve环境变量讄</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">q个时? LiteIDE依然找不到delve, 因ؓ它不在环境变量PATH? q里无需修改环境变量, 只需要LiteIDE的环境配|?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">在LiteIDE菜单中选择 查看->~辑当前环境, 在弹出的文档中修?/p><pre linenums="" prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">PATH</span><span style="color: #93a1a1;">=</span><span style="color: #48484c;">c</span><span style="color: #93a1a1;">:</span><span style="color: #48484c;">\mingw32\b</span><span style="color: #1e347b;">in</span><span style="color: #93a1a1;">;%</span><span style="color: #48484c;">GOROOT</span><span style="color: #93a1a1;">%</span><span style="color: #48484c;">\b</span><span style="color: #1e347b;">in</span><span style="color: #93a1a1;">;%</span><span style="color: #48484c;">PATH</span><span style="color: #93a1a1;">%;</span><span style="color: #48484c;">c</span><span style="color: #93a1a1;">:</span><span style="color: #48484c;">\y</span><span style="color: #1e347b;">our</span><span style="color: #48484c;">\path\to\delve</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LPATH前的注释#, ?PATH%d分号, 然后和你到delve调试器的路径</p><h2>开始调?/h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">选择你的工程, 点击F5, q入调试模式</p><h2>调试器显C变量?/h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;"><img src="file:///D:/Documents/My%20Knowledge/temp/6f9eec62-fe6c-4f28-89ad-acbade688a96/4/index_files/2be001ea-878e-4e38-9209-76ef93d427f0.png" style="border: 0px; max-width: 100%; margin: 2px 0px; height: auto !important;" alt="" /></p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE使用delve调试? 无法?变量 监视{窗口中正确捕捉delve调试q回数据(因ؓ格式太复杂了…)</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">没关p? 我们使用命o行配合显C即?/p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE控制台或调试输出H口在delve调试? 实际上是一个标准命令行 <br />命o如下</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;"><p style="margin: 0px;">p 变量名可以查看变量?/p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">locals查看局部变?/p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">ls可查看当前文?/p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">stack查看?/p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">help可以查看各种帮助</p></li></ul><h2>调试外部E序</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果你的E序是外部程? 或者用go install安装到GOPATH/bin目录的程? 那么使用delve调试器启动程序时, 可能会碰到启动\径错误的问题</p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;">使用LiteIDE菜单 调试->调试其他应用E序… 填入你要调试E序的\径以及工作目? 可以解决q个问题</p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, "Hiragino Sans GB", 微Y雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;"></p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/214254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2016-09-03 18:12 <a href="http://www.shnenglu.com/sunicdavy/archive/2016/09/03/214254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang的简单反性能试http://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.html战魂筑战魂筑Fri, 12 Aug 2016 07:26:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.htmlhttp://www.shnenglu.com/sunicdavy/comments/214152.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/214152.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/214152.html试用例

    我们对Golang的结构体变量赋? 以及单参数函数调用进行反和native操作的测?pre>

     

    package main

     

    import (

    "reflect"

    "testing"

    )

     

    type data struct {

    Hp int

    }

     

    const AssignTimes = 100000000

     

    func TestNativeAssign(t *testing.T) {

     

    v := data{Hp: 2}

     

    for i := 0; i < AssignTimes; i++ {

    v.Hp = 3

    }

     

    }

     

    func TestReflectAssign(t *testing.T) {

     

    v := data{Hp: 2}

     

    vv := reflect.ValueOf(&v).Elem()

     

    f := vv.FieldByName("Hp")

     

    for i := 0; i < AssignTimes; i++ {

     

    f.SetInt(3)

    }

     

    }

     

    func TestReflectFindFieldAndAssign(t *testing.T) {

     

    v := data{Hp: 2}

     

    vv := reflect.ValueOf(&v).Elem()

     

    for i := 0; i < AssignTimes; i++ {

     

    vv.FieldByName("Hp").SetInt(3)

    }

     

    }

     

    func foo(v int) {

     

    }

     

    const CallTimes = 100000000

     

    func TestNativeCall(t *testing.T) {

    for i := 0; i < CallTimes; i++ {

     

    foo(i)

    }

    }

     

    func TestReflectCall(t *testing.T) {

     

    v := reflect.ValueOf(foo)

     

    for i := 0; i < CallTimes; i++ {

     

    v.Call([]reflect.Value{reflect.ValueOf(2)})

    }

    }

    性能试数据

    === RUN TestNativeAssign
    ?PASS: TestNativeAssign (0.03s)
    === RUN TestReflectAssign
    ?PASS: TestReflectAssign (0.41s)
    === RUN TestReflectFindFieldAndAssign
    ?PASS: TestReflectFindFieldAndAssign (9.86s)
    === RUN TestNativeCall
    ?PASS: TestNativeCall (0.03s)
    === RUN TestReflectCall
    ?PASS: TestReflectCall (21.46s)

    试评测

    • 在结构体变量赋值测试用例中, 我们发现TestReflectFindFieldAndAssign赋值格外的耗时. 分析性能点在FieldByNameq个函数? 我们查了下底层如何实现的:

    // FieldByName returns the struct field with the given name

    // and a boolean to indicate if the field was found.

    func (t *structType) FieldByName(name string) (f StructField, present bool) {

    // Quick check for top-level name, or struct without anonymous fields.

    hasAnon := false

    if name != "" {

    for i := range t.fields {

    tf := &t.fields[i]

    if tf.name == nil {

    hasAnon = true

    continue

    }

    if *tf.name == name {

    return t.Field(i), true

    }

    }

    }

    if !hasAnon {

    return

    }

    return t.FieldByNameFunc(func(s string) bool { return s == name })

    }

    各位看官必须吐槽用for来遍历获取数? 但冷静下来分? q样做无可厚?
    试想如果reflect包在我们使用ValueOf时用map~冲好一个结构体所有字D늚讉K数据? 肯定讉K指定字段速度会很?br>但是, 以空间换速度的需求其实最多满了1%的需?
    同样的例子是囑ŞAPI里访问Shader变量的方? L默认使用字符串获? 速度很慢. 当你惛_速访问时, h前按需~存字段
    那么, Golang使用的也是这L思\. 虽然暴力了一? 但是能够让程序跑? 性能优化的东西放在之后来? ~冲下就可以解决

    • 在调用测试用例中, 毫无悬念? 调用速度很慢
      因此, 我们在^时用反时, 量偏向于反变量缓冲存在下的变量赋值或者获?br>而调用的需求尽量减? 如果有goroutine存在的情况下, 则不必太多担?


    战魂筑 2016-08-12 15:26 发表评论
    ]]>
    Google Protobuf 3版本介绍http://www.shnenglu.com/sunicdavy/archive/2016/01/25/212739.html战魂筑战魂筑Mon, 25 Jan 2016 06:23:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/01/25/212739.htmlhttp://www.shnenglu.com/sunicdavy/comments/212739.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/01/25/212739.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/212739.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/212739.html本文~写? Google 官方?protobuf 版本?.0.0beta

    下面介绍下proto3的一些细节变?/p>

    Proto3的语法变?/h1>

    语法标记

    q个版本的protoc的protobuf~译器已l可以支持proto2语法和proto3的语?/p>

    如果你的proto文g没有dsyntax说明的话, 用这个版本的~译器会报错, 提示你默认proto2支持, h加语法标?/p>

    syntax = "proto2";

     

    optional不需要了

    只保留repeated标记数组cd, optional和required都被L?/p>

    实际使用证明, required的设计确实是蛋疼, C++的调试版会弹出assert,release版和optional也没啥区?/p>

    map支持

    map~写格式?/p>

    map<key_type, value_type> map_field = N;
    例如:
    map<string, Project> projects = 3;
    代码生成认支持map, q对于很多语a来说又可以偷懒了

    字段default标记不能使用?/h2>

    位于proto2语法的字Dnumber后的[default=XX]

    q个东西不能用了, 理由?

    对于同一D序列化后的数据, 如果序列化端的default和反序列化端的default描述不一样会D最l结果完全不一?/p>

    ? 同一个数据两个结? q是不可预测的结? 因此q掉q个Ҏ?/p>

    不过本h觉得, 对于游戏来说, q个功能本n可以压羃很多数据,虽然会有隐患

     

    枚D默认g定是0

    proto2里的默认值是枚D的第一个value对应的? 不一定ؓ0

    proto3在你定义value? 强制要求W一个值必Mؓ0

    q个修改为避免隐患还是有帮助?/p>

    泛型描述支持

    anycd, 可以代表Mcd, 可以先读q来, 再进行解? 没具体用, 步子跨大了怕扯到蛋

    支持json序列?/h2>

    q个极好, json再次被同化了

    增加了多U语a支持

    js, objc, ruby, C#{等

    然? C#版本的基runtime库是用C# 6.0的语法写?q对于Unity mono传2.0来说, 实扯到蛋了,没法?/p>

    Protobuf现在使用CMAKE做配|系l?/h2>

    ~译hE微ȝ, q要下个被墙掉的cmake?/p>

     

     

    W三方库里对于proto3的变?/h1>

    Golang的官方protobuf支持: https://github.com/golang/protobuf

    生成代码中的l构体字D늱型变?/h2>

    对于proto2的文? 生成的go代码中的l构体依然用类型指针作为默认存? 兼容老的pȝ

    对于proto3的文? 生成的go代码中的l构体直接用字D作为默认存? 不再使用GetXXX来作为字DD? 赋值时也无需使用proto.cd() 函数q行指针cd字段值创?

    q个调整很是方便, 但丢׃optional判断功能, 对应C++里就是hasXXX的功? 不过好歹q个逻辑现在用的不多?/p>

    q个修改大概也是配合json序列化来做的, go默认的json序列化时, 无法使用proto2生成的结构体? 因ؓ都是指针,无法赋?.

     

    新版protoc-gen-go的插件会生成descriptor的压~数?/h2>

    新插件会l每ơ生成的文gdq样一D代?/p>

    var fileDescriptor0 = []byte{
        // 220 bytes of a gzipped FileDescriptorProto
        0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x8f, 0xcd, 0x4e, 0xc5, 0x20,
        0x10, 0x85, 0x53, 0xbd, 0x35, 0x32, 0xb7, 0xdd, 0x4c, 0x5c, 0xb0, 0x70, 0x71, 0xd3, 0xb8, 0x70,
        0x75, 0x17, 0xfa, 0x04, 0xc6, 0xd8, 0xb8, 0x50, 0x63, 0xa8, 0x2f, 0x80, 0xed, 0x44, 0x89, 0x28,
        0x04, 0xc6, 0xbf, 0x47, 0xf1, 0x6d, 0x95, 0x49, 0x8d, 0x4d, 0x5c, 0x01, 0xdf, 0x39, 0x7c, 0x30,
        0x00, 0x1c, 0x82, 0xdf, 0xc6, 0x14, 0x38, 0xe0, 0xaa, 0xec, 0xbb, 0x37, 0x68, 0x2e, 0x3e, 0x62,
        0x48, 0x7c, 0x49, 0x76, 0xa2, 0x84, 0x47, 0xd0, 0xde, 0x96, 0xf8, 0xee, 0x33, 0xd2, 0x8d, 0x7d,
        0x26, 0x5d, 0x6d, 0xaa, 0x63, 0x65, 0xda, 0xb8, 0x84, 0xd8, 0x41, 0x63, 0xc2, 0x7b, 0xef, 0xc8,
        0x4f, 0x52, 0xda, 0x91, 0x52, 0x93, 0x16, 0x0c, 0x0f, 0x41, 0x89, 0xa9, 0x77, 0x9e, 0xf4, 0xae,
        0x14, 0x54, 0xfc, 0x05, 0xdd, 0x57, 0x05, 0x4a, 0xba, 0xd7, 0xc4, 0x16, 0xb7, 0x80, 0x03, 0x27,
        0xf7, 0xf2, 0x70, 0x72, 0xe5, 0x32, 0x0f, 0xd1, 0x3b, 0xa6, 0x34, 0x5b, 0x31, 0xff, 0x4b, 0x70,
        0x03, 0x6b, 0x43, 0x91, 0x2c, 0x9f, 0x3f, 0xd2, 0xf8, 0x24, 0xf6, 0x7d, 0xb3, 0x4e, 0x7f, 0x08,
        0x0f, 0xa0, 0x3e, 0xf3, 0xce, 0x66, 0xbd, 0x12, 0x49, 0x6d, 0xcb, 0xa1, 0x4c, 0x37, 0xbf, 0xf3,
        0xb3, 0xbc, 0x8e, 0xac, 0x6b, 0xb9, 0xd9, 0xe6, 0x25, 0xbc, 0xdf, 0x93, 0x6f, 0x9e, 0x7e, 0x07,
        0x00, 0x00, 0xff, 0xff, 0x0c, 0x9f, 0x10, 0xa8, 0x2e, 0x01, 0x00, 0x00,
    }

    对于meta信息的提取还是很方便?/p>

    然?/p>

    对于多个文g的生? q样做非常的ȝ, 因ؓq个字段会重复导致编译错?/p>

    很多人在论坛里吐? 官方l出的解x法是, 使用protoc一ơ性传入一个package下的所有的proto直接生成一个go

    而不是现在的一个proto一个go

    生成代码会自动注册到全局, q可以方便的查询

    以前q个代码需要自己来? 现在官方提供了支? 很是方便

    然? Z么不支持遍历?D念? 又要自己动手?/p>

    战魂筑 2016-01-25 14:23 发表评论
    ]]>
    ZProtobuf的电子表格导出器tabtoy开?/title><link>http://www.shnenglu.com/sunicdavy/archive/2016/01/25/212738.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Mon, 25 Jan 2016 06:00:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2016/01/25/212738.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/212738.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2016/01/25/212738.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/212738.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/212738.html</trackback:ping><description><![CDATA[<p>目地址:</p> <p><a title="https://github.com/davyxu/tabtoy" >https://github.com/davyxu/tabtoy</a></p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/212738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2016-01-25 14:00 <a href="http://www.shnenglu.com/sunicdavy/archive/2016/01/25/212738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器开发语a比较http://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.html战魂筑战魂筑Tue, 05 Jan 2016 08:51:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.htmlhttp://www.shnenglu.com/sunicdavy/comments/212611.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.html#Feedback10http://www.shnenglu.com/sunicdavy/comments/commentRss/212611.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/212611.html以下比较的基都是Z一U编E语a+一定的W三Ҏ者自q写的|络库和底层q行的,SkynetE微ҎQ但M比较合适放到比较中?/p>

    C#

    开发效率:Windows下可以通过VisualStudioq行开发,其他q_可以使用MonoDevelopQ非常方?/p>

    q行效率QJIT的性能优化比较CQ能适应90%性能环境

    部v便捷性:可以通过交叉~译生成其他q_的可执行文gQ通过monoq行可执行文?/p>

    调试便捷性:VisualStudio和MonoDevelop调试均很方便Q?q可q程调试

    上手度:对Cp语a熟悉的几天就可上?/p>

    热更斎ͼ可以通过DLL方式q行

    WebҎQ可做,代码比较啰嗦

    崩溃处理Q可通过try catch捕获错误

    |络库编写难度:一般,需注意gc问题

    W三方网l库及框架数量:一?/p>

     

    Golang

    开发效率:?/p>

    q行效率Qƈ发上非常有优势,对CPU利用率比较高Q原生运行无虚拟?/p>

    部v便捷性:一ơ编译到处运行,无Q何运行库依赖

    调试便捷性:实际操作中,单线E挂接调试器可行Q?但变量显CZ正确Q开发期基本采用日志方式q行查错

    上手度:语言单,Ҏ少Q?新手1周能贡献代码

    热更斎ͼ无法q行热更斎ͼ语言无法~译为DLLQ也不支持DLL加蝲Qlinuxq_?so加蝲忽略不计Q?/p>

    WebҎQ非常方便, 代码_

    崩溃处理Q崩溃后以命令行方式打印出栈Q程序内可以捕获M崩溃错误ql运?/p>

    |络库编写难度:单,比C socket更简?/p>

    W三方网l库及框架数量:偏少

     

    Skynet(lua+C)

    开发效率:Z动态语a的开发初ơ写比较快,后期l护和重构会耗费一定的旉在查错上

    q行效率Q基于lua jit的运行效率还是能接受?/p>

    部v便捷性:方便Q?只有底层修改需要重新编译, 大部分时间只用更新lua文g

    调试便捷性:不是很方便,Z日志方式q行查错

    上手度:lua语言Ҏ有部分和Cp语a有一定差异,ZActor模型的思想学习Q适应需要耗费一定的旉

    热更斎ͼcM于ErlangQ可_到函数的热更新

    WebҎQ有一些http支持Q通过C֌慢慢q行完善

    崩溃处理Qlua天生可以捕获错误

    |络库编写难度:自带Q无需~写

    W三方网l库及框架数量:通过C֌慢慢完善

     

    C++

    开发效率:~译慢,文g多,通用库少

    q行效率Qnative速度标杆

    部v便捷性:~写各类的make门槛较高

    调试便捷性:可通过VisualStudioq行Windowsq_调试

    上手度:2~3q经验的熟手仍然会写出崩溃和泄露代码

    热更斎ͼ可通过DLLq行

    WebҎQ代码啰嗦,W三方库?/p>

    崩溃处理QWindows下可使用SEH捕获D异常,其他q_只能通过崩溃后进行coredump分析Q容错非常差

    |络库编写难度:Zasio~写较ؓ单,但M看来隑ֺ不低

    W三方网l库及框架数量:较多

     

    以下是得?/p>

    image

     

    从发文时的项目对q些语言使用率来_JavaQErlangQC++~写的服务器较多QGolangQJavaScriptQC#是第二梯队,Skynet׃上手不是很容易,所以仅有两位数的团队在使用Q但M表现q是比较?

    对于老团队, C++的服务器工具铑֒框架已经相对成熟Q?完全没必要更换新语言Q?只是在对接sdk感觉困难Ӟ可以试Golangq些对web有优势的语言q行混合语言开?

    对于新团队,开发效率,上手度和部v效率是优先选择的,C#QGolangQJavaScriptq些新兴语言会让你事半功?

    对于大规模无需选服的服务器Q?Skynet的actor模型Ҏ展会比较Ҏ

    对于大公司,好项目,上线后需要通过热更新进行bug修补的,C#QC++QErlang会是首?

     

    但ȝ一点, q是Ҏ团队熟悉度来选择语言QN然的使用新语a的风险也是很大的

    战魂筑 2016-01-05 16:51 发表评论
    ]]>
    开源Golang游戏服务器框架cellnethttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.html战魂筑战魂筑Fri, 16 Oct 2015 03:44:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.htmlhttp://www.shnenglu.com/sunicdavy/comments/212026.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.html#Feedback6http://www.shnenglu.com/sunicdavy/comments/commentRss/212026.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/212026.html?方便,高效的Go语言的游戏服务器框架

    func server() {
     
        pipe := cellnet.NewEventPipe()
     
        evq := socket.NewAcceptor(pipe).Start("127.0.0.1:7234")
     
        socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) {
            msg := content.(*coredef.TestEchoACK)
     
            log.Println("server recv:", msg.String())
     
            ses.Send(&coredef.TestEchoACK{
                Content: proto.String(msg.String()),
            })
     
        })
     
        pipe.Start()
     
    }
     
    func client() {
     
        pipe := cellnet.NewEventPipe()
     
        evq := socket.NewConnector(pipe).Start("127.0.0.1:7234")
     
        socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) {
            msg := content.(*coredef.TestEchoACK)
     
            log.Println("client recv:", msg.String())
     
        })
     
        socket.RegisterSessionMessage(evq, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) {
     
            ses.Send(&coredef.TestEchoACK{
                Content: proto.String("hello"),
            })
     
        })
     
        pipe.Start()
    }

     

    目地址: https://github.com/davyxu/cellnet



    战魂筑 2015-10-16 11:44 发表评论
    ]]>
    Golang, Lua, C#闭包变量捕获差异http://www.shnenglu.com/sunicdavy/archive/2015/09/23/211895.html战魂筑战魂筑Wed, 23 Sep 2015 10:31:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/09/23/211895.htmlhttp://www.shnenglu.com/sunicdavy/comments/211895.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/09/23/211895.html#Feedback2http://www.shnenglu.com/sunicdavy/comments/commentRss/211895.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/211895.html看C#例子

                Action[] a = new Action[3];
     
                for (int i = 0; i < 3; i++)
                {
                    a[i] = ( ) => { Console.WriteLine(i); };
                }
     
                for (int i = 0; i < 3; i++){
                    a[i]();
                }

    C#打印l果? 3 3

     

    Golang的例?/p>

        a := make([]func(), 3 )
        
        for i := 0; i < 3; i++ {
            
            a[i]= func( ){
                
                fmt.Println(i)
                
            }    
        
        }
        
        for _, s := range a {
            s()
        }

    Golang打印l果? 3 3

     

    最后是Lua的例?/p>

    a = {}
     
    for i = 1, 3 do
     
        table.insert( a, function()
            print(i)
        end
        )
     
    end
     
     
    for _, v in ipairs(a) do
        v()
    end

    Lua打印l果? 2 3

     

    差异在于, C#和Golang变量捕获到闭包内时, 均用引用方? 卛_最后开始调用用变量时, ׃变量已经l束循环, 所以是最l?/p>

    但是Lua捕获方式是值捕? 因此比较Ҏ理解, 是多就是多?/p>

    战魂筑 2015-09-23 18:31 发表评论
    ]]>
    对golang服务器开发模式的一些思?/title><link>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Wed, 09 Sep 2015 11:06:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/211784.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/211784.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/211784.html</trackback:ping><description><![CDATA[<h1>多线E?同步d模型</h1> <p>在我们的游戏目中用的golang服务器开发方式如?/p> <p>1.多线E逻辑</p> <p>2.同步d. 也就是说, 每个Z个线E?goroutine), ioU程=逻辑U程</p> <p>q种方式的优?</p> <p>1. 同步d方式与h的思维方式cd</p> <p>2. 逻辑处理性能有一定提?/p> <p>在大规模使用q种模式~写逻辑? 我们发现了这U模式只?个缺? <strong>~写者需要处理多U程关系</strong></p> <p>但这本n实直接致命? 回想C++时代, 多线E处理时, 调试重现的困䏀?脑补景象太惨不敢直视</p> <h1>单线E?异步多进E模?/h1> <p>在C++时代, 我曾l编写过一套asio的C++服务器框? 采用io多线E? 逻辑单线E? 依赖着C++高性能的优? 让开发便L单且无需兛_U程问题.</p> <p>那么Cgolang时代, Z么不能试下单U程异步多进E方式来~写逻辑?</p> <p>与多U程同步dҎ? 我们发现, 两者优~点互补. 那这回C领域选型问题? 对于游戏服务器需要的上手? 开发便? 压力降低(非MMO)q些特点来说, 单线E异步多q程再合适不q了</p> <p>那么, 我们在用golang~写单线E异步多q程服务器应该注意哪些点?</p> <p>1. socket处理完全装, 只通过channel抛出到逻辑U程排队处理</p> <p>2. 数据? rpc及其他io处理, 一律改为异步回调模? 不用同步接?/p> <p>3. 玩家存盘提交数据可以考虑复制q提交到存盘U程方式, 提高性能. </p> <p>4. 采用多进E架? 比如讄兌E? 把io压力分散到进E中</p> <p>5. 逻辑~写? 不允怋用go开U程及channel, 有需要提高性能部分需要单独编?/p> <p> </p> <h1>Actor模型的痛</h1> <p>cellnet在开发时本来考虑使用actor模型来进一步简化多U程逻辑的麻? l历了一D|间的原型开发后, 发现了一些问? 列D如下:</p> <p>1. golang的强cd不适合actor模型q种l常需要动态生成各cL息的模型, 但skynet(C+lua)/erlang有天生优势</p> <p>2. actor模型本n不是万能? 不能解决所有需? 特别是游?/p> <p>3. actor模型理解到应用有一定的隑ֺ. 本nq需要搭建框? 上手复杂</p> <p>M, 看过一些erlang及skynet的用? 没有应用的很U正且成熟的成功actor模型案例, 从传lsocket服务器框架跨到actor模型会扯到蛋, 因此, 后期cellnet会考虑回归到成熟的socket服务器框? 把架构做到简单上? 高扩展上.</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/211784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2015-09-09 19:06 <a href="http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大服务器架构讨论http://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.html战魂筑战魂筑Tue, 21 Jul 2015 02:30:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.htmlhttp://www.shnenglu.com/sunicdavy/comments/211321.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.html#Feedback8http://www.shnenglu.com/sunicdavy/comments/commentRss/211321.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/211321.html最q参加了一个大服务器架构讨论活? 记录下心?

    概述

    游戏客户端采用Cocos2dx-Lua的纯Lua~写逻辑, 服务器采用Golang作ؓ开发语a

    游戏cdcM于COC,因此无需选服. 需要用大服务器架构进行处?

    数据?/b>

    采用Mongodb做持久存? redis做跨服通信数据交换

    使用UCloud的云技? 省去了烦人的q维工作

    通信及协?/b>

    客户端和服务器通讯使用HTTP短连? Zjson的数据封包协?

    服务器间大量使用Golang自带的json+rpcq行通信

    服务器类?/b>

    服务器类型大致分为逻辑服务?战斗服务? 中心服务?

    逻辑服务?/b>

    逻辑服务器负责日帔R辑及公共逻辑处理(好友, 公会)

    1个逻辑服务器对应一个区, n个区均用Ucloud云Mongodbq行数据存储

    战斗服务?/b>

    战斗服务器是一个集? 集群会返回一个负载最低的服务器返回?

    战斗服务器通过cgo技术与客户端C++/lua的战斗逻辑q行逻辑复用, 在此技术上q行

    战斗逻辑的校?

    中心服务?/b>

    客户端登陆前, 在中心服务器q里获得可登陆的逻辑服务器地址, 同时做一个负载均?

    短连?

    评h

    ׃操作pȝ的技术趋于稳? 同时, 手游的弱交互型导致的游戏架构于? 因此|络负蝲不再是游戏服务器技术的瓉. 从经验看? 游戏服务器技? 更重要的是还是看数据库的选型及处理方? 

    虽然Mongodb的性能上不如内存数据库. 但是从存储安全性上要比个h搭徏的内存数据库? 安全

    外加上云技术的引用, 性能的瓶颈和q维的技术复杂度q刃而解

    Redis用于跨服数据交互那是再好不过的数据中介了, 保证速度和稳定? l对不是造轮子能比拟?

    短连接在手游上处理v来比长连接简单一? 无需做断UKq? 服务器的底层也是由Golang的框架库保证质量? 因此负蝲毫无问题. 服务器对内及对外均用jsonq行数据交换, 化了协议处理. 也方便了调试

    json rpc的性能损耗对于整个逻辑的处理来说均可以忽略不计



    战魂筑 2015-07-21 10:30 发表评论
    ]]>
    我的Golang全接?/title><link>http://www.shnenglu.com/sunicdavy/archive/2015/06/04/210823.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 04 Jun 2015 09:19:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2015/06/04/210823.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/210823.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2015/06/04/210823.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/210823.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/210823.html</trackback:ping><description><![CDATA[<p>满打满算, 从好友推荐Golang臛_文时, 使用Golang已经?q多? q种旉对于C/C++ Javaq些老者来? 直是菜鸟U别的经?/p> <p>但作为新生代语言的特点就是实? Golangq一q里, 已经为项目提供了E_的服务器和强大的扩展能力, 与客L的Unity3D里的C#一? 都是强大, 极致开发效率代表的优秀开发语a.</p> <h2>用途篇</h2> <p>Golang到底拿来做啥? 我需要么?</p> <p> 高效(性能,开?的服务器语言. 包括Web, 游戏, App</p> <p>~写桌面UUI暂不是很适合</p> <p>我需要把现在的C++, Python, Erlang{服务器ҎGolang?</p> <p>性能有瓶? 开发效率低, 有钱有时间的? 完全可以</p> <p> </p> <h2>评h?/h2> <p>听过太多的h对Golang的评? 大概分ؓq么几类: </p> <h3>C/C++性能?/h3> <p>此类党员对Q何事物都q求极致?性能. q好Golang是直接生成native code, 否则会被批的体无完肤. 但是׃Golang底层为ƈ发和开发效率而做出的一些系l? cM于GC, 调度器和分配器等, 会在语言层上损失很多性能. 因此C/C++党还是有理由批Golang性能低下</p> <h3>Erlangq发?/h3> <p>作ؓ电信U元? Erlang的模型和架构当之无愧, OTP扩展性超U强. 完美的Actor模型也让逻辑~写比OO更加直观</p> <p>CSP与Actor区别仅仅只是在channel的归属范围而已, 但这点细微差别却对两U语a的开发变的E然不?/p> <p>Golang在ƈ发模型上选择了CSP, 是考虑把架构的设计留给使用? 像C#一样徏立一个类库的世界, 而不是MFC一L框架世界. 让开发更自由</p> <p>Erlang的Actor也没? 让开发更直观, 让崩溃提前来? 快处理</p> <h3>Rust?/h3> <p>Rust在发文时已经发布?.0. q让R_兴奋的I梭于各大技术论坛和讨论?/p> <p>但Rust的理念在我看来有点偏执了, 一定要把各U错误在~译期暴露出? 所以造出了很多不需要的cd和概? q语a都比C语言更符可</p> <p>大白话说? 有点~程l验的h看到JavaScript完全看得? 但看Rust却像天书</p> <p>Ҏ同时期的TypeScript, Dart, Swift. Rust是有点那么独辟y径</p> <p>该党党员l常性的用各U特性对比Golang, q求单特性的优秀. </p> <p>但其? Golang本n是一门完整哲? 很多语言Ҏ互怹间有兌. 有设计不当的地方, 当然更多的是完整体系. 不求和其他语a?/p> <p>只追求解决问题的速度</p> <h3>自定义党</h3> <p>云风看过Golang? 因ؓ该语a本n是强化版的C, 因此颇受云风喜欢. 但在一堆评价后, 云风q是果断选择了C+lua的组合写出的Skynet</p> <p>虽然不知道原? 但我猜的? 毕竟是对语言本n的可控性还不那么看?/p> <p>同时, 我们发现Skynet使用的是Actor模型, 也发现大的程序员是有先? </p> <p><font style="background-color: #ffffff" color="#ffffff">转蝲h? 战魂筑</font><a title="http://www.shnenglu.com/sunicdavy" href="http://www.shnenglu.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.shnenglu.com/sunicdavy</font></a></p> <h2>感触?/h2> <p><strong>设计</strong></p> <p>t入Golang, ׃要尝试设计模?/p> <p>传统的OO在这里是非法? 试模拟只是一U搞W?/p> <p>把OO在Golang里换成复?接口</p> <p>对实现者来? 把各U结构都复合h, 对外暴露Z个或多个接口, 接口好像用者在实现模型上打出的很多z?/p> <p>别怕全局函数, ?Package)可以控制全局函数使用范围. </p> <p>没必要什么都用interface对外装, struct也是一U良好的装Ҏ</p> <p>Golang无? 因此无需cL生图. 没有zq种点对点的依赖, 因此不会在大量类关系到来? 形成J杂不可变化的树形结?/p> <p> </p> <p><strong>容器</strong></p> <p>用了很长旉map, 才发现Golang把map内徏aҎ时, 已经L了外|型map的apiҎ? 一切的讉K和获取都是按照语aҎ来做的, 原子?/p> <p>数组可以理解为底层对? 你^时用的都是切? 不是数组, 切片是指针, 指向数组. 切片是轻量的, 即便值拷贝也是低损耗的</p> <p> </p> <p><strong>内存</strong></p> <p>Golang在实际运行中, 你会发现内存可能会疯? 但跑上一D|间后, ׃持稳? q和Golang的内存分? 垃圾回收有一定的关系</p> <p>C的编E语a的内存管理不会很_暴的直接从OS那边分配很多内存. 而是按需的不断分配成块的内存. </p> <p>对于非v量应用, Golang本n的内存模型完全可以撑得下? 无需像C++一? 每个工程必做内存池和U程?/p> <p><strong>Channel</strong></p> <p>Channel和锁谁轻? 一句话告诉? Channel本n用锁实现? 因此在迫不得已时, q是量减少使用Channel, 但Channel属于语言层支? 适度使用, 可以改善代码可读?/p> <p><font style="background-color: #ffffff" color="#ffffff">转蝲h? 战魂筑</font><a title="http://www.shnenglu.com/sunicdavy" href="http://www.shnenglu.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.shnenglu.com/sunicdavy</font></a></p> <p><strong>错误</strong></p> <p>觉得Golang不停的处理err? 那是因ؓqx在其他语aҎ没处理过错误, 要不然就是根部一ơ性tryq所有的异常, q是一U危险的行ؓ</p> <p>panic可以被捕? 因此~写服务器时, 可以做到不挂</p> <p> </p> <p><strong>危险的interface{}</strong></p> <p>q东西就跟C/C++里的void*一L危险, nil被interface{}包裹后不会等于nil相等, 但print出来实是nil</p> <p>模板估计可以解决容器内带interface{}的问? 但新东西引入, 估计又会让现在的哲学一些凌?/p> <p> </p> <p><font style="background-color: #ffffff" color="#ffffff">转蝲h? 战魂筑</font><a title="http://www.shnenglu.com/sunicdavy" href="http://www.shnenglu.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.shnenglu.com/sunicdavy</font></a></p> <p> </p> <h2><strong>初学Tips</strong></h2> <p>语言学习按照官网的教学走, 跑完基本׃?/p> <p>下蝲一个LiteIDE, 配合Golang的Runtime,基本开环境有?/p> <p>Golang的类库设计方式和C#/C++都不? 如果有Pythonl验的会感觉毫无q和?/p> <p>有一万个理由造轮子都请住? cd里有你要的东?/p> <p>写大工程h? <a name="688">Golang目目录l构l织</a></p> <p>Golang语言本n本h没有发现bug, 即便有也早就被大们捉住? 唯一的一个感觉貌似bug? l常是结构体成员首字母小? 但是json又无法序列化出来?/p> <p> <p><a name="688">慎用cgo. 官方已经声明未来对cgo不提供完整兼Ҏ? M一门语a在早期都需要对C做出支持, 但后期完善后的不兼容都是常?/a></p> <p> </p> <p><font style="background-color: #ffffff" color="#ffffff">转蝲h? 战魂筑</font><a title="http://www.shnenglu.com/sunicdavy" href="http://www.shnenglu.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.shnenglu.com/sunicdavy</font></a></p> <p> </p> <p><a name="688"> </p></a><img src ="http://www.shnenglu.com/sunicdavy/aggbug/210823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2015-06-04 17:19 <a href="http://www.shnenglu.com/sunicdavy/archive/2015/06/04/210823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>golang的time.Format的坑http://www.shnenglu.com/sunicdavy/archive/2015/03/26/210173.html战魂筑战魂筑Thu, 26 Mar 2015 09:23:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/03/26/210173.htmlhttp://www.shnenglu.com/sunicdavy/comments/210173.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/03/26/210173.html#Feedback1http://www.shnenglu.com/sunicdavy/comments/commentRss/210173.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/210173.htmlgolang的time.Format设计的和其他语言都不一? 其他语言L使用一些格式化字符q行标示, 而golang? 查了|上一些坑例子 自己查了下golang的源? 发现以下代码
    // String returns the time formatted using the format string
    //  "2006-01-02 15:04:05.999999999 -0700 MST"
    func (t Time) String() string {
        return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
    }
    

    试?006-01-02 15:04:05写入到自q例子?pre>func nowTime() string { return time.Now().Format("2006-01-02 15:04:05") }

    l果q回正确. 询问了下, 据说q个日期是golang诞生的日子?咋那么自恋呢?

    战魂筑 2015-03-26 17:23 发表评论
    ]]>
    ƷŮͬþþþõӰԺ| þ91ۺϹ91þþƷ| 91þ㽶Ů߿| ۺҹҹþ| þ޹ӰԺվ| LƷþ| þseƷһƷ| Ʒþ99| þ99Ʒþ99ý | ձþþþƷĻ| պ뾫Ʒþһ| þùֱ| þAVһ| þAVĻ| ŷպƷþþѹۿ| 2021¾þþӾƷ| ĻþòҰav| ˾þþƷһ| 99þֻƷ| þþûɫƬ| þþƷav鶹ɫ| Ʒþþþ㽶| ݺݸɺݺݾþ| ۺۺϾþ69| þþþþ޾Ʒ| þҹɫ˾ƷС˵| ɫþþþþþС˵| þɧ| ĻƷѾþ5151 | Ʒþþþù3d| þAVij| þ99Ʒþþþ| 99ȾþֻоƷ68| ֻƬþøպ | þ99ȾƷ| պvavaŷvaþ| þþ뾫Ʒպ˳| ˾þþƷһ| þþƷһapp| þɧ| ŷƷרþ|