我们的第四个五年计划
今天是元旦,过去的一年经历了过山车式的体验,国内的疫情管制终于放开,虽然未来还有很多不确定,但是大方向完全正确。 我们全家去年也收获了很多,展望未来,小熊说要让我想想未来五年的计划,我总结了一下,所有的计划可以归为在AU:事业有成、学业有成、买房定居。 这也是我们对新年的愿望,我们必将实现,我们必须实现。
今天是元旦,过去的一年经历了过山车式的体验,国内的疫情管制终于放开,虽然未来还有很多不确定,但是大方向完全正确。 我们全家去年也收获了很多,展望未来,小熊说要让我想想未来五年的计划,我总结了一下,所有的计划可以归为在AU:事业有成、学业有成、买房定居。 这也是我们对新年的愿望,我们必将实现,我们必须实现。
经过三年的漫长等待,澳洲移民局终于给我们发签了!!! 我们于2019年11月提交PR签证申请,年底新冠疫情笼罩国内,接着扩散到全世界,各国关闭边境,澳洲也经历了封锁和开放,今年年初工党上台,承诺加快签证审批,我们终于迎来曙光。 两个月前收到co的邮件,要求补充体检和无犯罪证明,现在终于正式获得了PR,想起第一次有migration的念头已经是五年前,小熊说我们的五年计划似乎都实现了。 世界杯揭幕战的时候,我脑子里闪过南非世界杯和巴西世界杯等等时刻,那时候我们全国、全球随便跑,当时突然觉得有一种想哭的感觉,这个世界原本不应该如此封闭,人不应该被困起来,那一晚我对完全的自由有了极大的渴望。 两周之后,国内居然突然以惊人的速度彻底放开,方向我支持,但速度太快了,但是箭已发出不可能回头,我们只能多做防护。 昨天世界杯决赛,梅西拿到了大力神杯,承载着80后青春记忆的一代球王终于圆梦。随着世界杯落下帷幕,也许真的可以看到世界慢慢恢复正常的曙光了,我对未来许下了美好的愿望,我们一定要实现,我们一定会实现。
一、协变和逆变是什么? 先从字面上理解 协变(Covariance)、逆变(Contravariance)。 co- 是英文中表示“协同”、“合作”的前缀。协变 的字面意思就是 “与变化的方向相同”。 contra- 是英文中表示“相反”的前缀,逆变 的字面意思就是是 “与变化方向相反”。 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。 那么问题来了,这里的“变化方向”指的是什么? 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
容器技术正日益成为打包、部署应用程序的第一选择。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。 ...
从提交PR申请今天,已经过去了将近三年时间!今天收到IMMI的邮件,要求补无犯罪记录证明和全家体检,其实这两项早在疫情前一个月我们提交申请的时候就已经完成,但是因为有时效性,只能重新补。 2019年底,眼看着马上要审理我们的case,国内突发疫情,澳洲移民局直接把中国所有的cases都hold on了。后来疫情蔓延至全球,澳洲关闭边境,所有offshore的cases都暂停。今年澳洲完全放开国门,前几个月大选换了总理,终于开始加速审理我们这些被滞留的cases,这一晃已经三年时间。 这三年深刻影响了每一个人,全球化停止了,随着各国民族主义的崛起,世界已经不再友好,一切都已经回不去了。而也正是在这三年时间,我静下来(重)读了很多书,从文学到中国文化、从历史到政治哲学,因为拥有科学上网的能力,能看到未删减的图书,得以获得信息全貌,逐渐形成自己牢固的思想。 今天已经预约体检,并申请了无犯罪记录证明,后续按部就班完成各项事宜,希望这次真的Granted Directly
之前记录的依赖注入太复杂,今天认真看了《C#高级编程》里面对依赖注入的解释,明显就简单很多。 1、什么是依赖注入?为什么需要它? 更快的开发周期需要单元测试和更好的可更新性。更改一些代码,不应该导致意外位罝出现错误。创建更模块化的、减少依赖项的应用程序,有助于防止这种错误。 依赖注入(Dependency Injection,DI)允许从类的外部注入依赖项,因此注入依赖项的类只需要知道一个协定(通常是C#接口)。这个类可以独立于其对象的创建。 依赖注入更便于进行单元测试。在单元测试中,只需要测试特定的类,需要的依赖项可以替换为包含测试数据的特殊模拟类。 还可以使用不同的实现区分生产模式和开发模式。例如,在生产过程中,可能需要访问SAP服务器,或者可能需要对所有开发人员都无法访问的特定活动目录进行身份验证。在开发的每个调试会话期间,都不希望等待成功的身份验证,也不需要SAP服务器开发用户界面。在这里,可以给相同的协定使用不同的实现来模拟身份验证,可以使用测试数据而不是访问SAP服务器。 也可以在不同的平台上使用不同的实现。例如,可以创建一个.NET标准库,在其中为UWP、WPF和Xamarin应用程序实现所有公共功能,并可以根据需要重定向到特定于平台的代码。 依赖注入还允许用自定义特性替换标准功能。ASP.NETCore和EntityFrameworkCore主要基于依赖注入。这些技术使用数百个协定一例如,来找到控制器,将HTTP请求映射到控制器,将接收到的数据转换为参数,将数据库表映射到实体类型等。使用不同的实现,可以轻松地替换自定义功能。 DI是敏捷软件开发和持续软件交付实践的核心模式。 依赖注入不需要依赖注入容器,但该容器有助于管理依赖项。 依赖注入容器管理的服务列表越来越长,就可以看到它的优点。ASP.NETCore和EntityFrameworkCore使用Microsoft.Exteosions.DependencyInjection作为容器来管理所有依赖项,以此管理数百个服务。 尽管依赖注入和依赖注入容器在非常小的应用程序中会增加复杂性,但是一旦应用程序变得更大,需要多个服务,依赖注入就会降低复杂性,并促进非紧密绑定的实现。 2、没有依赖注入 下面的示例没有使用依赖注入;稍后将更改它,以使用依赖注入。所用的服务实现在类GreetingService中定义。这个类定义了返回字符串的Greet方法: public class GreetingService { public string Greet(stringname)=>$"Hello,{name}"; } 类HomeController使用这个服务。在Hello方法中,实例化了GreetingService,并且调用Greet方法: public class HomeController { public string Hello(string name) { var service = new GreetingService(); return service.Greet(name); } } 下面看看Program类的Main()方法。其中实例化了HomeController,调用Hello方法,将结果写入控制台: static void Main() { var controller=new HomeController(); string result=controller.Hello("Stephanie"); Console.WriteLine(result); } 程序运行时,把Hello,Stephanie写入控制台。这有什么问题吗? HomeController和GreetingService是紧密稱合的。要用不同的实现取代HomeController中的GreetingService并不容易。 这个GreetingService是一个返回字符串的简单服务。在正常的应用程序中,场景通常更复杂。例如,GreetingService可能使用HTTP请求访问API服务,或者使用EntityFramewoik访问数据库。可能要更改在一个地方使用的服务,而不是査找使用服务的所有位置。 另外,为HomeController创建单元测试时,也会测试GreetingService。在单元测试中,希望仅测试单个类的方法的功能,而不需要使用其他依赖项。在HomeController中,不能很容易地为单元测试替换GreetingService。从技术上讲,为单元测试替换GreetingService方法的内部实现是可能的。使用Microsoft Fakes框架,可以通过替换GreetingSeivice类的特定方法和属性,来更改方法的实现。这个变更是在单元测试中定义的,并且只有在单元测试运行时才会发生:通过另一个方法来“伪造”原来的方法。其实这有更好的方法:使用依赖注入。 下一节将介绍如何更改此实现,以使用依赖注入。 3、使用依赖注入实现 下面使HomeController独立于GreetingService的实现。为此,可以创建接口IGreetingService,它定义了HomeController所需的功能: public interface IGreetingService { string Greet(stringname); } GreetingService现在实现了接口IGreetingService: public class GreetingService:IGreetingService { public string Greet(stringname)=>$"Hello,{name}"; } HomeController现在只需要对一个对象的引用,该对象实现了接口IGreetingService。它用HomeController的构造函数注入,分配给私有字段,通过方法Hello来使用: public class HomeController { private readonly IGreetingService _greetingService; public HomeController(IGreetingService greetingService) { _greetingService=greetingService?? throw new ArgumentMullException(nameof(greetingService)); } public string Hello(stringname) => _greetingService.Greet(name); } 在这个实现中,HomeController利用了控制反转的设计原理。HomeController没有像以前那样实例化GreetingService。相反,定义由HomeController使用的具体类的控件在外部给出;换句话说,控制是反转的。 ...
开发过程中,可能会遇到在https里面请求内容的时候报混合调用的错误,一般是因为网站启用了https,但是老的网页链接和请求中还有使用http的情况。接口会错block: mixed-content,图片则会报错:Mixed block。解决的办法有两种。 第一种, 页面的head中加入下面代码(将调用的http请求升级成https请求并调用): <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 这是最方便快捷的,也是很有效的办法。 第二种, 如果是接口,可以通过本地后端(将本地后端当成service中间层),从后端再去调用其他服务器的http请求。
1、添加log4net程序集 通过nuget添加,可以直接在程序集引用里搜索nuget包安装,也可以通过命令行安装,这里使用命令行:PM> Install-Package log4net 2、添加log4net.config配置文件 创建一个log4net.config文件,保存在项目的根目录: <log4net> <root> <level value="ALL" /> <appender-ref ref="console" /> <appender-ref ref="file" /> </root> <!--File Appender--> <appender name="file" type="log4net.Appender.RollingFileAppender"> <file value="main.log" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="5" /> <maximumFileSize value="25MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %level %logger - %message%newline" /> </layout> </appender> <!--Console appender--> <appender name="console" type="log4net.Appender.ManagedColoredConsoleAppender"> <mapping> <level value="INFO" /> <forecolor value="Green" /> </mapping> <mapping> <level value="WARN" /> <forecolor value="Yellow" /> </mapping> <mapping> <level value="ERROR" /> <forecolor value="Red" /> </mapping> <mapping> <level value="DEBUG" /> <forecolor value="Blue" /> </mapping> <layout type="log4net.Layout.PatternLayout"> <conversionpattern value="%date [%thread] %-5level - %message%newline" /> </layout> </appender> </log4net> 3、加载log4net的配置的并创建相关实例 这里有两种办法,第一种最简单 ,这种情况适用于控制台应用程序,简单明了,直接用加载到程序集中: ...
一、耐心、认真地去“听”你的孩子讲话 有时当妈妈一边炒菜一边盛饭时,孩子在想跟妈妈说些什么时,妈妈有时是不经心地听着,有时会打断她,反而请她帮忙摆桌吃饭,但从未停下来,专心去“听”她想说的话,除非她说的话,真是什么天大的好消息(不过,这种机率低于百分之一)。 这里不是教您一定要停下手边所做的,但你可给孩子一个“确定”的时间,比如:“好,等我把饭菜摆好。”或是“再给我一分钟。“当然,最好是立即去“听”孩子要说的。 因为,你一次,二次,三次地忽略了他们后,他们便会慢慢地失去了"告诉你”的兴趣。另外,在“听”时,最好做目光接触,要孩子知道你是直的愿意听。很多时候,孩子不过想说你觉得不太要紧的事,但对他们而言,却是重要的。如果你没有经常拒绝他们,当他们真遇到困难时,自然就会地来找你谈了。 二、有些话不能说,以免伤害到孩子的感情 家长不要说一些孩子最不想听的话,即使在盛怒的时候,也要思考话语的轻重,以免伤害孩子的感情。 另外,孩子的世界与想法是和大人们不同的,当孩子很认真地告诉你什么时,你如果取笑孩子,或者有轻蔑或不相信的态度,也会伤害孩子,这样孩子以后也就不再愿意跟你谈了。 三、有意识地与孩子进行沟通,主动分享自己的感受 多与孩子说说自己的感受和以往的经历,让孩子走进自己,向孩子表达自己的期待和需求。 当然,做父母的,不需要把心中的担心向孩子表明,去增加孩子担忧的心理负担,但有时不妨主动地与孩子分享自己的心情、感受,及对事情的看法,孩子当然也就比较容易向你诉说他的心情、感受与看法了。 四、重视沟通的方法,别问一些太空洞的问题 譬如“今天如何?”“学校好吗?”也别常用,“为什么?”因为孩子会不自觉地想保护自己。以询问孩子一些有趣的、愉快的事情作为聊天的开场白。愉快的开始,能营造良好的沟通氛围,促进亲子沟通。 了解孩子的兴趣,了解现在孩子与同龄人中流行的东西 ,包括儿歌、动画片,故事书等,与孩子一起做他感兴趣的事,进行积极沟通,让孩子感受到父母对自己的关心,他会更愿意与家长沟通。 五、了解孩子的想法,理解孩子要表达的意思 由于孩子的表达能力条理性较差,因此孩子有时不能清晰表达自己 。家长要耐心等孩子把话说完,把“零散”的东西拼凑起来,准确理解孩子要表达的意思。 大部分时间,孩子只是想从他信任的成人中,确定自己的想法与做法 。所以,家长可在了解情况后,做个回答或支持。