12
1

.NET7下string的改进

0
归档:2023年1月分类:C#和.NET

string是开发过程中,使用频度最高的类型之一,所以在构建类型时作了很多处理,如“不可变性”,“保留性”等特点。string的常量是在""引号中进行赋值的。

var str1 = "这是一段文字";
Console.WriteLine(str1);

为了字符串的格式化,引入了$""定义方式,这样就可以在字符串中用{}来标注格式化的内容了。

var str2 = $"时间:{DateTime.Now}";
Console.WriteLine(str2);
//输出结果是:时间:1/6/2023 15:37:13

var str2_1 = $"时间:{DateTime.Now:yyyy-MM-dd}";
Console.WriteLine(str2_1);
//输出结果是:时间:2023-01-06

为了解决字符串内容的换行,引定入@"",来定义有换行的字符串,比如下面的一条SQL查询,可以按格式化后的样式来定义。$和@可以混用,不分先后。

var str3 = @"SELECT ID
    ,Question
    ,Score
    ,QuestionTypeID
    ,SubjectTypeID
    FROM Questions";
Console.WriteLine(str3);

var str3_1 = @$"SELECT ID
    ,Question
    ,Score
    ,QuestionTypeID
    ,SubjectTypeID
    FROM Questions WHERE Score>{10}";
Console.WriteLine(str3_1);

其实原始字符串还解决了一个问题,就是字符串中有"的问题,以前需要有转义字符来实现,现在原始字符串都搞定了。

Console.WriteLine("\"a\" 是小写的");//通过\来转义
Console.WriteLine(@"""a"" 是小写的");//前缀是@时,通过"转义

最佳demo是json字符串的定义,用原始字符串的方式定义json字符串,最合适不过了。

var jsonString = """
                 {
                     "irstName": "John",
                     "astName": "Smith",
                     "ex": "male",
                     "ge": 25,
                     "ddress": 
                     {
                         "treetAddress": "21 2nd Street",
                         "ity": "New York",
                         "tate": "NY",
                         "ostalCode": "10021"
                     }
                 }
                 """;

Console.WriteLine(jsonString)

通过下图,看到的json原始字符串,一目了然:

10
1

作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等。

本文将更深入的研究当你输入一个网址的时候,后台到底发生了一件件什么样的事

1 首先,你得在浏览器里输入要网址:

2 浏览器查找域名的IP地址

导航的第一步是通过访问的域名找出其IP地址。DNS查找过程如下:

浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。

系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。

路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。

递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。DNS递归查找如下图所示:

DNS有一点令人担忧,这就是像wikipedia.org 或者 facebook.com这样的整个域名看上去只是对应一个单独的IP地址。还好,有几种方法可以消除这个瓶颈:

循环 DNS 是DNS查找时返回多个IP时的解决方案。举例来说,Facebook.com实际上就对应了四个IP地址。

负载平衡器 是以一个特定IP地址进行侦听并将网络请求转发到集群服务器上的硬件设备。 一些大型的站点一般都会使用这种昂贵的高性能负载平衡器。

地理 DNS 根据用户所处的地理位置,通过把域名映射到多个不同的IP地址提高可扩展性。这样不同的服务器不能够更新同步状态,但映射静态内容的话非常好。

Anycast 是一个IP地址映射多个物理主机的路由技术。 美中不足,Anycast与TCP协议适应的不是很好,所以很少应用在那些方案中。大多数DNS服务器使用Anycast来获得高效低延迟的DNS查找。

3 浏览器给web服务器发送一个HTTP请求

因为像Facebook主页这样的动态页面,打开后在浏览器缓存中很快甚至马上就会过期,毫无疑问他们不能从中读取。

所以,浏览器将把一下请求发送到Facebook所在的服务器:

GET http://facebook.com/ HTTP/1.1
 Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
 User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
 Accept-Encoding: gzip, deflate
 Connection: Keep-Alive
 Host: facebook.com
 Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]

GET 这个请求定义了要读取的URL: “http://facebook.com/”。 浏览器自身定义 (User-Agent 头), 和它希望接受什么类型的相应 (Accept and Accept-Encoding 头). Connection头要求服务器为了后边的请求不要关闭TCP连接。

请求中也包含浏览器存储的该域名的cookies。可能你已经知道,在不同页面请求当中,cookies是与跟踪一个网站状态相匹配的键值。这样cookies会存储登录用户名,服务器分配的密码和一些用户设置等。Cookies会以文本文档形式存储在客户机里,每次请求时发送给服务器。

用来看原始HTTP请求及其相应的工具很多。作者比较喜欢使用fiddler,当然也有像FireBug这样其他的工具。这些软件在网站优化时会帮上很大忙。

除了获取请求,还有一种是发送请求,它常在提交表单用到。发送请求通过URL传递其参数(e.g.: http://robozzle.com/puzzle.aspx?id=85)。发送请求在请求正文头之后发送其参数

像“http://facebook.com/”中的斜杠是至关重要的。这种情况下,浏览器能安全的添加斜杠。而像“http: //example.com/folderOrFile”这样的地址,因为浏览器不清楚folderOrFile到底是文件夹还是文件,所以不能自动添加 斜杠。这时,浏览器就不加斜杠直接访问地址,服务器会响应一个重定向,结果造成一次不必要的握手。

4 facebook服务的永久重定向响应

图中所示为Facebook服务器发回给浏览器的响应:

HTTP/1.1 301 Moved Permanently
 Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
 pre-check=0
 Expires: Sat, 01 Jan 2000 00:00:00 GMT
 Location: http://www.facebook.com/
 P3P: CP="DSP LAW"
 Pragma: no-cache
 Set-Cookie: made_write_conn=deleted; expires=Thu, 12-Feb-2009 05:09:50 GMT;
 path=/; domain=.facebook.com; httponly
 Content-Type: text/html; charset=utf-8
 X-Cnection: close
 Date: Fri, 12 Feb 2010 05:09:51 GMT
 Content-Length: 0

服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问“http://www.facebook.com/” 而非“http://facebook.com/”。

为什么服务器一定要重定向而不是直接发会用户想看的网页内容呢?这个问题有好多有意思的答案。

其中一个原因跟搜索引擎排名有 关。你看,如果一个页面有两个地址,就像http://www.igoro.com/ 和http://igoro.com/,搜索引擎会认为它们是两个网站,结果造成每一个的搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是 什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。

还有一个是用不同的地址会造成缓存友好性变差。当一个页面有好几个名字时,它可能会在缓存里出现好几次。

5浏览器跟踪重定向地址

现在,浏览器知道了“http://www.facebook.com/”才是要访问的正确地址,所以它会发送另一个获取请求

GET http://www.facebook.com/ HTTP/1.1
 Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
 Accept-Language: en-US
 User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
 Accept-Encoding: gzip, deflate
 Connection: Keep-Alive
 Cookie: lsd=XW[...]; c_user=21[...]; x-referer=[...]
 Host: www.facebook.com

头信息以之前请求中的意义相同。

  1. 服务器“处理”请求

服务器接收到获取请求,然后处理并返回一个响应。

这表面上看起来是一个顺向的任务,但其实这中间发生了很多有意思的东西- 就像作者博客这样简单的网站,何况像facebook那样访问量大的网站呢!

Web服务器软件

web服务器软件(像IIS和阿帕奇)接收到HTTP请求,然后确定执行什么请求处理来处理它。请求处理就是一个能够读懂请求并且能生成HTML来进行响应的程序(像ASP.NET,PHP,RUBY...)。举个最简单的例子,需求处理可以以映射网站地址结构的文件层次存储。像http://example.com/folder1/page1.aspx这个地 址会映射/httpdocs/folder1/page1.aspx这个文件。web服务器软件可以设置成为地址人工的对应请求处理,这样 page1.aspx的发布地址就可以是http://example.com/folder1/page1。

请求处理

请求处理阅读请求及它的参数和cookies。它会读取也可能更新一些数据,并讲数据存储在服务器上。然后,需求处理会生成一个HTML响应。
所 有动态网站都面临一个有意思的难点 -如何存储数据。小网站一半都会有一个SQL数据库来存储数据,存储大量数据和/或访问量大的网站不得不找一些办法把数据库分配到多台机器上。解决方案 有:sharding (基于主键值讲数据表分散到多个数据库中),复制,利用弱语义一致性的简化数据库。

委托工作给批处理是一个廉价保持数据更新的技术。举例来讲,Fackbook得及时更新新闻feed,但数据支持下的“你可能认识的人”功能只需要每晚更新 (作者猜测是这样的,改功能如何完善不得而知)。批处理作业更新会导致一些不太重要的数据陈旧,但能使数据更新耕作更快更简洁。

7 服务器发回一个HTML响应

图中为服务器生成并返回的响应:

HTTP/1.1 200 OK
 Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
 pre-check=0
 Expires: Sat, 01 Jan 2000 00:00:00 GMT
 P3P: CP="DSP LAW"
 Pragma: no-cache
 Content-Encoding: gzip
 Content-Type: text/html; charset=utf-8
 X-Cnection: close
 Transfer-Encoding: chunked
 Date: Fri, 12 Feb 2010 09:05:55 GMT

整个响应大小为35kB,其中大部分在整理后以blob类型传输。

内容编码头告诉浏览器整个响应体用gzip算法进行压缩。解压blob块后,你可以看到如下期望的HTML。

关于压缩,头信息说明了是否缓存这个页面,如果缓存的话如何去做,有什么cookies要去设置(前面这个响应里没有这点)和隐私信息等等。

请注意报头中把Content-type设置为“text/html”。报头让浏览器将该响应内容以HTML形式呈现,而不是以文件形式下载它。浏览器会根据报头信息决定如何解释该响应,不过同时也会考虑像URL扩展内容等其他因素。

8 浏览器开始显示HTML

在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了:

9 浏览器发送获取嵌入在HTML中的对象

在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。

下面是几个我们访问facebook.com时需要重获取的几个URL:

图片
http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
http://static.ak.fbcdn.net/rsrc.php/zBS5C/hash/7hwy7at6.gif

CSS 式样表
http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
http://static.ak.fbcdn.net/rsrc.php/zANE1/hash/cvtutcee.css

JavaScript 文件
http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
http://static.ak.fbcdn.net/rsrc.php/z6R9L/hash/cq2lgbs8.js

这些地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等...

但 不像动态页面那样,静态文件会允许浏览器对其进行缓存。有的文件可能会不需要与服务器通讯,而从缓存中直接读取。服务器的响应中包含了静态文件保存的期限 信息,所以浏览器知道要把它们缓存多长时间。还有,每个响应都可能包含像版本号一样工作的ETag头(被请求变量的实体值),如果浏览器观察到文件的版本 ETag信息已经存在,就马上停止这个文件的传输。

试着猜猜看“fbcdn.net”在地址中代表什么?聪明的答案是"Facebook内容分发网络"。Facebook利用内容分发网络(CDN)分发像图片,CSS表和JavaScript文件这些静态文件。所以,这些文件会在全球很多CDN的数据中心中留下备份。

静态内容往往代表站点的带宽大小,也能通过CDN轻松的复制。通常网站会使用第三方的CDN。例如,Facebook的静态文件由最大的CDN提供商Akamai来托管。

举例来讲,当你试着ping static.ak.fbcdn.net的时候,可能会从某个akamai.net服务器上获得响应。有意思的是,当你同样再ping一次的时候,响应的服务器可能就不一样,这说明幕后的负载平衡开始起作用了。

10浏览器发送异步(AJAX)请求

在Web 2.0伟大精神的指引下,页面显示完成后客户端仍与服务器端保持着联系。

以 Facebook聊天功能为例,它会持续与服务器保持联系来及时更新你那些亮亮灰灰的好友状态。为了更新这些头像亮着的好友状态,在浏览器中执行的 JavaScript代码会给服务器发送异步请求。这个异步请求发送给特定的地址,它是一个按照程式构造的获取或发送请求。还是在Facebook这个例 子中,客户端发送给http://www.facebook.com/ajax/chat/buddy_list.php 一个发布请求来获取你好友里哪个 在线的状态信息。

提起这个模式,就必须要讲讲"AJAX"-- “异步JavaScript 和 XML”,虽然服务器为什么用XML格式来进行响应也没有个一清二白的原因。再举个例子吧,对于异步请求,Facebook会返回一些JavaScript的代码片段。

除了其他,fiddler这个工具能够让你看到浏览器发送的异步请求。事实上,你不仅可以被动的做为这些请求的看客,还能主动出击修改和重新发送它们。AJAX请求这么容易被蒙,可着实让那些计分的在线游戏开发者们郁闷的了。(当然,可别那样骗人家~)

Facebook聊天功能提供了关于AJAX一个有意思的问题案例:把数据从服务器端推送到客户端。因为HTTP是一个请求-响应协议,所以聊天服务器不能把新消息发给客户。取而代之的是客户端不得不隔几秒就轮询下服务器端看自己有没有新消息。

这些情况发生时长轮询是个减轻服务器负载挺有趣的技术。如果当被轮询时服务器没有新消息,它就不理这个客户端。而当尚未超时的情况下收到了该客户的新消息,服务器就会找到未完成的请求,把新消息做为响应返回给客户端。

总结一下

希望看了本文,你能明白不同的网络模块是如何协同工作的.

02
1

[转]NPM和webpack的关系

0
归档:2023年1月分类:C#和.NET

入门前端的坑也很久了,以前很多大小项目,前端都是传统式开发,一直在重复造轮子;接触VUE后,对vue-cli有了解后,仅仅知道vue-cli是一个vue项目的脚手架,可以快速的构建一个vue的基于npm的模块化项目,vue内部的打包机制其实还是借助webpack;但是对webpack\npm\node\nodejs这几个在前端模块化中的高频词总是傻傻分不清,不知道他们之间的具体关系,今天花了些功夫查阅了网上大神的回答和官方教程给出的解释写一篇小白文,总结一下这几个概念或者说高频词汇之间的关系

what is webpack?

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。即WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

webpack的核心作用

模块化开发中,我们会编写大量模块,如果不打包就上线,那么页面加载或交互时,将会发起大量请求。为了性能优化,需要使用webpack这样的打包器对模块进行打包整合,以减少请求数。就像简单的vue项目,所有组件最终都将被打包到一个app.js中。
相较于无差别打包依赖模块的传统打包器,webpack的核心优势在于它从入口文件出发,递归构建依赖关系图。通过这样的依赖梳理,webpack打包出的bundle不会包含重复或未使用的模块,实现了按需打包,极大的减少了冗余。

webpack是一个工具,这个工具可以帮你处理好各个包/模块之间的依赖关系(modules with dependencies),并将这些复杂依赖关系的静态文件打包成一个或很少的静态文件,提供给浏览器访问使用;除此之外,webpack因为可以提高兼容性,可以将一些浏览器尚不支持的新特性转换为可以支持格式,进而减少由新特性带来的浏览器的兼容性问题。

好,我们通过介绍,我们有个概念,webpack是一个打包工具,可以帮你把你的项目这里的项目其实就是指通过模块化开发的项目 打包为简洁版的浏览器可识别的静态资源。

what is npm?

介绍了webpack,我们可能会疑问,我的JS,CSS,HTML文件分开写,挺好的呀,为什么要使用webpack工具,进行复杂的各项配置。在传统前端开发模式下,我们确实是按照JS/CSS/HTML文件分开写的模式就可以,但是随着前端的发展,社区的壮大,各种前端的库和框架层出不穷,我们项目中可能会使用很多额外的库,如何有效管理这些引入的库文件是一个大问题,而且我们知道基于在HTML中使用script引入的方式,有两个弊端,一个是会重复引入,二是当库文件数量很多时管理成为一个大难题。面对这样的局面,为了简化开发的复杂度,前端社区涌现了很多实践方法。模块化就是其中一项成功实践,而npm就是这样在社区 其实就是node社区中产生的。

npm 由三个独立的部分组成:网站、注册表(registry)、命令行工具 (CLI)。

网站 是开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径。
注册表 是一个巨大的数据库,保存了每个包(package)的信息。CLI 通过命令行或终端运行。开发者通过 CLI 与 npm 打交道。

一般来说提起npm有两个含义,一个是说npm官方网站,一个就是说npm包管理工具。npm社区或官网是一个巨大的Node生态系统,社区成员可以随意发布和安装npm生态中的包,也就是不用在重复造轮子了,别人造好了,你直接安装到你的项目中就可以使用,但是因为前面说了,当包引入数量很多时管理就成为了一个问题,这个就是npm为开发者行了方便之处,npm已经为你做好了依赖和版本的控制,也就是说使用npm可以让你从繁杂的依赖安装和版本冲突中解脱出来,进而关注你的业务而不是库的管理。

webpack就是将你从npm中安装的包打包成更小的浏览器可读的静态资源,这里需要注意的是,webpack只是一个前端的打包工具,打包的是静态资源,和后台没有关系,虽然webpack依赖于node环境。

what is node or nodejs?

其实node和nodejs两个概念没有太大差别,我个人认为唯一的区别就是,人们说起node的时候语境更多的是再说node环境,而说nodejs时更多的是在说node是一门可以提供后端能力的技术。本质上来说,node就是nodejs,nodejs就是node

简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

node环境基于V8引擎提供了一种可以让JS代码跑在后端的能力,这就是node。其实这里的node本身和我们这篇讲的前端模块化没啥关系。但是因为npm是产生与node社区,node中也是通过npm来加载模块的,所以有必要说一下他们之间的关系。

npm 是 Node.js 官方提供的包管理工具,他已经成了 Node.js 包的标准发布平台,用于 Node.js 包的发布、传播、依赖控制。

webpack npm node之间关系?

webpack是npm生态中的一个模块,我们可以通过全局安装webpack来使用webpack对项目进行打包;

webpack的运行依赖于node的环境,没有node是不能打包的,但是webpack打包后的项目本身只是前端静态资源和后台没有关系,也就是说不依赖与node,只要有后台能力的都可以部署项目。

npm是于Node社区中产生的,是nodejs的官方包管理工具,当你下载安装好node的时候,npm cli 就自动安装好了。

正是因为npm的包管理,使得项目可以模块化的开发,而模块化的开发带来的这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就是webpack工具存在的意义

原文地址:https://blog.csdn.net/AngelLover2017/article/details/84801673

01
1

原作者:刘原 2023-01-01 10:02

这是2022年的最后一缕斜阳,它穿越云翳和树梢,穿越山梁和旷野,呼啸而来,打在你的脸上,也打在我的屁股上。

都不许喊疼。

每到岁末,我都会在这一天和读者们共同回望即将远逝的这一年。谈不上新年献词,因为我的底色总是苍凉,从无昂扬喜庆,倘在先前的报馆,那都是要被毙的稿,除非那天恰好是我自己值班签版可以徇私。我把它归类为:民间记忆。

站在这个时间门槛上,我只望见了两个字:永逝。所有的故事都已终结,所有的脸孔都已凝固,悉数留在了2022,万物在这一年展露过它们应有的容颜,然后,被历史的书页重重覆盖。

那么,2022的记忆该从哪一截起始呢?我已记不清晰,可能是从丰县的一段锁链,也可能是从唐山的一家烧烤店。大家都记得那会满世界刷屏的场景。

我从未见过亿万网民如此齐心。

事后我思忖过,拐卖人口、伤害女性,固然是极其恶劣的,但它是多年来的沉疴,类似案例屡见不鲜,那么,为何这两桩恶行突然点爆了全民的怒火?

一是以短视频为主力的网络传播,与以往的文字图片传统形式相比,在视觉和情感上的爆破力是无与伦比的,再高超的文字记者,描述出的场景都远不如那几十秒视频有冲击力。

二是人民心中有块垒。经过几年疫情的折磨,大家对苦难有了更多的共情,谁无母亲姐妹妻女?这样的惨案已经不仅仅是女性群体的悲剧,它更是属于全体国民的悲剧。

三是每个人都会思索:我们生而为人,有哪些与生俱来的权利?如果被拘禁、被伤害、被殴打可以被漠视,被掩盖,谁敢保证下一个受害者不会是自己和家人?

在这两次刷屏之下,冬奥会并没有收到预期中的热度。当然也正常,中国的冰雪运动普及还很有限,即便我这样曾经狂热的体育爱好者,几十年看的惟一冰雪项目也只有短道速滑。我甚至不记得谷爱凌在哪些项目上拿了金牌,只知道她多年来一到暑假就飞回北京参加海淀区的奥数班。

冬奥会刚结束,俄乌战争开始了。

这是2022年里,全世界最刻骨铭心的一件事。

当我在2月24日中午醒来时,手机里有无数条朋友们发的信息。我一睁眼就吓得激灵一下,大意是说俄军几十万大军分几路攻入乌克兰,基辅陷落,乌三军已经悉数被摧毁……

这样的消息,我只信了半天,是的,就开战之初兵荒马乱的那半天。然后,我再没信过那些打鸡血的简中自媒体,连看都不去看。

这是一场局部战争,但也是一场剧烈改变世界格局的战争。它的烈度和席卷范围,远不如20世纪的一战和二战,但它事实上起到了三战的效能,对1945之后、冷战落幕之后的国际秩序进行了重构。

一切都因为一个叫泽连斯基的人。

没有人在今年的早春二月看好他,包括他的国民,包括欧美国家。作为“95街区”(大概类似于乌克兰版的开心麻花)的创始人,《人民公仆》的主演,泽连斯基能唱会跳,演技出色,若说他是各国元首中表演造诣最深的人,恐不为过。即使考虑到罗纳德里根的存在,他至少也是TOP2。

但在大兵压境时,没人指望一个喜剧演员出身的总统能力挽狂澜,美国甚至为他设计了流亡路线,欧洲各国也打算旁观乌克兰亡国,然后象征性发个谴责声明算球。

但是,这个小个子演员爆发了。他告诉国民和世界:他就在基辅,哪里都不去,他的家人也同在基辅,他随时准备死在那里。

从国家被入侵的那一天起,这个男人就没刮干净过胡子,没穿过西装。他永远胡子拉碴,穿着浅绿的军用T恤,在烛光里的防空洞,在残垣断壁的街道,在被血洗过的村庄,不停地穿行,不停地拍着视频,告诉他的人民——他从未离开,他始终在抵抗。

这不是演技。出入于血与火之间,一秒就可能被炮弹炸死。没人会拿自己的性命去演。他就是无畏,他就是骨头硬。

说来也是滑稽,世上多少所谓强人,平素大喇喇上山打虎下海捉鳖,装旷世伟人,真碰上事了就大小便失禁。真正泰山崩于前而色不变的,却往往是人们嘴里嘲讽的所谓戏子。

80年代,刚遇刺不久的里根,在西柏林的一次公开集会上演讲,现场的一个氢气球爆炸,声音像极了枪响。正在演讲的他头都不抬,只说了一句:Miss me(没打中)。连缩起头的条件反射都没有,这才叫无畏。

里根以其机敏、睿智、勇气,以一己之力拖垮了苏联帝国。撒切尔夫人曾评价他:一枪不开就赢了冷战。

而泽连斯基以视死如归的气概,正在让俄罗斯帝国失血。俄罗斯这个国家,大概是命犯演艺圈,注定要被两个演员终结国运。

起初欧洲是混沌而绥靖的,除了鲜明而锋利的金毛,以及迟缓但坚定的老拜,并没有太多国家伸出援手,天知道你是不是亡国之君。但当乌克兰挺过最艰难的前几天,当泽连斯基一次次向世界发布他和他的人民誓死抵抗的宣言之后,情势逆转了。人类的勇气、良知和同情被瞬间唤醒,冬夜里微弱的摇曳之烛迅速变成巨大火把,几乎所有民选国家的民众都在督促本国政要支援乌克兰,这成了最大的政治正确。

为了挺乌克兰,波兰德国等接纳了大批乌克兰难民,东欧尤其波罗的海一众小国毫无畏惧地拿出了压箱底的军火,从北美到亚洲甚至非洲,无数国家从军援到经援,都在慷慨支援乌克兰。整个欧洲甚至愿意忍受缺气的寒冬,也要制裁发动战争的国家。

不要污蔑乌克兰在打什么代理人战争。联大每次投票,大部分国家都支持他们,他们又是哪一国的代理人?自己的家园被夷为废墟,自己的亲人死于非命流离失所,而自己拿起枪加入卫国战争,这是最堂堂正正、最天经地义的抵抗。你若连这都能抹杀,那你一定也会抹杀我们祖辈浴血奋战的伟大的抗日战争,那叫汉奸。

在冬残奥会上,特别感人的一幕是:许多国家的运动员在临冲线时,默契地放缓了脚步,让乌克兰运动员夺金。那几天,乌克兰国旗一次次在冬残奥会赛场升起,甚至一次升起三面。人们想让战火中的乌克兰人民知道,世界的道义和慈悲站在他们这边,他们不是孤独的。

在这场战争中,除了泽连斯基,我还记住了三张脸:

一个11岁的男孩哈桑,十年前,在俄军的空袭下,寡母抱着襁褓中的他逃离了叙利亚回到乌克兰,十年后,俄军炮击扎波罗热核电站,住在这个城市的母亲要照顾年迈的外婆,他自己背着一个包,拿着一个塑料袋和一本护照,独自坐了近千公里的火车,去斯洛伐克投奔哥哥姐姐。他的手臂上写着电话号码。

file

这孩子和我家流氓兔一样大。他羞怯,胆小,很快就吃完了身上带的一点食物,平素连夏令营都不敢去的他,不安地趴在车窗边,向着未知的异国孤身逃难。乌克兰的知名女狙击手埃梅拉尔德,在深秋的哈尔科夫前线阵地,与同为军人的新郎举行了婚礼。乌军的一名将军是他们的证婚人。

file

当这场战争结束时,或许他们已经殉国,或许已经伤残。但他们只想告诉这个世界:他们来过,爱过,对得起这片向日葵盛开的大地,对得起2022年的秋天。

而最令我动容的,是下面这张照片,我特地选它作为本文的题图。
马里乌波尔钢铁厂的一名守军,在日复一日绞肉机式的战斗间隙,贪婪地沐浴着珍贵的阳光。

file

这是一群绝望的孤军,每天都在倚靠钢铁建筑进行巷战,缺乏补给,没有援军。像四行仓库的谢晋元,像衡阳保卫战的方先觉,一无所有,除了必死之心。

生活在黑暗里的人们,心里一定要有光。我们来到这世界,不是为了当一只鼹鼠。阳光与朝露,是造物主赐予我们的,我们配得上每一束光。

不是每个人都能望见2023年的霞光。英国女王、戈尔巴乔夫,这些曾在收音机里陪伴过我们童年的名字都远逝了,他们曾经参与的历史,也变成了书籍中的铅字。而未来的史,由现在活着的人继续书写。

9月8日深夜,我用手机看BBC的女王病危现场画面,镜头在伦敦白金汉宫和苏格兰巴尔莫勒尔城堡之间切换,像是一场死亡直播。我突然看到两辆轿车和一辆军用吉普驶出城堡大门,扬长而去,当时就发了个朋友圈说:女王似已殁,那几辆车应该是去操办后事了。

随后的讣告验证了我的直觉,女王正是那个时间点去世的。这几年,见的缟素太多,我对死亡的嗅觉也变得敏锐多了。

但11月26日,新疆阿勒泰的7名福建籍工人没能嗅到死亡的气息。那天傍晚,他们乘车去4公里外的小镇准备转车返乡,没想到车刚开出500米就陷入暴雪中,于是,他们决定下车,徒步走回工地。没想到,在能见度仅3米的暴风雪中,他们竟然迷路了,连500米外的工地都没能找到,活活冻死。
他们倒下的地方距工地300米,这是阳世与阴间的距离。

而今年三月,一架东航737客机在我曾经的故乡梧州上空一头栽下。8000米,这也是从阳世到阴间的距离。而我们,至今不知事故原因。

破碎的脸太多,我们无法记全。

当一个三岁的小男孩在某场悲剧中罹难后,我看到一句令人心碎的评论:他生于疫情,死于疫情,就这样过了一生,他很乖,只是从未被这人间爱过。
不说了,说多了难过。

在这个寒冬,世界杯,或许是2022年惟一能慰藉我们的幸福。

这届世界杯的精彩度,是几十年来罕见的。不仅仅因为这是梅西C罗莫德里奇内马尔莱万一众诸神的黄昏,也因为大疫三年,人类受够了,人类太需要一场血脉贲张的赛事来涤荡几年的悲伤和郁结。

结局亦完美。

曾经的侏儒症患者梅西,在经历了无数人生悲喜之后,登顶王座。命运终于给了那个最努力最有天赋的孩子最好的馈赠,这是生命的大和谐,哦不,大圆满。

他终于成了贝利、马拉多纳之后的第三位球王。

有人觉得梅西缺乏马拉多纳的霸气,配不上球王称号。在他们眼中,在那不勒斯带着全队去嫖娼、跟女理发师造个私生子、用气枪射击记者、服用麻黄素的迭戈才叫王者气概,而梅西太乖,不像定海神针的样子。

file

但我喜欢梅西。他刻苦、干净、忠诚、慈悲,从未忘记含辛茹苦培养他的天堂里的外婆,会给遥远中国一个热爱足球的穷孩子寄来礼物,这是典型的在欧洲长大并接受欧洲文明的孩子。而马拉多纳,虽然天赋异禀,但至死都是南美街头烂仔底色,跟不止一个独裁者勾肩搭背。

我当然更喜欢梅西。他走在人间正道上,代无数平凡人实现了一个卑微而伟大的梦想。

如今谈及梦想,近乎奢侈。活着就是最大的梦想。

一位老友的女儿,从海外留学归来,在早春的沪上,曾经匮乏得桌上只剩一根胡萝卜。解禁之后,她直接买了一张机票,再次留洋。

在2022的最后一个月,我应约给媒体写一篇盘点稿。我忽然好奇,在同样的这一年,不同国度的人们是如何度过的?于是,我和亚洲、欧洲、北美洲的朋友们,在冬夜里,漫无边际地聊天。

我刨根问底地询问他们,印象最深刻、灵魂最颤栗的事情有哪些。

身在清迈的朋友边跟我聊,边收拾行李准备翌日去柬埔寨旅游。他告诉我,泰国有几个地方让他最是感慨:国民极注重卫生,即便是贫困乡村的农户,厕所里都没有苍蝇和臭味;当地人从不吵架,更不会拳脚相见,世道恬静,人民温和;他丢了几次钱包手机,每次都能找回来,别的朋友亦如此,此地不偷不抢不骗,甚至不捡,真正的路不拾遗。

初到多伦多的朋友遇到大雪封门,坐在壁炉边和我聊枫叶国的教育。老师永远不会因成绩优劣歧视任何孩子,智障学生有专人辅导,残疾学生有专车接送。移民局官员主动帮她联系了女儿就读的学校,说有困难告诉我们,许多问题可以由政府出钱解决,因为有你们这些市民,才令我们政府的存在有意义;校长对她说,不要焦虑地去报课外培训班,所有学业上的事都归学校负责,你不用操心;老师给家长发调查问卷,标题特别温暖:“每一个孩子都重要”。朋友的女儿上小学六年级,稚嫩的她冒出的一句话,让我惊愕而震撼——

“在加拿大,孩子们才是这个国家最大的软肋。”

file

我望着朋友微信发的北美明月,陷入谜之沉思。

多说无益。2022,终究是要过去了。

我想拥抱北京的朋友们,最近在网上看到太多视频,我心里很惨痛,希望你们能熬过这个寒冬;我想拥抱上海的朋友们,年初你们忍饥挨饿的时候,我偶尔想发个美食图片都觉得很可耻;我想拥抱长沙的朋友们,我们在2022年几乎没见过面,我甚至没见到岳麓山的红枫,也不知道橘子洲解放西坡子街上还有没有游客;我想拥抱许多远方的朋友们,我们都在这个贫瘠的长夜里,忍受着浓雾里的病痛和忧伤。

但我谁都拥抱不了,甚至包括家里的俩娃。我和兔妈都阳了,但娃们还阴着,每天傍晚,我给小软肋们做完晚饭后就捧着碗躲进书房独自吃。入夜,我口吞刀片,在剧烈的疼痛中,一篇一篇赶着文章,记录着这现世。

朋友圈里尽是讣闻。许多朋友在料峭冬夜里,失去了至亲。有两位老友最近刚失去了父亲,我看他们的纪念文字时,惊诧地发现他们的父亲都是86岁,都在50年代考上了华南理工大学,正是同期校友。只是命运蹉跎,一位留校当了教授,一位回到广西边陲当了乡村教师;一位早有预感向儿子交待了身后事,一位骤然离世没给漂洋过海的儿孙留半句话。

球王贝利也没能逾越过这个冬天,他和19年前的梅艳芳一样,生命的钟摆停留在12月30日。今夜我看了他半个世纪前的进球集锦,伤感地想,这个世界失去了一个多么伟大、多么有趣的人。

时代的一粒尘埃,足以让我们爆头,满嘴是血。

倘若时光可以选择,我情愿2022不曾来过,当然,也包括2021、2020。这三年,没人愿去经历。但是它,毕竟是我们命定的时光,选择不了。

雨落下。雪也落下。覆盖了我们所有的哀伤。

此刻所有的新年祝福都会显得虚伪、没心没肺。但我还是想祝福你们。狗日的2022就要过去了,愿大家渡尽劫波,在兔年的除夕焰火里陪孩子欢笑,在年夜饭里做好多道荤菜,假装生活没有困厄,没有离散,就像我们经历过战火和饥荒的祖辈许多年里做的那样,穿着围裙,越过灶火,朝不谙世事的雀跃的儿孙们,投去若无其事的苍凉一笑。

那么,别了,2022。我们继续往下一个庚年谋生,千山独行,不必相送。

01
1

我们的第四个五年计划

0
归档:2023年1月分类:点滴生活

今天是元旦,过去的一年经历了过山车式的体验,国内的疫情管制终于放开,虽然未来还有很多不确定,但是大方向完全正确。

我们全家去年也收获了很多,展望未来,小熊说要让我想想未来五年的计划,我总结了一下,所有的计划可以归为在AU:事业有成、学业有成、买房定居。

这也是我们对新年的愿望,我们必将实现,我们必须实现。

21
10

C#泛型接口的协变和逆变

0
归档:2022年10月分类:C#和.NET

一、协变和逆变是什么?

先从字面上理解 协变(Covariance)、逆变(Contravariance)。

co- 是英文中表示“协同”、“合作”的前缀。协变 的字面意思就是 “与变化的方向相同”。
contra- 是英文中表示“相反”的前缀,逆变 的字面意思就是是 “与变化方向相反”。

官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。

那么问题来了,这里的“变化方向”指的是什么?

C# 中对于对象(即对象引用),仅存在一种隐式类型转换,即 子类型的对象引用到父类型的对象引用的转换。这里的变化指的就是这种 子->父 的类型转换。

协变与逆变虽然从名字上看是两个完全相反的转换,但其实只是“子类型引用到父类型引用”这一过程在函数中使用的“两个不同阶段”而已,接下来将详细说明这点。

二、为什么需要协变和逆变

三、协变例子

四、逆变例子

五、.NET自带的协变和逆变委托和泛型

20
10

C#委托之Action和Func的用法

0
归档:2022年10月分类:C#和.NET

我们在使用委托的过程中,除了为每个参数和返回类型定义一个委托之外,也就是说为每一个方法(作为参数的方法)定义一个委托,我们还可以使用Action和Func委托。

泛型Action委托表示引用一个void返回类型的方法。Action委托类存在不同的变体,可以传递至多16种不同的参数类型,没有泛型参数的Action类可以调用没有参数的方法。例如:Action调用带一个参数的方法,Action<in T1,in T2>调用带两个参数的方法等

Func的用法和Action用法类似,但是Func表示引用一个带返回类型的方法,Func也存在不同的变体,至多可以传递16个参数类型和1个返回类型,例如:Func<in T1,out Resout>表示带一个参数的方法,Func<in T1,in T2,out Resout>表示调用带两个参数的方法。

总结 1:Action用于没有返回值的方法(参数可以根据自己情况进行传递);2:Func恰恰相反用于有返回值的方法(同样参数根据自己情况情况);3:记住无返回就用action,有返回就用Func

10
10

[转]Azure Container App 应用介绍

0
归档:2022年10月分类:C#和.NET

容器技术正日益成为打包、部署应用程序的第一选择。Azure提供了许多使用容器的选项。例如,我们可以使用Azure容器注册表来存储和管理Docker Images。Azure Container Instance或Azure应用服务可用于运行隔离容器。对于需要完整容器编排、自动缩放和服务发现的更复杂的场景,Azure Kubernetes服务是一个很好的选择。问题是,Azure Kubernetes虽然是托管的,但 用起来还是有些困难,开发人员必须得学习掌握一些运维知识。

2021年,Azure提出了新服务 Azure Container App。该服务旨在减少构建 AKS 应用程序所需的知识和配置量,从而可能降低解决方案成本并加快上市时间。

1,什么是 Azure Container App ??

Azure Container App 提供位于 AKS 服务之上的无服务器托管服务,允许您部署多个容器而无需处理底层基础结构。事实上,Azure Container App 甚至不向用户公开 Kubernetes API。

当我们在 Azure Container App中部署或更改容器时,该服务将自动创建应用程序的快照-----修订版,并在一个 pod 中运行它的容器。就像在 Azure Kubernetes 中一样,这些容器共享相同的应用程序生命周期、网络和磁盘。它们可以相互交流。此外,由于它与基于 Kubernetes 的事件驱动自动缩放的集成,该服务将根据 HTTP 并发请求数等指标自动增加/减少(不支持垂直缩放)与修订相关的 Pod 数量和内存使用。作为节省一些费用上开支,我们还可以将最小副本数设置为 0。如果应用程序没有请求,该服务会将活动 pod 的数量缩减为 0,我们无需支付任何费用。

同时多个 Azure Container App 也可以部署到单个环境中。通过这样做,它们将被置于同一个虚拟网络下并与外界隔离。为了提供监视功能,每个环境都有自己的 Log Analytics 工作区,该工作区与其中的 Azure Container App共享。对于熟悉 Kubernetes 的人来说,我们可以将 Azure Container App Environment 视为 Kubernetes Namespace,将 Azure Container App Revision 视为 Kubernetes Deployment。

最后就是,Azure Container App 将可用选项减少为一个简单的入口切换,一旦启用,它就会提供 HTTPS 入口和完全限定域名 (FQDN)。

2、修改

当我们在 Azure Container App 中部署或更改容器时,该服务会自动获取 Azure Container Instance 的不可变快照。然后它在一个单独的 pod 上部署一个新版本。但是,并非所有更改都会触发此行为。在 Azure Container App 中,我们可以区分两种类型的更改:

  1)修订范围更改。

  2)应用范围的变化。

当我们创建新版本时,旧版本的流量会完全转移到新版本。我们可以使用流量拆分规则来定义它们之间的流量平衡方式。这些包括将一定比例的流量引导到特定的修订版。

3、和 Dapr 集成

Azure Container App 提供与开源项目 Dapr(分布式应用程序运行时)的内置兼容性。启用后,Dapr 应用程序将与我们修订版一起部署,通过 HTTP 或 gRPC 提供对 Dapr API 提供的功能的访问。

三,结尾
  相对于操作有些复杂的 Azure Kubernetes 和昂贵的使用的定价,Azure Container App 这项服务变得越来越流行。目前,该服务作为公共预览版提供,因此我们已经可以开始使用它了。

作者:Allen

公告栏

欢迎大家来到我的博客,我是dodoro,希望我的博客能给你带来帮助。