未分类

macbook pro 手动换电池

由于自用的macbook发现底部不平,猜测应该是电池鼓包了。。。可是当时我的循环次数是70+而已。。。。费解。。。

赶紧自己淘宝买一个1502【这是我笔记本的型号,底部可以看到】型号的电池

当晚回家后,当时查了下,发现要撬棒,我没有。。。。。看了下作用,我觉得自己指甲能解决了。。。。就二话不说开撸了。

 

步骤如下:

准备工具,两个小螺丝刀【苹果macbook拆机专用的五星螺丝刀,一个信用卡之类的东西】

一个买好对应型号的电池

 

开拆:

螺丝有点多而且小,一定要放好,不然丢了挺尴尬的。。。

拆开后是这样的。。。。鼓包确实很严重,胖了啊。。。。

 

 

等等。。。那电池板上面的bar带是怎么回事?别人拍出来的好像没有的啊T.T

 

看着它绑着电池板的样子,有点慌。。。。

研究了大半天,实在是太精密了,基本上没缝隙可以看到,而且上面还加了外壳。。。不管了,先拆一个看看。。。

 

事实证明我是对的,拆了后就可以拔出这个bar带

 


 

接着就看到整个电池了,第一次拆,也是各种瞄,尽可能看懂它的结构。【它右上角就是靠近电池的排线的地方有个螺丝要拧开】

 

其实是看不出来下面的结构的,当时电池是纹丝不动在哪里,我徒手尝试解锁多种姿势,都没搞出来。

之前看过手机店换iphone手机电池,他们里面是有双面胶不粘住电池的。我估摸着要也是,去看新电池发现就是这样的

那只能大力出奇迹了。。。。徒手试了很多次,没法下手

想了下用信用卡之类的东西嵌进去试,发现是可行的

 



 

 

 

 


 

终于拆出来了,还是麒麟臂厉害

 

 


拆出来了就比较下新旧电池的差异了

新电池厚度

旧电池厚度

所谓没有对比就没有伤害。。。。88vs167,感受下来自胖子的2倍暴击

清理残留的胶布后


剩下就是顺理成章放上新的电池了,没什么难度了

 

把bar带扣回去,然后装上螺丝和那个小小的外壳罩

确认装好了,就接上电池的排线,这样就可以给主板供电了

 

 

 

 

 

 

 

装好后全景图,美滋滋

 

顺利点亮

 

ps:

以外收获是发现是可以换ssd的。。。。。很开心的淘宝各种找。。。。看了ssd的价格: 512G的要2300.。。。。。。。。1T的ssd的价格4k多。。。。滚烫的心都凉了。。被冻伤了。。。。。要不起要不起。。。。突然感受到暴击。。。。

小白组anemos折叠车的全过程

背景:

有两台车,rhine和1403,rhine由于轴距不适合,骑起来有点不爽,还有闲置了DA9100套件想用起来。

最初计划如下:

    1. 新买一个18寸的折叠车架,组成弯把折叠车【主要是rhine车现在用的18寸轮组很不错,不想丢弃,所以想置换过来】
    2. rhine的所有配件都迁移到新的车架去
  1. 1403上的da9100的牙盘也置换到新车架去,rhine的birdy牙盘放到1403去
  2. 把自己闲置了一年的da9100前拨后拨手变都用在新的车架上

然后开始折腾了。

车架(经过淘宝一波骚操作,选了anemos的18寸车架YQ,红色。颜值不错)

线管和线芯(这个买的时候有个小插曲,线管单位2表示2米,我以为是2条。怒买12个,以为是买了12条。结果到手4根,长短不一。一顿迷惘。赶紧在回家的路上去厂里【广州梦工场】充值两根线)

弯把uno的40

6800的夹器(这个失误了,当时没看到有r8000的只差50元)

5700直锁前拨(这个本来有9100的前拨的,但是店家说装不上r8000也说装不上。然后钦点了个5700的直锁前拨。由于5700前拨存量不多,各种找才找到一家,还是我不喜欢的银色。忍忍也买了。后来自己用9100给装上去了。蜜汁尴尬。。。白瞎了我一顿找买下5700直锁前拨了。)

 

 

过程【多图提醒】:

红色的链条是给单速412用的。弯把,线管,前拨到了。

车架到了,拆箱。

颜值不错,美滋滋。。。。

边看世界杯边改车,本以为是很惬意的,没想到组车出了特别多问题。

开始拆上海鸟的birdy轮组,链条,后拨。。。然后发现顺序搞错了。。应该要先拆da牙盘的。。尴尬。。。

赶紧过去开始拆1403的da牙盘中轴

不熟悉工具,看了下这几个东西,试了个遍都不对。

原来是这个。。。顺利拆出来了。。。

开始上中轴,这里有个小插曲。由于拆中轴夹在修车架的时候,1403方向和anemos的方向反的。我没留意,直接就按照记忆上中轴了。。。

这是拿了右边的中轴上到车架左边去了,然后发现分外难拧进去,然后跟店家沟通了,店家说铣牙。当时老条提示过我有没有上反了,我断定没有。因为刚从车架拆出来,但是忘了两车架的方向不一样啊。。。


找了个遍没看到有洗牙工具,店家说我没有。

然后我就上油硬上去,日常练好的麒麟臂此刻展示了威力了,成功拧上去。换另一边的时候突然发现我刚才上反了!!!!!

心疼我的车架,估计刚才车架是这种感觉。

赶紧默默的退了出来,退的过程也是分外的艰难,进去有多艰难出来就用多痛苦了。然后顺利装好牙盘后拨。

接着是头管了,头管店家帮我压好了的。这个作为小白的我确实不会。跟店家直接沟通,最后知道了头管里面的培林吊心的安装顺序。顺利安装好

接着就准备上轮组了,结果发现上海鸟的轮组的开档是100/130,而anemos的yq的开档是74/100.尴尬。。。。



只能先装成这样了。。。

赶紧闲鱼一对轮组。。。

轮组隔天中午卖家就自己骑着小布从白云区送过来了,壕气掩盖不住啊。这是体验生活的赢家啊。。羡慕并感谢。。

轮组到手

发现没快拆,又赶紧闲鱼一对快拆,因为是晚上八点了,卖家肯定不快递了。我急着用,就让美团跑腿,九点就到了。。快拆买了20元,这跑腿就18了。。。



开始装前拨,由于店家是说9100装不上,所以我直接就用5700了,但是不死心,用9100前拨试了下,发现9100居然能装的。。。当时心情是复杂的。

装轮组


然而世界对于小白是不友善的再次验证。

前叉不太对,锁紧就成这样了。直接刹胎皮了啊。。。赶紧淘宝店家问情况。经过一轮沟通,原来是店家做错了前叉啊。蜜汁尴尬。。。


再次等合适的前叉。。。。装车暂停。。。基本大局已定的样子。。。

想起卖家说轮组漏气,隔天看了下真漏气了,就用卖家送的内胎自己换胎。没想到在这里再次翻船了。这个胎紧,直接搞断了我两根塑料撬胎棒和以及pt的撬胎棒蹦了个扣子。。。在我心中pt的工具王者形象瞬间就跌落神坛。。。。

挣扎得换好内胎,看着三根烂了的撬胎棒,心情复杂。。。

前叉隔两天顺丰到了。

发现做工不是特别细致,垫圈压不下去。有凸起的一块。

这难不倒哥,火速下楼买了锉刀,顺便买了把钢锯。原计划是要去车店锯坐杆的。。这下有工具就顺便自己锯了。

一切看起来再次尘埃落定了。。。

开始准备缠把带了。人生第一次。看了各种资料,准备好工具。开搞。

缠出来的结果有点惨不忍睹了。。。由于我搞错了垫片,把长的贴纸当成了拐弯处的垫片了。垫进去后就分外的薄。。。。导致拐弯处有大窟窿。。。还好我colnago的把带贴纸还在,否则封口那里就只能用我那个无牌的电工胶布了。。。最后定妆,我不管我不管我不管,就是好看好看很好看,亲生的亲生的亲生的。。。

变速老条协助下勉为其难得调好了后拨。但是前拨调不好。大晚上的赶紧趁闪电没下班,杀过去让技师帮忙调好。。。。。尴尬。。。。

效果如图,看起来美滋滋了。。。。店家批评说我手变角度奇特,我瞄了下确实低了。。。怎么看都不对啊,我参考的是公路车的手变角度。。。

最后发现,我看的是sram的手变,它小一些。。。。参照物不一样,角度也不同了。。。。。尴尬。。。。但是我没去调了,还要重新缠把带,这个接受不了了。。。。。就这样吧。。。。


骑了一天,发现头管是松动的,问店家说头管要用两个夹器,配少了个。

赶紧去车店搞,由于头管夹有个坐,塞不进头管。。。瞄了下,用锉刀挫平。。在马路边挫了半小时才搞定。。。最后就稳稳得了。。。

最后定妆图。。美滋滋。。

由于多出了对轮组,还是喜欢黑边的轮组。就找了淘宝改轮组的店家,快递过去改了旧轮组的轴心,后轮改轴重新调圈。

换轮组换飞轮。。。重新搞

最后定妆。。。。。。折腾了快两周了

 

再次充值了下信仰,补了条颜值高的链条,黑钻【红黑】

 

 

到货后10分中装上,定妆,自我感觉良好中。。。

 

 

 

制作mac启动u盘Sierra

  1. 用appstore搜索 macos ,然后下载
  2. 用磁盘工具格式化你的U盘,macos扩展格式
  3. 下载好了执行下面的命令,其中/Applications/Install\ macOS\ High\ Sierra.app 【表示下载的系统文件,看你下载的是什么版本】,/Volumes/Sierra【是你的u盘的盘符对应的路径】

bash

sudo /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/createinstallmedia --volume /Volumes/Sierra --applicationpath /Applications/Install\ macOS\ High\ Sierra.app --nointeraction

等命令完成了,启动盘就做好了

极路由的ss插件配置

  1. 安装开发者插件:“云插件”>“全部插件”>“开发者模式”>”确定”。

ssh登录路由器

然后执行以下命令安装:

然后在路由器后台可以看到一个 安全上网 的新菜单,自己研究吧

phpstorm配置sass编译scss文件

由于项目使用了sass作为css的预编译。然后自己又得配置一番。

 

我们项目是style.scss 编译成 style.min.css。

祭出配置:

Program:【ide自己找的】

scss

Arguments:

 

参数说明:

 

 

遇到的问题,需要安装ruby,gem,sass。

 

需要配置file watcher

看上图

需要使用压缩

 

需要了解sass的编译语法

不想生成map文件

 

 

phpstorm使用file watcher配置stylus

背景:

项目有使用stylus,经常要手动编译成css,其实挺麻烦的。后来发现ide本身有个file watcher可以完成自动编译功能。这教程适合其他修改后立即要编译的程序,入sass之类的。

废话不说,直接祭出配置

 

Program:【这里指定在项目里面的stylus,需要在项目npm install后才有】

Arguments:

参数解释:

 

 

中间遇到几个问题

  1. stylus版本问题【由于开发环境是docker容器,宿主和container的node的stylus版本可能不一致】
  2. file watcher和stylus 的-w参数冲突问题
  3. stylus依赖的node包的可能不一致
  4. 压缩功能
  5. file watcher参数配置

 

由于容器和宿主的node的环境不一致,当时产生了莫名其妙的错误。

node和stylus的版本折腾成一致后,发现老找不到bid包,然后又一顿搜索,发现是引入包的问题,其实还是node版本的问题,然后用stylus -I 指定包目录解决。

压缩需要使用stylus –compress 参数

后来又发现ide的file watcher貌似不会结束,一直在进行中,看了下。然后懂了,网传的 -w参数是stylus自带的监听文件变更,他的功能跟file watcher是一样的,去掉就好了。

 

终于可以用了。顺便吐槽下nodejs的报错,牛头不对马嘴的感觉。。。。参数配置错了,说语法错误。。。尴尬。。。。找不到包,也说语法错误,”期待缩进,但是出现;”,这句把我没写过nodejs的人坑的非常惨烈,一直轻信node的报错,各种找语法,还去修改官方的包。。。特别惨。。。

修复docker的终端命令自动截断

用cli命令进入docker容器后,发现在终端输入长一些的字符串会被截断,有种蛋蛋的忧伤。。。。

原因是容器不知道它所处的终端的大小,所以默认初始终端的尺寸是0 0,迷之尴尬。。。大家可以执行以下命令确认:

 

最后解决方式,在进入容器后执行一条命即可:

 

最后完美解决:

可用的做法:
1. 在/etc/bashrc 加入 reset -w

2. 在Dockerfile挂一个启动脚本 ENTRYPOINT [“/start.sh”] , 里面附带 reset -w

3. 进入容器的时候设置:

 

骑车感悟T.T

34+的休闲骑是不可能骑的,我这辈子也不可能跟你们去34+的休闲骑的,跟风又跟不上,只能掉下来收尾,发完朋友圈就闪现往回跑这样子。队友说很久没骑车了,发车后就开尾灯让我赶紧追,反正我每次一掉就有队友说前面没有坡拐个弯就到了!

【转发】Go 语言机制之栈和指针

简介

我不打算说指针的好话,它确实很难理解。如果应用不当,会产生恼人的 bug,甚至会导致性能问题。当写并发和多线程程序时更是如此。所以许多语言试着用其它方法让编程人员避免指针的使用。但如果你是在用 Go 语言的话,你就不得不使用它们。如果不能很好的理解指针,是很难写出干净、简单并且高效的代码的。

帧边界(Frame Boundaries)

帧边界为每个函数提供了它自己独有的内存空间,函数就是在这个内存空间内执行的。帧边界除了可以让函数在自己的上下文环境中运行外还提供一些流程控制功能。函数可以通过帧边界指针直接访问自己帧边界中的内存,但如果想要访问自己帧边界外的内存,就需要用间接访问来实现了。要实现间接访问,被访问的内存必须和函数共享,要想弄清楚共享是怎么实现的,我们就得先了解一下由这些帧边界建立起来的内存结构以及其中的一些限制。

当一个函数被调用时,会在两个相关的帧边界间进行上下文切换。从调用函数切换到被调用函数,如果函数调用时需要传递参数,那么这些参数值也要传递到被调用函数的帧边界中。Go 语言中帧边界间的数据传递是按值传递的。

按值传递的好处是可读性好,拷贝并被函数接收到的值就是在函数调用时传入的值 。这就是为什么我把按值传递叫做 WYSIWYG(what you see is what you get 的缩写)。如果发生上下文环境转换时参数是按值传递的,我们就可以很清楚的知道这个函数调用会怎样影响程序的执行

让我们看一下下面这个小程序,主程序用按值传递的方式调用了一个函数:

清单 1

程序启动后,语言运行环境会创建 main goroutine 来执行包含在函数 main 内的所有初始化代码。goroutine 是被放置在操作系统线程上的可执行序列,在 Go 语言的1.8版本中,为每一个 goroutine 分配了 2048 byte 的连续内存作为它的栈空间。这个初始化的内存大小几年来一直在变化,而且未来很有可能继续变化。

栈在 Go 语言中是非常重要的,因为它为分配给每个函数的帧边界提供了物理内存空间。main goroutine 在执行表 1 中的代码时,goroutine 的栈看起来像下面这个样子(在一个比较高的语言层次)

图 1

在图 1 中可以看到,一部分栈空间被框了起来,作为函数 main 的可用空间,这块栈区域叫做「栈帧」,正是它界定了函数 main 在栈上的边界。这块栈空间是在函数被调用后,随着一些初始化代码的执行一并被创建的。可以看到变量 count 被放置到了函数 main 的栈帧中地址为 0x10429fa4 的地方。

在图 1 中也可以发现另外一点,就是在活动栈帧之下的栈空间是不可用的,只在活动栈帧以及它之上的栈空间是可用的。这个可用栈空间与不可用栈空间的边界我们需要明确一下。

地址

变量名是为了标识一块内存,使代码更具可读性而存在的。一个好的变量名可以让编程人员清楚的知道它代表了什么。如果你已经有了一个变量,那在内存中就有一个值与它对应;反之,如果在内存中有一个值,就必须有一个与之对应的变量,通过这个变量来访问这个内存值。在第 9 行,主函数调用了内置函数 println 来显示变量 count 的值和地址。

清单 2

用 & 操作符来获取变量的地址并不新鲜,许多其它语言也同样用这个操作符来获取变量地址。如果你在 32 位机器上运行这段代码(例如 playgournd ),第 9 行的输出应该像下面这样。

清单 3

函数调用

接下来第 12 行,函数 main 调用了函数 increment:

清单 4

函数调用意味着 goroutine 需要在栈空间中创建一个新的栈帧。然而,这里并没有这么简单。要成功的调用一个函数,需要将数据在上下文转换过程中跨栈帧边界传递到新建的栈帧中。特别的,对于 integer 值,在调用过程中需要拷贝并传递过去,在第 18 行对函数 increment 的声明语句中可以看到这一点:

清单 5

如果再看一下第 12 行对函数 increment 的调用,可以看到传递的正是变量 count 的值。这个值经过拷贝、传递并最终放置到了函数 increment 的栈帧中。因为函数 increment 只能直接访问自己栈帧里的内存,所以它用变量 inc 来接收、存储和访问从变量 count 传递过来的值。

在函数 increment 刚刚要开始执行的时候,goroutine 的栈结构看起来像下面这个样子(从一个比较高的语言层次)。

图 2

可以看到,现在在栈里有两个栈帧, 一个是函数 main 的,它下面的是函数 increment 的。在函数 increment 栈帧里,有一个变量 inc,它的值是当函数调用时从外面拷贝并传递过来的 10,它的地址是 0x10429f98,因为栈帧是从上往下使用栈空间的,所以它的地址比上面的小,不过这只是一个实现细节,并不保证所有实现都这样。重要的是 goroutine 把函数 main 的栈帧中的变量 count 的值拷贝并传递给了函数 increment 的栈帧中的变量 inc。

函数 increment 剩下的代码显示了变量 inc 的值和地址:

清单 6

在 playground 平台上,第 22 行的输出看起来像这样:

表 7

当执行完了这些代码以后,栈结构变成下面这个样子

图 3

执行完第 21 行和第 22 行以后,函数 increment 返回,控制权重新回到了函数 main 中,然后函数 main 再一次显示了变量 count 的值和地址:

清单 8

在 playgournd 平台上,程序全部的输出如下:

清单 9

函数返回

当函数返回,控制权回到调用函数后,栈结构发生了什么变化呢?答案是什么也没有。下面就是当函数 increment 返回后,栈结构的样子:

图 4

除了为函数 increment 创建的栈帧现在变为不可用外,其他和图 3 一模一样。这是因为函数 main 的栈帧变成了活动栈帧。对函数 incrment 的栈帧没有做任何处理。

函数调用完成后,没有必要立即清理被调用函数的栈帧空间,这样做只会浪费时间,因为你不知道那块内存之后是否会被再次用到。所以相应内存就原封不动的留在那里。只有当发生了函数调用,这块内存被再次用到时,才会对它进行清理。清理过程是通过拷贝过来的值在这个栈帧中的初始化完成的,因为所有的变量至少会被初始化为相应类型的零值,这就保证了发生函数调用时,栈空间一定会被合理的清理。

值的共享

但是如果我们想在函数 increment 中直接操作存在于函数 main 的栈帧中的变量 count,应该怎么办呢?这时候我们就要用到指针了。指针存在在目的就是为了和一个函数共享变量,从而让这个函数可以对这个共享变量进行读写,即使这个变量没有直接放置在这个函数的栈帧中。

如果当你用指针时,一下子想到的不是「共享」,那就得看看是不是真的有必要使用指针了。当我们学习指针的内容时,有一点很重要,就是要用一个明确的单词而不是操作符或者语法来对待指针。所以请记住,用指针是为了共享,在阅读代码的时候也应该把 & 操作符当做共享来看。

指针类型

对每个已经声明的类型,不管是语言自己定义的还是用户定义的,都有一个与之对应的指针类型,用它来进行数据共享。比如 Go 语言中有一个内置的 int 类型,所以一定有一个与 int 类型对应的叫做 *int 的指针类型。如果你定义了一个叫做 User 的类型,那么语言会自动为你生成一个与它对应的叫做 *User 的指针类型。

所有的指针类型有两个共同点。一、它们以 * 开头。二、它们占用相同的内存大小(4 个字节或者 8 个字节)并且表示的是一个地址。在 32 位的系统上(比如 playground ),一个指针占用 4 个字节,在 64 位的系统上(比如你自己的电脑)占用 8 个字节。

规范一点说,指针类型被认为是一个字面类型(type literals),也就是说它是通过对已有类型进行组合而成的。

间接内存访问

看下面这段程序,它同样调用 了一个函数,不过这次传递的是变量的地址。这样被调用的函数 increment 就可以和函数 main 共享变量 count 了:

清单 10

同原来的程序比起来,新的程序存在 3 点不同

表 11

在程序的第 12 行,并没有像之前一样传递变量 count 的值,而是传递的变量 count 的地址。现在我们可以说,我将要和函数 increment 共享变量 count 了,这就是 & 操作符想要表达的。

变量仍然是按值传递的,唯一不同的是,这次传递的是一个 integer 的地址。地址同样是一个值;这就是在函数调用时跨越两个帧边界被拷贝和传递的东西。

鉴于有一个值正在被拷贝和传递,在函数 inrement 中我们就需要一个变量来接收并存储这个基于地址的 integer 值,所以我们在程序的第 18 行把参数声明为了 *int 类型。

表 12

如果你传递的是 User 类型的地址值,这里声明的类型就应该换成 *User,尽管所有的指针存储的都是地址值,但是传递和接收的必须是同一个类型才可以,这个是关键。我们之所以要共享一个变量,是因为在函数内我们要对那个变量进行读写操作,而我们只有知道了这个类型的具体信息后才可以这样做。编译器会保证传递的是同一个指针类型的值。

下面是调用了函数 increment 后,栈结构的样子。

图 5

在图 5 中我们可以看到,当把一个地址按值进行传递后,栈结构会变成什么样子。函数 increment 的栈帧中的指针变量 inc 指向了存在于函数 main 的栈帧中的变量 count。

通过这个指针变量,函数就可以以间接方式读写存在于函数 main 的栈帧中的变量 count 了。

清单 13

这个时候,* 被用作一个操作符和指针变量一起使用,把 * 用作操作符,意思是说要得到指针变量所指向的内容,在这里也就是函数 main 中的 count 变量。指针变量允许在使用它的栈帧中间接访问此栈帧之外的内存空间。有时候我们把这种间接访问叫做指针的解引用。在函数 increment 中仍然需要一个可以直接访问的本地指针变量来执行间接访问,在这里就是变量 inc。

当执行了第 21 行后,栈结构的变成下面这个样子。

图 6

下面是程序的全部输出:

表 14

可以看到,变量 inc 的值正是变量 count 的地址,就是这一个联系才使得访问本栈帧外的内存成为可能。一旦函数 increment 通过指针变量执行了写操作,当控制返回到函数 main 后,修改就会反应到对应的共享变量中。

指针型变量并不特别

指针类型和其它类型一样,一点也不特殊。它们有一块分配的内存并存放了一个值,抛开它指向的类型,指针类型总是占用同样的大小并且有相同的表示。唯一可能让我们感到困惑的是字符 *,在函数 increment 内部,它被用作操作符,在函数声明时用来声明指针变量。如果你可以分清指针声明时和指针的解引用操作时的区别,应该就没那么困惑了。

总结

这篇文章讨论了设计指针背后的目的,以及在 Go 语言中栈和指针是怎样工作的。这是理解 Go 语言的语言机制、设计哲学的第一步,也对写出一致的、可读性好的代码有一定的指导作用。

下面来总结一下我们学到了什么:

  1. 帧边界为每个函数提供了独立的内存空间,函数就是在自己的帧边界内执行的
  2. 当调用函数时,上下文环境会在两个帧边界间切换
  3. 按值传递的优点是可读性好
  4. 栈是非常重要的,因为它为分配给每个函数的帧边界提供了可访问的物理内存空间
  5. 在活动栈帧以下的栈空间是不可用的,只有活动栈帧和它之上的栈空间是可用的
  6. 函数调用意味着 goroutine 需要在栈上为函数创建一个新的栈帧
  7. 只有当发生了函数调用 ,栈区块被分配的栈帧占用后,相应栈空间才会被初始化
  8. 使用指针是为了和被调用函数共享变量,使被调用函数可以用间接方式访问自己栈帧之外的变量
  9. 每一个类型,不管是语言内置的还是用户定义的,都有一个与之对应的指针类型
  10. 使用指针变量的函数,可以通过它间接访问函数栈帧之外的内存
  11. 指针变量和其它变量一样,并不特殊,同样是有一块内存,在其中存放值而已

 

来源:https://studygolang.com/articles/12443

phabricator 没法发送邮件,人肉找到邮件内容并发送出去。。。。

 

第一次接触这货,然后邮件还一直发送不出去。。。最后好不容易找到方式出大招了,看内容自己发。。。嗯哼。。。。。暂时这么解决吧。。。