0%

  • 不抽烟
  • 不喝酒
  • 尽量全素食,少吃不吃肉蛋奶,保持清淡,低糖少油少盐,粗粮+蔬菜+水果+坚果,
  • 每天晒太阳20分钟
  • 每天高强度运动一次,比如引体向上十个,俯卧撑30个,快速冲刺200米,保持身体战斗力
  • 睡前泡脚十五分钟
  • 少发脾气
  • 培养一个有益的爱好,弹琴,书法,摄影,球类运动均可
  • 早睡
  • 除非必要不玩手机,抖音
  • 经常去绿色的大自然活动,减少室内活动

Javascript is a single threaded language. This means it has one call stack and one memory heap. As expected, it executes code in order and must finish executing a piece code before moving onto the next. It’s synchronous, but at times that can be harmful. For example, if a function takes awhile to execute or has to wait on something, it freezes everything up in the meanwhile.

A good example of this happening is the window alert function. alert("Hello World")

You can’t interact with the webpage at all until you hit OK and dismiss the alert. You’re stuck.

So how do we get asynchronous code with Javascript then?

Well, we can thank the Javascript engine (V8, Spidermonkey, JavaScriptCore, etc…) for that, which has Web API that handle these tasks in the background. The call stack recognizes functions of the Web API and hands them off to be handled by the browser. Once those tasks are finished by the browser, they return and are pushed onto the stack as a callback.

Open your console and type window then press enter. You’ll see most everything the Web API has to offer. This includes things like ajax calls, event listeners, the fetch API, and setTimeout. Javascript uses low level programming languages like C++ to perform these behind the scenes.

Let’s look at a simple example, run this code your console:

1
2
3
4
5
console.log("first")
setTimeout(() => {
console.log("second")
}, 1000)
console.log("third")

What did we get back?

1
2
3
4
first
third
undefined
second

Feels odd, right? Well, let’s break this down line by line:

console.log("first") is on the stack first, so it gets printed. Next, the engine notices setTimeout, which isn’t handled by Javascript and pushes it off to the WebAPI to be done asynchronously. The call stack moves on without caring about the code handed off to the Web APIs and console.log("three") is printed.

Next, the Javascript engine’s event loop kicks in, like a little kid asking “Are we there yet?” on a road trip. It starts firing, waiting for events to be pushed into it. Since the setTimeout isn’t finished, it returns undefined, as the default, well because it hasn’t been given the value yet. Once the callback finally does hits we get console.log("second") printed.

There’s a really good site that slows this all down and shows this happening.

http://latentflip.com/loupe

I suggest playing around in this sandbox to help solidify your understanding. It helped me get a feel for how asynchronous code can work with Javascript being single threaded.

Ref:https://dev.to/bbarbour/if-javascript-is-single-threaded-how-is-it-asynchronous-56gd

https://stackoverflow.com/questions/51007636/how-javascript-single-threaded-and-asynchronous

JavaScript has a concurrency model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.This model is quite different from models in other languages like C and Java.

Run Time Concepts

Stack, heap, queue

Stack

Function calls form a stack of frames.

1
2
3
4
5
6
7
8
9
10
11
function foo(b) {
let a = 10
return a + b + 11
}

function bar(x) {
let y = 3
return foo(x * y)
}

const baz = bar(7) // assigns 42 to baz

Copy to Clipboard

Order of operations:

  1. When calling bar, a first frame is created containing references to bar‘s arguments and local variables.
  2. When bar calls foo, a second frame is created and pushed on top of the first one, containing references to foo‘s arguments and local variables.
  3. When foo returns, the top frame element is popped out of the stack (leaving only bar‘s call frame).
  4. When bar returns, the stack is empty.

Note that the arguments and local variables may continue to exist, as they are stored outside the stack — so they can be accessed by any nested functions long after their outer function has returned

Heap

Objects are allocated in a heap which is just a name to denote a large (mostly unstructured) region of memory.

Queue

A JavaScript runtime uses a message queue, which is a list of messages to be processed. Each message has an associated function that gets called to handle the message.

At some point during the event loop, the runtime starts handling the messages on the queue, starting with the oldest one. To do so, the message is removed from the queue and its corresponding function is called with the message as an input parameter. As always, calling a function creates a new stack frame for that function’s use.

The processing of functions continues until the stack is once again empty. Then, the event loop will process the next message in the queue (if there is one),so some of event loop’s task is clear queue & stack.

Event loop

The event loop got its name because of how it’s usually implemented, which usually resembles:

1
2
3
while (queue.waitForMessage()) {
queue.processNextMessage()
}

Copy to Clipboard

queue.waitForMessage() waits synchronously for a message to arrive (if one is not already available and waiting to be handled).

“Run-to-completion”

Each message is processed completely before any other message is processed.

This offers some nice properties when reasoning about your program, including the fact that whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs (and can modify data the function manipulates). This differs from C, for instance, where if a function runs in a thread, it may be stopped at any point by the runtime system to run some other code in another thread.

A downside of this model is that if a message takes too long to complete, the web application is unable to process user interactions like click or scroll. The browser mitigates this with the “a script is taking too long to run” dialog. A good practice to follow is to make message processing short and if possible cut down one message into several messages.

Adding messages

In web browsers, messages are added anytime an event occurs and there is an event listener attached to it. If there is no listener, the event is lost. So a click on an element with a click event handler will add a message—likewise with any other event.

Several runtimes communicating together

A web worker or a cross-origin iframe has its own stack, heap, and message queue. Two distinct runtimes can only communicate through sending messages via the postMessage method. This method adds a message to the other runtime if the latter listens to message events.

Never blocking

A very interesting property of the event loop model is that JavaScript, unlike a lot of other languages, never blocks. Handling I/O is typically performed via events and callbacks, so when the application is waiting for an IndexedDB query to return or an XHR request to return, it can still process other things like user input.

Ref:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Introduction to Vue.js

What is Vue Router

Learn vuex in 15 minutes

Reactivity in Depth

image

Tips:

  • In a traditional app that is not using client-side routing,the browser is essentially going out and fetching the different content that we need from those different urls
  • With a Single Page Application,we’re really only looking at one page,the index.html,and as we click around in it, we’re adjusting which view we’re seeing of that app, hence we call it a single page application, because all of these pages come from that one index.html page.
  • 【router-view】 is a placeholder replaced by route’s component
  • In client-side routing,when navigation happens, Vue with the help of Vue router compares and renders the differences without ever having to reload the page

image

image

image

image

Q:What is One-Way Data Flow

A: All props form a one-way-down binding between the child property and the parent one:when the parent property updates,it will flow down to the child,but not the other way around.This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand.

Ref:https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

Q:What is Computed Property

A: In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example:

1
2
3
<div id="example">
{{ message.split('').reverse().join('') }}
</div>

At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it displays message in reverse. The problem is made worse when you want to include the reversed message in your template more than once.That’s why for any complex logic, you should use a computed property.Computed property is much more like a function,but what’s the difference? For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as message has not changed, multiple access to the reversedMessage computed property will immediately return the previously computed result without having to run the function again.In comparison, a method invocation will always run the function whenever a re-render happens.

Ref:https://vuejs.org/v2/guide/computed.html#Computed-vs-Watched-Property

The Route Object

A route object represents the state of the current active route. It contains parsed information of the current URL and the route records matched by the URL.The route object is immutable.Every successful navigation will result in a fresh route object

image

cat

  • short for “concatenate”

  • allows us to create single or multiple files,view content of a file, concatenate files and redirect output in terminal or files

    image

电脑默认安装java 16,需要更换为java 8

1
open /Library/Java/JavaVirtualMachines/

选择想要删除的版本,输入管理员密码

点击下载java8dmg安装

1
2
3
4
java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (Zulu 8.58.0.13-CA-macos-aarch64) (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (Zulu 8.58.0.13-CA-macos-aarch64) (build 25.312-b07, mixed mode)

完。

参考:https://www.anotheriosdevblog.com/installing-homebrew-and-jenkins-on-my-m1-mac-mini/

今日安装jenkins,出现报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
arch -arm64 brew install jenkins
==> Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/openjdk%4011-11.0.10.arm64_big_sur.bottle.1.tar.gz
#=#=#
curl: (22) The requested URL returned error: 404
Warning: Bottle missing, falling back to the default domain...
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/11/manifests/11.0.10-1
Already downloaded: /Users/kevin/Library/Caches/Homebrew/downloads/c92dbb3dbfa86fe1cdbe7a74ec208c3789d188d92be2d580af208aef5b80a197--openjdk@11-11.0.10-1.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/11/blobs/sha256:8990371b4279802b949bcff3a2064ea0a51e7a64da7449267a1c4021e2d7d6d8
Already downloaded: /Users/kevin/Library/Caches/Homebrew/downloads/92754dc32a66d4a7c38ea48c4e3820236bf633e1bd5949f96cd13a502a14f41f--openjdk@11--11.0.10.arm64_big_sur.bottle.1.tar.gz
==> Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/jenkins-2.302.all.bottle.tar.gz
#=#=#
curl: (22) The requested URL returned error: 404
Warning: Bottle missing, falling back to the default domain...
==> Downloading https://ghcr.io/v2/homebrew/core/jenkins/manifests/2.302
Already downloaded: /Users/kevin/Library/Caches/Homebrew/downloads/a7cf18dfe095a4d331d7905c74417d764e90ace995b98a023bfae85aced3cb0f--jenkins-2.302.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/jenkins/blobs/sha256:fc7f49175e23a67127dc70338bd12abac822048f12b213fc666e1f9499ff6e82
Already downloaded: /Users/kevin/Library/Caches/Homebrew/downloads/eb6411ff42c44cb186e34607b5ac9d17d67777a07a985ad36570e9001354fae7--jenkins--2.302.all.bottle.tar.gz
==> Installing dependencies for jenkins: openjdk@11
==> Installing jenkins dependency: openjdk@11
==> Pouring openjdk@11-11.0.10.arm64_big_sur.bottle.1.tar.gz
tar: Error opening archive: Failed to open '/Users/kevin/Library/Caches/Homebrew/downloads/1096bb647c4eefa040e362e9f88af881902e3cfd88dc4bb9daab7319cda7ab44--openjdk@11-11.0.10.arm64_big_sur.bottle.1.tar.gz'
Error: Failure while executing; `tar --extract --no-same-owner --file /Users/kevin/Library/Caches/Homebrew/downloads/1096bb647c4eefa040e362e9f88af881902e3cfd88dc4bb9daab7319cda7ab44--openjdk@11-11.0.10.arm64_big_sur.bottle.1.tar.gz --directory /private/tmp/d20211129-8757-13q6qjl` exited with 1. Here's the output:
tar: Error opening archive: Failed to open '/Users/kevin/Library/Caches/Homebrew/downloads/1096bb647c4eefa040e362e9f88af881902e3cfd88dc4bb9daab7319cda7ab44--openjdk@11-11.0.10.arm64_big_sur.bottle.1.tar.gz'

解决方案

1
2
export HOMEBREW_BOTTLE_DOMAIN=''
arch -arm64 brew install jenkins

分析:

1
2
3
open ~/.zprofile
export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles/bottles #ckbrew
eval $(/opt/homebrew/bin/brew shellenv) #ckbrew

可以看到是中科大的镜像,未和官网完成同步,五月一号起官网已不再支持bintray服务,把域名切换为空即可

完。

参考:https://www.tinkol.com/372

需求描述:

打一次包,用户可以自由切换开发和生产环境

实现原理

每一个app在设置界面可以增加配置选项,存的数据可以通过user default读取,根据存储的数据来甄别切换网络

实现步骤

  • 新增setting bundle image

root.plist source code 如下

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Title</key>
<string>环境</string>
<key>Key</key>
<string>env_key</string>
<key>DefaultValue</key>
<string>1</string>
<key>Titles</key>
<array>
<string>DEV</string>
<string>TEST</string>
<string>PROD</string>
<string>SAAS</string>
</array>
<key>Values</key>
<array>
<string>1</string>
<string>2</string>
<string>3</string>
<string>4</string>
</array>
</dict>
</array>
</dict>
</plist>

效果:image

image

  • 代码获取值

    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
    - (void)registerDefaultsFromSettingsBundle{
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];

    if(!settingsBundle) {
    NSLog(@"Could not find Settings.bundle");
    return;
    }

    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];

    NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];

    NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];

    for(NSDictionary *prefSpecification in preferences) {
    NSString *key = [prefSpecification objectForKey:@"Key"];

    if(key) {
    [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
    }

    }

    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
    }


    -(NSString *)getNetworkOption{
    #if DEBUG
    id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"env_key"];
    if ([obj isKindOfClass:[NSString class]]) {
    return (NSString *)obj;
    }
    return @"";

    #else
    return @"";

    #endif

    }
  • 设置release状态不包含bundle文件

    Xcode—->Project—->Build Settings—->Build Options—->Exclude Source Files Names—->Release 把文件拖进去

完。

参考:https://blog.csdn.net/nogodoss/article/details/21938771

查单词

遇见一个新的单词,分三步:

  • 去查单词的英文解释,去猜大概的意思

网址:https://www.ldoceonline.com/

tip:看单词意思时可以看看单词的来源origin,拉丁?法语?西语?可以帮助理解单词

  • 打开谷歌,查询单词对应的图片

网址:https://www.google.com/imghp?hl=en

  • 看着图片,听十次单词的发音,让大脑把声音和图像建立连接

听广播

福克斯live:https://radio.foxnews.com/player-files/radio.php

WNYC: https://www.wnyc.org/?gclid=CjwKCAiA4veMBhAMEiwAU4XRrwNPDuvJZfNt-j899F9FDUh3SiWtsg99NlUml5nMb4Z8eVDpuyJG-BoC_OwQAvD_BwE

tip:在家或者坐公交带着耳机听,听懂多少算多少,别慌,手机去商店下载国外广播app

看影视剧

油管:https://www.youtube.com/

学习图形化数学:https://www.3blue1brown.com/

Curious George 动画系列

tip:一定要注意,看无字幕

看八卦新闻

reddit:https://www.reddit.com/

电子书

PDF电子书:https://www.pdfdrive.com/

tip:寻找感兴趣的领域书籍阅读

纸质书推荐

Nights in Rodanthe》by Nicholas Sparks (2002)

Nothing Lasts Forever》by Roderick Thorp (1979)

《The Old Man and the Sea》by Ernest Hemingway (1952)

《The Call of the Wild]》by Jack London (1903)

词典

英英词典:https://www.zhihu.com/question/21964466

tip:一定要使用英英词典,个人使用的是mac自带的词典+朗文第五版的词库

语言获取原理

Second Language Acquisition

《找对英语学习方法的第一本书》

《把你的英语用起来!》

《人人都能用英语》

英语学习的一些经验

解谜英语语法

为什么需要熟练英语

如何超过大多数人

用惯了Android Studio底部直接可以用terminal,在想Xcode是不是可以有类似功能,经过查询,整理出方法

  • 新建一个.sh文件,内容如下,保存
1
2
3
#!/bin/bash

open -a Terminal "`pwd`"
  • 打开Xcode—>Preference—>Behaviors—>Custom—>Run,选择创建好的.sh文件,Run前面的checkbox打钩,设定一个快捷键,这样,在Xcode界面使用快捷键就可以打开当前文件夹的终端窗口了。

完。

参考:https://stackoverflow.com/questions/21998706/terminal-window-inside-xcode