0%

Azure官方文档token overview

JWT所述,JWT包含三个部分,一个标头,一个正文和一个签名。签名段可用于验证令牌的真实性,以便您的应用程序可以信任它。Azure AD B2C通过使用行业标准的非对称加密算法(例如RSA 256)对令牌进行签名。
header包含有关用于对令牌进行签名的密钥和加密方法的信息:

1
2
3
4
5
{
"typ": "JWT",
"alg": "RS256",
"kid": "GvnPApfWMdLRi8PDmisFn7bprKg"
}

Azure AD B2C具有一个OpenID Connect元数据EndPoint。大概长这样子:
1
https://qqstudio.b2clogin.com/qqstudio.onmicrosoft.com/B2C_1_basic_sign_up_and_sign_in/v2.0/.well-known/openid-configuration

通过此EndPoint,可以get到有关Azure AD B2C的信息。此信息包括端点,令牌内容和令牌签名密钥。
其中jwks_uri提供用于签署令牌的一组公共密钥的位置。
1
https://qqstudio.b2clogin.com/qqstudio.onmicrosoft.com/b2c_1_basic_sign_up_and_sign_in/discovery/v2.0/keys

jwks_uri如上格式,建议通过get元数据文档并解析以动态获取jwks_uri,而不要写死。

StackOverflow 上有个现成的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
"https://testb2ctenant05.b2clogin.com/testB2CTenant05.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_test",
new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever());
CancellationToken ct = default(CancellationToken);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
var discoveryDocument = await configurationManager.GetConfigurationAsync(ct);
var signingKeys = discoveryDocument.SigningKeys;
var validationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateIssuer = true,
ValidIssuer = discoveryDocument.Issuer,
ValidateIssuerSigningKey = true,
IssuerSigningKeys = signingKeys,
ValidateLifetime = true,

};

var principal = new JwtSecurityTokenHandler()
.ValidateToken(token, validationParameters, out var rawValidatedToken);

Jim Xu’s Answer

用例描述:

  • 使用非法字符串冒充access token,异常:decode fail
  • 使用其他来源的(比如其他talent)的token,异常:unmatch siguanture
  • 使用正确token 获得principal对象

回顾一下,对于非对称加密,签名用私钥产生,私钥绝对隐藏且不可被反推,公开公钥,任何人可以使用公钥验证签名。

云管理员,与普通IT管理员相比,不需要过多关注具体硬件软件的内容,云管理员管理着包括存储、网络连接和计算云功能在内的云服务,并对整个IT生命周期中的每项服务具有深入了解

他们接收最终用户对接入新云应用程序的请求,为其提供服务建议

Overview

There are 7 modules to learn:

  • Prerequisites for Azure administrators
  • Manage identities and governance in Azure
  • Implement and manage storage in Azure
  • Deploy and manage Azure compute resources
  • Configure and manage virtual networks for Azure administrators
  • Monitor and back up Azure Resources
    即Azure的订阅和资源,管理身份,实施和管理存储,虚拟机,虚拟网络, 监视和备份
    https://docs.microsoft.com/en-us/learn/certifications/exams/az-104

    Azure Policy

    参考利用 Azure Policy 进行云上资源实时控制及合规监控

    Azure Policy的工作原理是选择或新建一个策略或计划(计划是一组策略的集合),分配给指定范围的资源,然后定期(24小时左右)Policy会检查这些资源是否符合策略或计划,并列出不合规项。

Az104 Q5 使用resource policy修改虚拟网络的限制

类似的: 蓝图blue print,为某个订阅制订蓝图(和策略一样,azure上由很多已定义的)
Monitor里的Alert,为某个特定资源添加警报

虚拟机

可用性、可用区和可用集

可用性是可供使用的时间段的百分比,任意时间可访问的服务即100%可用性

因故障、因物理故障触发的自动迁移、定期更新都有可能造成资源可用性达不到100%

管理可用性
创建和部署高度可用的虚拟机

可用性区域:区域中的唯一物理位置,每个区域由一个或多个数据中心组成,这些数据中心配置了独立电源,冷却和网络。区域中可用性区域的物理隔离可以在发生数据中心故障的情况下保护应用程序和数据。 区域冗余服务可跨可用性区域复制应用程序和数据,以防范单点故障。

  • 更新域和容错域的组合
  • 当两个或更多个 VM 部署在一个 Azure 区域中的两个或更多个可用性区域时,可获得99.99% VM 运行时间 SLA(service-level agreement, 服务级别协议)

使用可用性区域创建vm settings—>High availability—>选择一个编号的区域 详细

而可用性集是一种逻辑分组功能,将在物理层面相分离的vm连接到一起,如果运行服务器的其中之一的物理硬件有问题,可以确信服务器的其他实例保持运行,因为它们位于不同的硬件上。使用命令创建可用性集 详细

Microsoft 为部署在可用性中的多实例 VM 提供 99.95% 的外部连接性服务级别协议 (SLA)。 这意味着,对于要应用的 SLA,必须在可用性集中至少部署两个 VM 实例。

You plan to deploy three Azure virtual machines named VM1, VM2, and VM3. The virtual
machines will host a web app named App1.
You need to ensure that at least two virtual machines are available if a single Azure datacenter
becomes unavailable.
What should you deploy?
A. all three virtual machines in a single Availability Zone
B. all virtual machines in a single Availability Set
C. each virtual machine in a separate Availability Zone
D. each virtual machine in a separate Availability Set

Answer is B.

  • 可以自己提供非官方镜像用于创建虚拟机

    It is possible to change the size of a VM after it’s been created, but the VM must be stopped first. So, it’s best to size it appropriately from the start if possible.调整vm配置需要停机

  • 几个size:普通的(B,D..)大数据存储(L-series),图形渲染(N-series),高性能(H-series)

    You can store data on the primary drive along with the OS(默认挂载/dev/sda,最大2018G), but a better approach is to create dedicated data disks(可以挂几万GiB).

  • 关于硬盘的unmanaged(以容量和IO计费)和managed(提供存储的伸缩性,提供快照和备份等)
  • ssh
    创建虚拟机时可以选择生成key pair,创建完成后下载pem文件用于连接,抑或在本地生成key pair使用其中的public key创建
    连接上VM使用下述方式添加更多的public key
    1
    2
    3
    4
    # 创建公钥私钥对
    ssh-keygen -t rsa -b 4098
    # 将公钥贴到虚拟机上
    ssh-copy-id -i ~/.ssh/id_rsa.pub azureuser@myserver
  • 虚拟机创建完成的初始网络状态是:Outbound request are allowed. Inbound traffic is only allowed from within the virtual network.即出站任意,入站限制为允许虚拟网络内的访问
  • Windows虚拟机相关:远程桌面连接(RDP 3389); 网络安全组(NSG)设置入站出站规则,软件防火墙

    The rules are evaluated in priority-order, starting with the lowest priority rule. Deny rules always stop the evaluation. The last rule is always a Deny All rule.That means to have traffic pass through the security group you must have an allow rule or it will be blocked by the default final rule. 规则使用优先级层叠,若无允许则被底层规则(the final rule)禁止

虚拟机的备份(存目)

Networking

学习目标:

  • 概念:网络协议和网络标准。
  • 网络拓扑类型(网格,总线,星形)
  • 网络设备。
  • 网络通信原则(如 TCP/IP、DNS 和端口)。
  • !以上组件在 Azure 网络上的映射和配置。

Azure虚拟网络

Bridge(网桥),将网络划分为网段,在其之间过滤和推送数据包,数据流向通过MAC地址决定,可以减少不必要的网络交通以提升网络传输性能。
HUb(指网络集线器),充当网络上的多端口中继器,用以连接多个设备并构建网络布局,集线器将以固定的速度运行即所连接的最慢的网络设备的速度
Switch(交换机),是网桥和集线器的结合

tip:进入命令行help可看到所有支持的命令,用tcping代替ping

协议:

  • 邮局协议 3(Post Office Protocol 3, POP3) 用于接收邮件
  • 简单邮件传输协议 (SMTP) 使用邮件服务器发送邮件
  • 交互式邮件访问协议 (IMAP) 管理邮箱
  • 安全套接字层 (Secure Socket Layer, SSL) 标准的加密和安全性协议,提供计算机和Internet访问目标服务器或设备之间的安全的加密连接
  • 传输层安全 (Transport Layer Security, TLS) SSL的后继者
  • 安全超文本传输协议 (HTTPS) 使用SSL或TLS加密的HTTP
  • 安全外壳 (Secure Shell, SSH)
  • Kerberos 验证协议 通过密钥加密为cs应用提供鲁棒的认证
  • 简单网络管理协议 (SNMP) 允许从网络上的设备收集数据以进行管理
  • Internet 控制消息协议 (ICMP) 允许网络的设备发送警告或错误

IPS模型:

DNS(Domain Name System)分散式查找服务,将用户可读的域名或 URL 转换为承载站点或服务的服务器的 IP 地址。

  • A SOA寻址
  • AAAA IP寻址
  • CNAME 域名别名
  • NS 名称服务器
  • MX SMTP 电子邮件

    网络安全

    学习目标
  • C/S网络模型:请求-响应;P2P(Peer-to-Peer);发布-订阅
  • 认证和授权
  • 网络防火墙类型
  • 监控项目
  • 在Azure上的映射

关于认证:

  • 密码认证
  • 双因素(two-factor)认证:如账户密码+邮箱/手机认证
  • token authentication
  • 生物识别认证(Biometric authentication):如用指纹、语音或人脸识别
  • 事务认证(Transactional authentication) 通常用于提供额外的认证保护,如在工作时间范围内允许访问
  • 图灵测试(CAPTCHA)解释看到的信息,通常是模糊的文字或场景中的特征,CAPTCHA可能会给存在视力障碍的用户带来困难

认证协议:

  • Kerberos
  • TLS/SSL

授权:
私以为其概念是对已持有的认证身份标记所赋予的权限

防范目标和措施:

  • any user, 访问控制(access control)即对用户设置访问相应资源的权限级别
  • 恶意软件,杀软
  • 应用程序漏洞
  • 行为分析,创建安全策略识别具有潜在危险的行文
  • 邮件,识别可疑邮件和发信人
  • 入侵检测(存目)

防火墙:

  • 应用程序层防火墙 如检测HTTP请求的插件或筛选器
  • 数据包筛选防火墙 如检测数据包
  • 线路级(circuit-level)防火墙 如检查TCP/UDP连接的源、目标、用户等是否符合既定规则
  • 代理服务器防火墙 以代理控制信息进出网络,因此可以监视、筛选和缓存网络上任意类型设备的internet访问
  • stateful firewalls & next-generation firewalls

通过配置与 Azure 的“站点到站点 VPN”连接,将本地网络连接到 Azure 虚拟网络。

亦可通过vpn配置实现点(client)到站点的连接

Notice:

  • 关键 Azure 服务只连接 Azure 虚拟网络,不连接公共 Internet,比如Azure SQL数据库,Azure Storage等
  • 尽可能禁用SSH/RDP 访问,应先创建点到站点 VPN 连接,然后再为远程管理启用 SSH/RDP。

Monitor:

  • SNMP 简单网络管理协议,前文已述,允许访问网络设备的信息
  • Syslog 允许设备发送事件,用于事件日志记录
  • Azure Monitor是网络监控解决方案,包含Log Analytics工具,用以查询、分析日志

    PowerShell

    学习目标
  • 使用Azure PowerShell 连接/操作 Azure资源
    Azure Portal,Azure CLI,Azure PowerShell是管理Azure资源的三种工具,相比Azure Portal页面,脚本工具因可以编写逻辑而更适合进行批量操作,以及自动化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Import-Module Az
    Connect-AzAccount
    Get-AzResourceGroup
    ... <-- 这里会列出资源组
    Get-Credential
    ... <-- 这里设置访问虚拟机的凭据
    New-AzVM -Name "testvm-eus-01" -ResourceGroupName "learn-940e9418-9b64-4c5b-a12c-a136ccb641da" -Credential (Get-Credential) -Location "East US" -Image UbuntuLTS -OpenPorts 22
    $vm = (Get-AzVM -Name "testvm-eus-01" -ResourceGroupName learn-940e9418-9b64-4c5b-a12c-a136ccb641da)
    $vm | Get-AzPublicIpAddress
    ssh QQs@13.92.231.172
    ... <-- 使用ssh连接虚拟机
    Stop-AzVM -Name $vm.Name -ResourceGroup $vm.ResourceGroupName
    Remove-AzVM -Name $vm.Name -ResourceGroup $vm.ResourceGroupName
    $vm | Remove-AzNetworkInterface –Force
    Get-AzDisk -ResourceGroupName $vm.ResourceGroupName -DiskName $vm.StorageProfile.OSDisk.Name | Remove-AzDisk -Force
    Get-AzVirtualNetwork -ResourceGroup $vm.ResourceGroupName | Remove-AzVirtualNetwork -Force
    Get-AzNetworkSecurityGroup -ResourceGroup $vm.ResourceGroupName | Remove-AzNetworkSecurityGroup -Force
    Get-AzPublicIpAddress -ResourceGroup $vm.ResourceGroupName | Remove-AzPublicIpAddress -Force
    注意 上面停止并移除虚拟机后,其他相关资源如网络接口、托管磁盘、网络安全组、公共IP另需手动删除
    似乎应该具备编写powershell脚本的能力,知乎:PowerShell有没有必要学?
    1
    2
    3
    4
    5
    6
    7
    8
    param([string]$resourceGroup) // 获取变量参数
    $adminCredential = Get-Credential -Message "Enter a username and password for the VM administrator."
    For ($i = 1; $i -le 3; $i++)
    {
    $vmName = "ConferenceDemo" + $i
    Write-Host "Creating VM: " $vmName
    New-AzVm -ResourceGroupName $resourceGroup -Name $vmName -Credential $adminCredential -Image UbuntuLTS
    }

Q: Admin1 attempts to deploy an Azure Marketplace resource by using an Azure Resource Manager template. Admin1 deploys the template by using Azure PowerShell and receives the following error message: “User failed validation to purchase resources. Error message: “Legal terms have not been accepted for this item on this subscription. To accept legal terms, please go to the Azure portal (http:// go.microsoft.com/fwlink/?LinkId=534873) and configure programmatic deployment
for the Marketplace item or create it there for the first time.”
You need to ensure that Admin1 can deploy the Marketplace resource successfully.
What should you do?
Answer is: From Azure PowerShell, run the Set-AzMarketplaceTerms cmdlet

数据和存储

数据:结构化数据、半结构化数据(也就是NoSQL数据,如Json数据,Xml数据)、非结构化数据
事务数据库:联机事务处理(Online Transaction Processing,OLTP)系统和联机分析处理(Online Analytical Processing,OLAP)系统,通常情况下,前者服务于较大量的用户,响应更快,可用性更高,处理大量数据(handle large volumns of data),后者用于处理大型复杂事务(handle large and complex transactions)
建议使用Azure Cosmos DB管理NoSQL数据,使用Azue Blob Storage管理文件数据,结构化数据使用Azure SQL Database, Azure SQL Database可以认为是云端托管的sqlserver

订阅

AZ104 Q9 Only a global administrator can add users to this tenant.
跨订阅移动资源,虚拟机、存储、虚拟网络、托管磁盘(managed disk)、Recovery Service均可移动 Microsoft Docs:跨订阅移动方案

Azure Backup

AZ104 Q7 Azure Backup 执行备份并不受限于虚拟机的os,是否在运行。
AZ104 Q8 Azure Recovery Vault 如果数据源位于多个区域中,请为每个区域创建恢复服务保管库

unachieved

You have a Microsoft 365 tenant and an Azure Active Directory (Azure AD) tenant named
contoso.com.
You plan to grant three users named User1, User2, and User3 access to a temporary Microsoft SharePoint document library named Library1. You need to create groups for the users. The solution must ensure that the groups are deleted automatically after 180 days.
Which two groups should you create? Each correct answer presents a complete solution.
A. an Office 365 group that uses the Assigned membership type
B. a Security group that uses the Assigned membership type
C. an Office 365 group that uses the Dynamic User membership type
D. a Security group that uses the Dynamic User membership type
E. a Security group that uses the Dynamic Device membership type

hint:Microsoft 365 组过期策略 answer is AC

解析JWT token —> jwt.io

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

  • “紧凑地、自包含地形式” 自包含即中间部分包含部分用户信息
  • 通过JSON形式作为web应用中的令牌,用于在各方之间安全地传输信息

结构:
以.分隔地三个部分:标头header,载荷payload,签名signature 三部分均以base64编码

标头:如下的编码描述

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

载荷:可以放user profile中的非敏感信息
签名:将前两部分信息连同加密salt使用密钥加密生成签名,如
HMACSHA256(base64UrlEncode(header)+’.’+base64UrlEncode(payload).secret)

解析后的json形如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"iss": "https://csdentaldevb2c.b2clogin.com/ea520207-3fcd-4afc-9b75-90139cd87407/v2.0/",
"exp": 1632306604,
"nbf": 1632303004,
"aud": "5d91d9f1-d3f0-44bb-93ab-1db127a11b35",
"idp": "LocalAccount",
"oid": "ae0dff61-7c3d-460e-87ad-f2567dd17b6f",
"sub": "ae0dff61-7c3d-460e-87ad-f2567dd17b6f",
"emails": [
"csdealer@yopmail.com"
],
"tfp": "B2C_1_CloudFx-ROPC",
"scp": "User.Standard",
"azp": "23ed21b8-c34d-4319-896e-0ced35ea6701",
"ver": "1.0",
"iat": 1632303004
}

json中的这些属性成为claim

  • iss 即issuer 令牌的发布服务
  • exp 即expiration time 有效期
  • nbf 即not valid before 生效期
  • aud 即audience 令牌的接受者,或者受众

参考 .net core 中的缓存内存

1
2
3
4
5
6
7
8
9
10
using Microsoft.Extensions.Caching.Memory;

public class HomeController : Controller
{
private IMemoryCache _cache;

public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}

CacheKeys API
1
2
3
4
5
6
7
8
9
10
11
12
13
public static class CacheKeys
{
public static string Entry { get { return "_Entry"; } }
public static string CallbackEntry { get { return "_Callback"; } }
public static string CallbackMessage { get { return "_CallbackMessage"; } }
public static string Parent { get { return "_Parent"; } }
public static string Child { get { return "_Child"; } }
public static string DependentMessage { get { return "_DependentMessage"; } }
public static string DependentCTS { get { return "_DependentCTS"; } }
public static string Ticks { get { return "_Ticks"; } }
public static string CancelMsg { get { return "_CancelMsg"; } }
public static string CancelTokenSource { get { return "_CancelTokenSource"; } }
}

缓存一个时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DateTime cacheTiming;

// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
cacheEntry = DateTime.Now;

// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(3));

// Save data in cache.
_cache.Set(CacheKeys.Entry, cacheTiming, cacheEntryOptions);
}

取出缓存
1
var timing = _cache.Get<DateTime?>(CacheKeys.Entry);

可调过期(slide expiration)时间和绝对过期(absolute expiration)时间

关于section

EMSCRIPTEN_KEEPALIVE宏

enscripten embind

C++暴露接口的一种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <emscripten/bind.h>

using namespace emscripten;

#include "../wrapper/DoSomething.cpp"

// binding code
EMSCRIPTEN_BINDINGS(DoSomething)
{
class_<DoSomething>("DoSomething")
.constructor()
.function("SetInputData", &DoSomething::SetInputData)
.function("DoAction", &DoSomething::DoAction)
.function("GetOutput", &DoSomething::GetOutput);
}

上述代码将C++类DoSomething中的方法SetInputData,DoAction,GetOutput暴露在wasm模块中

Javascript

window.requestAnimationFrame

顾名思义用于动画帧的绘制, 类似于setInterval,传入回调函数,该回调函数将会在下一次浏览器尝试重新绘制当前帧动画时被调用

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
//迭代调用以使dom持续更新

<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
let start = null;
let element = document.querySelector('div');

const step = (timestamp) => {
if (!start) start = timestamp;
let progress = timestamp - start;
element.style.left = Math.min(progress / 10, 200) + 'px';
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}

window.requestAnimationFrame(step);
</script>
</html>

Performance API

performance.timing
performance.now()返回当前时刻距离 “time origin” 所经过的毫秒数,以此可以计算代码执行所花时间,精度大于Date.now()

requestIdleCallback

传入一个回调函数,在浏览器的空闲时段内调用的函数排队。这使开发者能够在主事件循环上执行后台和低优先级工作,而不会影响延迟关键事件,如动画和输入响应。

TypedArray

类型化数组,其实例描述底层的二进制数据缓冲区的类数组视图。

实际上并没有TypedArray这个全局属性或者构造方法,可以认为是Int8Array,Uint32Array等对象的实例化数组的统称

1
2
3
4
5
6
7
8
9
10
11
12
13
const DEFAULT_INDEX = 0;
// Way one:
const int8Arr = new Int8Array(10);
int8Arr[DEFAULT_INDEX] = 16;
console.log(int8Arr); // Int8Array [16, 0, 0, 0, 0, 0, 0, 0, 0, 0]
int8Arr[0]=256, int8Arr[1]=257;
console.log(int8Arr); // Int8Array(10) [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

// Way two:
const buffer = new ArrayBuffer(16);
uintArray = new Uint8Array(buffer); // Uint8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
uintArray.set([255,255,255],4)
console.log(uintArray); // Uint8Array(16) [0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Way two中,ArrayBuffer 的构造函数其参数指定了该 ArrayBuffer 所能够存放的单字节数量,因此在“转换到”对应的 TypedArray 时,一定要确保 ArrayBuffer 的大小是 TypedArray 元素类型所对应字节大小的整数倍。

TypedArray.prototype.set, 方法接受两个参数,第一个参数为将要进行数据读取的 JavaScript 普通数组;第二个参数为将要存放在类型数组中的元素偏移位置。

可以作为类型化数组的内置对象

  • Int8Array
  • Uint8Array
  • Uint8ClampedArray
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array

    C/C++

    对于C++的函数重载,C++编译器通常使用名为 “Name Mangling” 的机制,在编译的可执行文件中区分同名函数

    使用extern “C” {}用以避免“Name Mangling”处理:由于在这个特殊的结构中,C++ 编译器会强制以 C 语言的语法规则,来编译放置在这个作用域内的所有 C++ 源代码。而在 C 语言的规范中,没有“函数重载”这类特性,因此也不会对函数名进行 “Name Mangling” 的处理。

    编译优化

    DCE(Dead Code Elimination)

    在诸如 Clang / GCC 等编译器中,我们通常可以为编译器指定一些有关编译优化的标记,以让编译器可以通过使用不同等级的优化策略来优化目标代码的生成。而诸如 -O0 / -O1 / -O2 一直到 -Os 与 -O4 等选项,便是这些优化标记中的一部分。

    原码 反码 补码

    原码符号位不变 逐位取反—> 反码

    反码+1 —> 补码

    访问控制列表

    ACL(Access Control List)

    堆栈机、寄存器机和累加器机

显然,.Net Core开发过程中,使用Visual Studio提供的近乎完美IDE,build和deploy都非常简单,如果说是用jenkins进行持续集成,那便相当于用脚本完成更新源码—构建—部署等过程。

jenkins ant

Apache Ant,是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发。由Apache软件基金会所提供。默认情况下,它的buildfile(XML文件)名为build.xml。——————wiki

build.xml定义了若干步骤(即target),以xml节点格式定义每个步骤的目录,执行程序,以及参数等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" ?> 
<project name="Hello World" default="execute">

<target name="init">
<mkdir dir="build/classes"/>
<mkdir dir="dist"/>
</target>
<target name="compile" depends="init">
<javac srcdir="src" destdir="build/classes"/>
</target>

<target name="compress" depends="compile">
<jar destfile="dist/HelloWorld.jar" basedir="build/classes" />
</target>

<target name="execute" depends="compile">
<java classname="HelloWorld" classpath="build/classes"/>
</target>

</project>

在Jenkins中可以配置使用Apache Ant,在构建时便可以使用build.xml来管理步骤
JenkinsAnt
源码目录build/build.xml:
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
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0"?>

<project name="PartnerPortal" default="PartnerPortal" basedir=".">
<description>
PartnerPortal Daily Build File.
</description>

<property file="build.properties"/>

<target name="build_partner_portal" description="Build CS ScanFlow with Microsoft Visual Studio">
<echo message=""/>
<echo message="======================================================="/>
<echo message=" build CSD PP x64 "/>
<echo message="======================================================="/>
<echo message=""/>
<echo message="MSVC : ${msbuild.exe}"/>
<echo message="root : ${root_dir}"/>
<exec dir="." executable="restore_dotnet.bat" failonerror="true" />
<exec dir="." executable="${msbuild.exe}" failonerror="true">
<arg line="../CSD.PartnerPortal.sln /property:Configuration=Release"/>
</exec>
</target>

<target name="restore_envirement" description="restore dotnet">
<echo message=""/>
<echo message="======================================================="/>
<echo message=" restore dotnet "/>
<echo message="======================================================="/>
<echo message=""/>
<exec dir="." executable="restore_dotnet.bat" failonerror="true" />
</target>

<target name="publish_to_server" description="publish to server">
<echo message=""/>
<echo message="======================================================="/>
<echo message=" publish start "/>
<echo message="======================================================="/>
<echo message=""/>
<exec dir="." executable="publish.bat" failonerror="true" />
</target>

<target name ="PartnerPortal" description="Build solution">
<antcall target="restore_envirement" />
<antcall target="build_partner_portal" />
<antcall target="publish_to_server" />
</target>

</project>

build/restore_dotnet.bat:
1
dotnet restore ../CSD.PartnerPortal.sln

build/publish.bat:
1
dotnet publish --no-build -c Release "..\CSD.PartnerPortal.csproj" /p:PublishProfile="..\Properties\PUblishProfiles\CSDPPci - Web Deploy.pubxml" /p:Password=xxxxxxxxxxxxxxxxxxxxxxxxxxx

项目的Properties目录下的 .pubxml配置:
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
<?xml version="1.0" encoding="utf-8"?>

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<ResourceId>/subscriptions/subscriptionid01/resourceGroups/resourcegroupname01/providers/Microsoft.Web/sites/CSDPPci</ResourceId>
<ResourceGroup>resourcegroupname01</ResourceGroup>
<PublishProvider>AzureWebSite</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://csdppci.azurewebsites.net</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>2df39477-f1f3-4522-9ca7-d0eefb5b16b7</ProjectGuid>
<MSDeployServiceURL>csdppci.scm.azurewebsites.net:443</MSDeployServiceURL>
<DeployIisAppPath>CSDPPci</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>$CSDPPci</UserName>
<_SavePWD>True</_SavePWD>
<_DestinationType>AzureWebSite</_DestinationType>
<InstallAspNetCoreSiteExtension>False</InstallAspNetCoreSiteExtension>
</PropertyGroup>
</Project>

架构视图

设计文档中要附有大量、各种各样的图,目的是为了与包括开发,项目,dba等角色达成更好的沟通

  • 逻辑视图
  • 开发视图
  • 过程视图(如泳道图)
  • 物理视图
  • 场景视图

Wireframe

XMLHttpRequest

XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。尽管名称如此,XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。它甚至支持 HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。

1
2
3
4
5
6
7
8
9
function reqListener () {
console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/getsomething");
oReq.responseType = "json";
oReq.send();

发送
1
2
3
var xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.send(data);

ResizeObserver

示例 ResizeObserver
调用构造方法返回一个ResizeObserver对象,传入回调函数(entries)=>{},即当监听到目标width height改变时,执行该函数,参数entries为ResizeObserverEntry接口的集合,可以访问真正在观察的 Element 或 SVGElement 最新的大小

1
2
3
4
5
6
7
8
9
10
11
12
const observer = new ResizeObserver(entries=>{
for (let entry of entries) {
if(entry.contentBoxSize) { // 内容盒尺寸
h1Elem.style.fontSize = `${Math.max(1.5, entry.contentBoxSize.inlineSize / 200)}rem`; // 前文某标题const h1Elem = document.querySelector('h1');
pElem.style.fontSize = `${Math.max(1, entry.contentBoxSize.inlineSize / 600)}rem`; // 前文某段文字const pElem = document.querySelector('p');
} else {
h1Elem.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 200)}rem`;
pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
}
}
})


关于内容盒和边框盒