0%

问题

通常返回内部数组的副本是必需的,这样用户就无法改变对象的内部状态。但这会导致代码的效率十分低下。

下面的例子中,在循环的每次迭代过程中 Employees 属性被访问了两次。下面这一小段代码就会产生2n+1个副本:

Company microsoft = GetCompanyData("MSFT");
for(int i = 0 ; i < microsoft.Employess.Lengthh; i++){
    if(microsotf.Employess[i].Alias == "kcwalina"){
    ...
    }
}

解决方案

这个问题可以通过以下两种方式解决。

一种方式是把属性改为方法,这可以告诉调用者该操作不只是访问内部字段,还有可能在每次调用时创建一个数组。这样一来,用户很可能只调用一次该方法,把结果暂时保存起来,并对保存的结果进行操作。

Company microsoft =GetCompanyData("MSFT");
Employees[] employees = microsoft.GetEmployees();
for(int i = 0 ; i < employees.Length; i++){
    if(employees[i].Alias == "kcwalina"){
    ...
    }
}

另一种方式是把属性的返回值改成集合而不要用数组。我们可以用’REadOnlyCollection‘以只读的形式来公开提供对私有数据的访问。或者,我们也可以用’Collection‘的子类来提供受控的读写访问,这样在用户的代码修改集合时,我们就能得到通知。

pulic ReadOnlyCOllection<Employees> Employees{
    get {return roEmployees; }
}
private Employee[] employees;
private ReadOnlyCollection<Employees> roEmployees;

问题

小羊能活5岁,它在2岁,4岁的时候都会生一只小羊,5岁的时候就死亡了。
问:现在有一只刚出生的小羊(0岁),n年后有多少只羊?

回答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int zeroSheepCount = 1, sheep1Count=0 , sheep2Count=0, sheep3Count=0, sheep4Count=0, sheep5Count=0;
for (int i = 0; i < 10; i++)
{
sheep5Count = sheep4Count;
sheep4Count = sheep3Count;
sheep3Count = sheep2Count;
sheep2Count = sheep1Count;
sheep1Count = zeroSheepCount;

var newSheep = sheep2Count + sheep4Count;
zeroSheepCount = newSheep;
}
var allCount = zeroSheepCount + sheep1Count + sheep2Count + sheep3Count + sheep4Count + sheep5Count;
Console.WriteLine(allCount);

常见的处理方式都会弄出来一个羊的对象,然后记录年龄,判断年龄。这样能够解决这个问题,但是羊的数量增加的很快,50年的时候内存已经增加明显,所以这个方法就不会有内存这方面的问题。

字符串换行

1
2
System.Console.WriteLine($@"Your full name is : {
firstName} {lastName}");
很好的点,可能不高级,但是看了觉着很好。

using static

   using static System.Console;
       class Program
       {
           static void Main(string[] args)
           {
               WriteLine("Hello World!");
           }
   }

C# 6.0的新写法

浮点数

浮点数的精度是可变的。除非用分数表示时分母恰好是2的正数次幂,否则用二进制浮点类型无法准确的表示该数。0.1 会有可能会表示成0.99999999999或1.000000000001.

decimal类型保证范围内的所有十进制数都是精确的。所以,对于decimal类型来说,0.1就是0.1而不是一个近似值。虽然decimal具有比浮点类型更高的精度,但是它的范围较小,所以,从浮点类型转换为decimal类型可能发生溢出错误。

Round-trip格式化

1.618033988749895 在Console.WriteLine($”{1.618033988749895}”)无法显示完全,最后一位会丢失。可以使用 string.Format(“{0:R}”,1.618033988749895)会返回结果1.618033988749895。

以下内容复制转载
原网址

因为之前留着链接,结果过一段时间之后,链接就失效了。所以打算把内容都粘上备着。

该文写给爱折腾的人,对纯新手不友善,没有辣么详细地说明如何安装node、git或者是hexo,所以关于这些问题可先行google,如有其它问题请在这里或者我的简书上留言

使用hexo而不使用jekyll在github上搭blog最大的问题就是,每次提交都需要先hexo g,然后再push生成的文件们,这样哪怕是改一个小的地方都需要重新编译全部blog,想想都蛋疼(虽然我还没有多少文章),所以决定使用Travis来自动持续集成提交到github以后的操作

网上一搜有很多的教程,看了好多然后东拼西凑才最终成功,遂决定记录下来最终成功的这个方法,以免忘记

本文中实现的最终效果是:

  • 写完blog后,直接push到github的source分支,其它的就可以不用管了
  • 由于我的.travis.yml配置文件里设置监听的就是source分支,所以会触发webhook
  • Travis则会将该项目clone过去,然后按照.travis.yml的设置执行接下来的命令
  • 执行完成后,再将编译好的文件们发送到自己的服务器,顺便pushmaster分支上来
  • 这样就可以在blog.godi13.comGodi13.github.io上都访问blog了

Github

首先,按规定名称XXXXX.github.io,其中XXXXX为你的用户名,如下图中的Godi13.github.io创建项目

创建github项目

为了使travis能够将编译好的文件们push回咱们的github,我们需要生成token,步骤如下:

  1. 点击右上方头像,然后点setting

githubsetting

  1. 点击Personal access tokens

  1. 点击Generate new token

![](http://images.godi13.com/2017-04-10-token2.png
-total)

  1. token起一个名字,勾选repo,然后点击生成

![](http://images.godi13.com/2017-04-10-repo.png
-total)

生成`token`以后,一定要复制好,因为只显示一次,如果丢失只能再次生成了

Travis

  1. 使用github帐号登录Travis,右上方按钮点击同步项目,下方打开需要集成的项目,最后点击齿轮进入项目配置页面

在travis同步

  1. 打开Build only if .travis.yml is present,右下角的那个其实也可以关了,然后往下移动页面到环境变量

  1. 在这里我将变量名称名为REPO_TOKEN,放上token,点击Add按钮

Terminal

回到终端,进入blog所在的文件夹下,新建.travis.yml文件,并添加以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 使用语言
language: node_js
# node版本
node_js: stable
# 设置只监听哪个分支
branches:
only:
- source
# 缓存,可以节省集成的时间,这里我用了yarn,如果不用可以删除
cache:
apt: true
yarn: true
directories:
- node_modules
# tarvis生命周期执行顺序详见官网文档
before_install:
- git config --global user.name "Godi13"
- git config --global user.email "mqzq9388@gmail.com"
# 由于使用了yarn,所以需要下载,如不用yarn这两行可以删除
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
- npm install -g hexo-cli
install:
# 不用yarn的话这里改成 npm i 即可
- yarn
script:
- hexo clean
- hexo generate
after_success:
- cd ./public
- git init
- git add --all .
- git commit -m "Travis CI Auto Builder"
# 这里的 REPO_TOKEN 即之前在 travis 项目的环境变量里添加的
- git push --quiet --force https://$REPO_TOKEN@github.com/Godi13/Godi13.github.io.git
master

然后,准备push该项目到github,看下是否成功,如果是新项目可参照下面的git指令

1
2
3
4
5
6
7
8
git init
# 添加自己的项目
git remote add origin git@github.com:Godi13/Godi13.github.io.git
# 新建并切换分支
git checkout --orphan source
git add -A
git commit -m "Travis CI"
git push

关于 --orphan 请参考 如何建立一個沒有 Parent 的獨立 Git branch

如最终成功则会看到

到这里关于hexo和github的事情就先吿一段落,接下来就是服务器与tarvis

服务器

按照上面.tarvis.yml的设置,其实我只需要在after_success这个生命周期中,把public文件夹下的所有文件传送到服务器指定的路径即可,接下来就是解决如何让tarvis往我的服务器传东西的问题了

在此之前,你需要将本机生成的密钥传到服务器上

1
2
3
4
5
ssh-keygen -t rsa # 然后一路回车即可
# ssh-copy-id 可能需要另行安装
# 如果ssh默认端口是22,则不需要 -p
ssh-copy-id <登录部署服务器用户名>@<部署服务器地址> -p <部署服务器ssh端口>
ssh <登录部署服务器用户名>@<部署服务器地址> -p <部署服务器ssh端口>

如果登录服务器成功,接下来需要安装travis命令行工具

1
2
3
4
5
6
7
# 安装travis命令行工具,如无法使用gem指令须先安装ruby
gem install travis
# --auto自动登录github帐号
travis login --auto
# 此处的--add参数表示自动添加脚本到.travis.yml文件中
travis encrypt-file ~/.ssh/id_rsa --add
# 这个命令会自动把 id_rsa 加密传送到 .git 指定的仓库对应的 travis 中去

执行完以后会发现在travis网站项目里面的环境变量里多了两个参数

并且在.travis.yml里的before_install周期中多了下面这2行

1
2
- openssl aes-256-cbc -K $encrypted_97d432d3ed20_key -iv $encrypted_97d432d3ed20_iv
-in id_rsa.enc -out ~\/.ssh/id_rsa -d

默认生成的命令可能会在/前面带转义符\,我们不需要这些转义符,手动删掉所有的转义符,否则可能在后面引发莫名的错误

之后为了保证命令的顺利运行,我们还需要正确地设置权限和认证

1
2
3
4
5
before_install
- openssl aes-256-cbc -K $encrypted_97d432d3ed20_key -iv $encrypted_97d432d3ed20_iv
-in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host 主机IP地址\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

最后,就是在after_success周期中,添加上传服务器的指令即可,在这里要注意,如果没有stricthostkeychecking=no参数,将构建失败,详细原因请参考通过travis部署代码到远程服务器

1
2
# 由于我修改了默认的port,所以在这里也进行了加密处理
- scp -o stricthostkeychecking=no -P $PORT -r public/* 用户@域名:/路径

但使用scp有很多问题,所以后来我决定改用rsync命令,缺点是端口号就不能用travis环境来加密了,如果哪个朋友有更好的方案希望能告诉我,关于rsync请参考介绍 rsync 数据同步工具

1
2
# public 后面加上/即可将该目录下的文件都传送到服务器了
- rsync -rv --delete -e 'ssh -o stricthostkeychecking=no -p 端口号' public/ 用户@域名:/路径

最后在这里放上我最终的.travis.yml配置参数,希望本文对大家能有所帮助

参考资料

  1. Ctrl + F搜索
  2. Ctrl + Shit + F全局搜素
  3. Ctrl + G输入行号可以跳转到指定的行
  4. Ctrl + N新建文件
  5. Ctrl + Shift + P打开命令输入框
    输入language输入想要的语言
  6. Ctrl + Shift + P打开命令面板
    输入encoding字符编码
  7. 支持markdown的书写和预览
    Ctrl + Shift + V预览
  8. Ctrl + Tab键来快速的切换文件
  9. Ctrl + p输入搜索文件

Travis 部署

忙乎到半夜 Travis 总算部署成功了,这一篇留着记录下部署过程中的问题。

Travis 下载

因为众所周知的原因,某些网站是访问不了的。所以下载ruby的 gem就不那么轻松,然后在安装travis的时候又访问不了,所以就在找国内的源,
然而https的因为证书问题有没有加进去,所以最后 使用了 ‘http://gems.ruby-china.org‘ 使用了这个

hexo 部署

hexo d 无法部署

  1. 注意config中的配置,:号后面有一个空格, type git

  2. 在搭建hexo博客的适合遇到个问题就是使用hexo deploy的时候遇到了下面的错误

    1
    2
    3
    4
    5
    6
    7
    8
    Clearing
    Copying files from public folder.
    events.js:72
    throw er; // Unhandled 'error' event
    ^
    Error: spawn ENOENT
    at errnoException (child_process.js:980:11)
    at Process.ChildProcess._handle.onexit (child_process.js:771:34)

    解决方法就是在cmd下敲的命令无法实现,我们把命令在git shell下面敲打就可以实现了。
    补充:找到原因了,因为没有设置环境变量导致的,在path中添加git的环境变量,就没有问题了

  3. 还有就是在 hexo d 之前 需要先执行 npm install hexo-deployer-git --save

  4. warning: LF will be replaced by CRLF」 我只使用这个命令就好用了 来源

  5. 部署的时候提示找不到username 的问题 github上的issue

hexo 资源

这个人的记录了很多比较实用的hexo从搭建到使用的问题,非常的不错 链接