Posted on 

踩坑合集/(不定时补充)

前后端踩坑合集

前端

Node-sass: Command failed

node-sass

更改 yarn 源即可

1
2
3
yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
yarn add node-sass

另附 npm 换源

1
2
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist

@sentry/cli 安装错误的问题

In case of @sentry-cli problem, create .yarnrc and write the source below into it.

sentry1

1
2
3
registry: https://registry.npm.taobao.org
ENTRYCLI_CDNURL: https://cdn.npm.taobao.org/dist/sentry-cli
sentrycli_cdnurl: https://cdn.npm.taobao.org/dist/sentry-cli

Then u will see the source is edited and show as below

sentry2

node16 以上的加密部件问题

使用 node18 跑新项目时出现了这一错误

1
error/0308010C/digital envelope routines//unsupported

看错误报告里讲node17.0以上的版本会出现这个情况。
nodejs 17: digital envelope routines::unsupported #14532

方案 1

环境变量里面加个变量,将OpenSSL降回到老策略去:

1
export NODE_OPTIONS=--openssl-legacy-provider

方案 2

版本回退到Node.js 16
如果平时工作的项目所使用的node版本不一样,通过全局频繁卸载安装的方式显然效率低下。推荐使用nvm来安装管理node版本,并且node版本间的切换也非常方便。
nvm切换node版本步骤:

1
2
3
4
5
6
7
# 安装 node 16.13.0 版本
nvm install 16.13.0
# 设置默认使用 node 版本
nvm alias default v16.13.0
# 确认切换是否成功
node -v
v16.13.0

安装 nvm

运行 curl 命令时会出现以下错误:

1
curl: (7) Failed to connect to raw.githubusercontent.com port 443 after 14 ms: Connection refused

github 的一些域名的 DNS 解析被污染,导致DNS 解析过程无法通过域名取得正确的IP地址。

因此我们要找到正确的这个raw.githubusercontent.com网站正确的ip地址

  • 打开ip地址查询网站:https://www.ipaddress.com/

  • 输入需要查询的网站名称raw.githubusercontent.com

  • 网站上会显示该网站的存在的ipv4以及ipv6地址,这里可以选取一个ipv4地址来进行设置

打开系统host文件

1
sudo vim /etc/hosts

在host文件中添加一行

1
185.199.108.133 raw.githubusercontent.com

最后执行

1
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Flutter/RN iOS 联调记录

Firebase Analytics setScreenName deprecatedFirebase Analytics setScreenName 已弃用

ARC Semantic Issue (Xcode): No known class method for selector ‘setScreenName:screenClass:’

https://stackoverflow.com/questions/68663243/error-no-known-class-method-for-selector-setscreennamescreenclass

如果 react-native 中发生相同的错误,则 在 RNFirebaseAnalytics.m 文件中,更新以下代码行:

1
[FIRAnalytics setScreenName:screenName screenClass:screenClassOverriewl;

1
[FIRAnalytics logEventWithName: kFIREventScreenView parameters: @(kFIRParameterScreenName: screenName])

Xcode 12 解決 Command PhaseScriptExecution failed with a nonzero exit code

在 build 專案時遇到以下錯誤時
1
/Users/.../Script-E97175B023F12D90003B2A7E.sh: line 2: /usr/local/bin/carthage: No such file or directoryCommand PhaseScriptExecution failed with a nonzero exit code

到 Project setting targets > Build Phases > Run Script>

勾選 ☑For install builds only

解決 Swift failed to emit precompiled header

Q: 在 OC 中引用 Swift , 需要#import “ProductName-Swift.h”, 升級之後回報failed to emit precompiled header的錯誤.

A: 在Build Settings 中, 搜索 precomplile找到Precompile Prefix Header設為YES

Issue: Invalid Podfile File Error in Flutter iOS Project

Problem

When running pod install, you may encounter the following error:

[!] Invalid Podfile file: undefined method `exists?’ for class File.

1
2
3
4
5
6
7
8
9
10
11
\# from /Users/zenn/Desktop/followcat-backup/ios/Podfile:34

\# -------------------------------------------

\#

\> flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

\# end

\# -------------------------------------------

This error occurs because the exists? method, which was previously supported, is not recognized in the current environment. This might be due to changes in the Ruby or CocoaPods versions.

Cause

In the Flutter SDK, the exists? method is used in the pod_helper.rb file. However, in some Ruby environments, this method is not recognized, resulting in the undefined method exists? error.

Solution

Instead of downgrading CocoaPods, which can cause other issues (especially with Xcode 14.3+), you can fix this issue by directly modifying the pod_helper.rb file in your Flutter SDK.

Steps to Fix

​ 1. Locate pod_helper.rb in Flutter SDK

Open the pod_helper.rb file, located in your Flutter SDK directory:

1
flutter/packages/flutter_tools/bin/pod_helper.rb

​ 2. Modify exists? to exist?

Find the following line in pod_helper.rb:

1
return [] unless File.exists? file_path

Replace exists? with exist? (the correct method name in Ruby’s standard library):

1
return [] unless File.exist? file_path

​ 3. Save the File and Run pod install Again

After making this change, save the file and try running pod install in your ios directory:

1
2
cd ios
pod install

The File.exists? method has been deprecated and is not supported in some environments. Replacing it with File.exist? resolves the issue without needing to downgrade CocoaPods.

Additional Resources

For more information, check this StackOverflow discussion on this issue.

W/FlutterActivityAndFragmentDelegate( 4159): A splash screen was provided to Flutter, but this is deprecated. See flutter.dev/go/android-splash-migration for migration steps.

https://blog.csdn.net/lqw200931116/article/details/123201386

Vue 日期表单限制当前时间为最大可选值

接手了 Vue 项目,需要 Mint-UI 的日期表单的最大可选值设置为当前时间,也就是说只能选择现在和现在以前的时间。

官方文档看起来使用方法很简单,添加一个endDate属性,设置最大可选时间就可以了

1
2
<mt-datetime-picker v-model="datetime" ref="datetimePicker" type="datetime" @confirm="this.changeTime" endDate="new Date()">
</mt-datetime-picker>

当然这个方法报错 endDate.getFullYear() is not a function,endDate不是当做一个属性被编译,而是被当作一个变量被编译了,所以说明这个用法是错误的。

正确用法如下,需要在date里面给endDate赋值,比如我这里只能选择今天及之前的日期:endDate: new Date()

1
2
<mt-datetime-picker v-model="datetime" ref="datetimePicker" type="datetime" @confirm="this.changeTime" :end-date="endDate">
</mt-datetime-picker>

Vue input 无法用 maxlength 限制长度

1、当input,type为text时,设置maxlength后,能限制输入内容长度;

2、当input,type为tel时,设置maxlength后,也是能限制输入内容长度,并且弹起键盘为默认为数字键盘;

3、当input,type为number,设置了maxlength,是无法正常限制输入内容长度的,input元素内还是可以无限的输入内容。

解决方法:a 通过监听input的输入,input事件。

1
<input type="number" oninput="if( this.value.length > 4 )  this.value = this.value.slice(0,4)">

当输入超过4位后,会进行截断,保留前面的4位。
用vue,使用@input
但是会有小小不好的体验,输入第五位的时候,会先显示第五位,然后再删除第五位。因为这是通过监听input事件,来实现的。

解决方法:b 将number改为tel类型,然后设置maxlength。因为设置type为tel后,也是只能输入数字。然后只能输入相应的位数。

vue 地图开发

获取本地位置

html5 地理定位接口在许多浏览器平台都返回如下的错误信息,这是因为 html5 默认调用谷歌接口,会有安全限制。

html-position

城市区域名称转化

获取到的是经纬度,所以要调百度或者谷歌的地图api,来转换为城市。

使用腾讯地图 API 获取当前位置的经纬度

因为使用 axios 自动拼接 url 路径会产生跨域问题axios-cross-origin

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
<!--	在 main.js 中添加
import axios from 'axios'
axios.defaults.baseURL='#'
Vue.prototype.$http = axios
-->

<script>
export default {
name: 'Home',
components: {
HelloWorld
},
created() {
this.getlocation()
},
methods: {
// 使用了async,await去简化Promise并解构获取到的数据,其中 axios 中的 https://apis.map.qq.com/ws/location/v1/ip 是在腾讯地图控制台获取的 reference
async getlocation() {
const {
data: res
} = await this.$http.get('https://apis.map.qq.com/ws/location/v1/ip', {
params: {
key: 'XOXBZ-MZWWD-CDX4H-PONXN-UA5PJ-D7FJN'
}
})
console.log(res);
}
}
}
</script>

使用 vue-jsonp 解决跨域问题

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
<!--	在 main.js 中添加
import { VueJsonp } from 'vue-jsonp'
Vue.use(VueJsonp)
-->

<script>
export default {
name: 'Home',
created() {
//获取当前位置的经纬度
var data = {
key: "XOXBZ-MZWWD-CDX4H-PONXN-*****-*****" //腾讯地图密钥
};
var url = "https://apis.map.qq.com/ws/location/v1/ip"; //地理位置信息的接口
data.output = "jsonp";
this.$jsonp(url, data)
.then(res => {
console.log(res,123);
})
.catch(error => {
console.log(error,456);
});
},
methods: {
}
}
</script>

后端

Non-resolvable import POM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mac@macdeMacBook-Pro WX-Fleas-Market-Demo % mvn clean package -Dmaven.test.skip=true
[INFO] Scanning for projects...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] Non-resolvable import POM: org.springframework.cloud:spring-cloud-dependencies:pom:Greenwich.M1 was not found in https://maven.aliyun.com/repository/public during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of aliyunmaven has elapsed or updates are forced @ line 44, column 25
@
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project io.github.nnkwrik:fangxianyu:0.0.1-SNAPSHOT (/Users/mac/github/WX-Fleas-Market-Demo/pom.xml) has 1 error
[ERROR] Non-resolvable import POM: org.springframework.cloud:spring-cloud-dependencies:pom:Greenwich.M1 was not found in https://maven.aliyun.com/repository/public during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of aliyunmaven has elapsed or updates are forced @ line 44, column 25 -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

转到发现

1
2
3
4
5
6
7
8
9
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>

参考了这篇博客后,知道系统文件自动将 ${spring-cloud.version} 读为 Greenwich.M1 版本。将其改成 Edgware.SR3 即可跑通。

开发代号看似没有什么规律,但实际上首字母是有顺序的,比如:Dalston版本,我们可以简称 D 版本,对应的 Edgware 版本我们可以简称 E 版本。

D、E版本:二者均基于SpringBoot的1.5.x版本,但支持其他组件的版本不同,如以 Dalston.SR4 和 Edgware.RELEASE 来对比:

  • spring-cloud-config 分别对应 1.3.3和 1.4.0;
  • spring-cloud-netflix 分别对应 1.3.5和 1.4.0;
  • spring-cloud-consul 分别对应 1.2.1和 1.3.0;
  • spring-cloud-gateway 前者不支持,后者 1.0.0。

F版本:F版本是个绝对的大版本,几乎所有组件,全部同步变更版本号为2.x;

SNAPSHOT: 小版本,快照版本,随时可能修改;

M: MileStone,小版本,M1表示第1个里程碑版本,一般同时标注PRE,表示预览版版。

SR: Service Release,小版本,SR1表示第1个正式版本,一般同时标注GA:(GenerallyAvailable),表示稳定版本。

jar missing problem

1
2
3
4
5
6
7
8
9
10
11
12
13
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'dependencies.dependency.version' for org.springframework.cloud:spring-cloud-starter-gateway:jar is missing. @ line 29, column 21
@
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project io.github.nnkwrik:gateway:0.0.1-SNAPSHOT (/Users/mac/github/WX-Fleas-Market-Demo/gateway/pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for org.springframework.cloud:spring-cloud-starter-gateway:jar is missing. @ line 29, column 21
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException

子在pom中为他们指定版本号就好了。版本号可以在https://mvnrepository.com/ 中通过artifactId 查询

还有写项目的时候突然报了这个错误:Error:java:java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
WARNING: All illegal access operations will be denied in a future release
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for fangxianyu 0.0.1-SNAPSHOT:
[INFO]
[INFO] fangxianyu ......................................... SUCCESS [ 5.236 s]
[INFO] common ............................................. FAILURE [ 55.328 s]
[INFO] inner-api .......................................... SKIPPED
[INFO] eureka ............................................. SKIPPED
[INFO] gateway ............................................ SKIPPED
[INFO] auth-service ....................................... SKIPPED
[INFO] user-service ....................................... SKIPPED
[INFO] goods-service ...................................... SKIPPED
[INFO] im-service ......................................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:00 min
[INFO] Finished at: 2022-07-13T23:39:33+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project common: Fatal error compiling: java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags -> [Help 1]

然后当时就很懵逼,后来通过排错,发现是使用的lombok版本过低,我使用的springboot的版本是:: Spring Boot :: (v2.2.1.RELEASE)

package org.springframework.cloud.openfeign does not exist

  1. 没有添加版本号

  2. 没有添加以下依赖

1
2
3
4
5
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>

开发环境配置踩坑大全

配置 maven

解压到某路径如 /usr/local/...

1
2
3
4
vim ~/.bash_profile 

export M2_HOME=/usr/local/apache-maven-3.8.4
export PATH=$PATH:$M2_HOME/bin

配置 flutter

1
export PATH="$PATH:`pwd`/flutter/bin"

使用 m1 GPU 训练 Tensorflow

Please try the same after creating a virtual environment.

1
2
3
4
5
python3 -m venv ~/tensorflow-metal
source ~/tensorflow-metal/bin/activate
python -m pip install -U pip
python -m pip install tensorflow-macos
python -m pip install tensorflow-metal

使用 bench.py 测试 m1 性能,运行时间为 108.47s(作为对比,24 核 gpu m1max 运行时间为 58s)

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import tensorflow as tf
import tensorflow_datasets as tfds
import time


print("TensorFlow version:", tf.__version__)
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
start_time = time.time()
# tf.config.list_physical_devices('GPU')

(ds_train, ds_test), ds_info = tfds.load(
'mnist',
split=['train', 'test'],
shuffle_files=True,
as_supervised=True,
with_info=True,
)

def normalize_img(image, label):
"""Normalizes images: `uint8` -> `float32`."""
return tf.cast(image, tf.float32) / 255., label

batch_size = 128
ds_train = ds_train.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_train = ds_train.cache()
ds_train = ds_train.shuffle(ds_info.splits['train'].num_examples)
ds_train = ds_train.batch(batch_size)
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE)
ds_test = ds_test.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_test = ds_test.batch(batch_size)
ds_test = ds_test.cache()
ds_test = ds_test.prefetch(tf.data.experimental.AUTOTUNE)

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, kernel_size=(3, 3),
activation='relu'),
tf.keras.layers.Conv2D(64, kernel_size=(3, 3),
activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
# tf.keras.layers.Dropout(0.25),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
# tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.001),
metrics=['accuracy'],
)

model.fit(
ds_train,
epochs=12,
validation_data=ds_test,
)

end_time = time.time()
print("Time consumed: {:.2f}秒".format(end_time - start_time))

运行 TensorFlow 报错

1
2
ERROR: Could not find a version that satisfies the requirement tensorflow (from versions: none)
ERROR: No matching distribution found for tensorflow

原因:Python的版本过高。使用指令:python –version 查看当前使用的Python版本。TensorFlow支持的Python版本只到python3.5。

解决方案:

  1. 把当前的Python卸载掉,安装python3.5
  2. 指定安装支持高版本Python的TensorFlow
1
python3 -m pip install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.12.0-py3-none-any.whl

tensorflow 加载数据集异常

异常错误提示:

tensorflow/core/platform/cloud/google_auth_provider.cc:184] All attempts to get a Google authentication bearer token failed, returning an empty token. Retrieving token from files failed with “Not found: Could not locate the credentials file.”. Retrieving token from GCE failed with “Failed precondition: Error executing an HTTP request: libcurl code 6 meaning ‘Couldn’t resolve host name’, error details: Couldn’t resolve host ‘metadata’”.

解决方法:改成如下对应的版本就行

tensorflow=2.3.0 and tensorflow-datasets=2.1.0

命令如下:

pip install tensorflow-datasets==2.1.0

想详细了解的同学可以去查看以下两个网址:

https://github.com/PAIR-code/lit/issues/26

https://github.com/PAIR-code/lit/issues/22

M1 安装 pytorch

1
2
3
4
# torch create virtual environment
conda create -n torch_nightly_env python=3.8
conda activate torch_nightly_env
conda install PyTorch torchvision -c pytorch-nightly

m1 安装 qemu 卡死问题

按照官网步骤使用 brew 安装 qemu 之后,make install 会卡死在第一步,在这一 issue 中找到了解决方案:

https://github.com/BASARANOMO/xv6-labs-2020/issues/1

Then, download the qemu-5.1.0 and unzip the downloaded .tar.xz file:

1
$ wget https://download.qemu.org/qemu-5.1.0.tar.xz

Two patches are needed:
patch1: just download it and cd to the qemu directory, then:

1
$ patch -p1 < ../patch/v2-tcg-Fix-execution-on-Apple-Silicon.patch

patch2: Two lines only. Find the file in qemu directory and modify it.
Then run configure with:

1
$ ./configure --disable-kvm --disable-werror --prefix=/usr/local --target-list="riscv64-softmmu"
1
2
$ make
$ make install

Catalina quarantine for corrupted apps

低于 Big Sur 系统版本的 macOSm1 芯片机器在安装一些未适配软件时候可能会出现 安装包损坏, 打不开“XXX”,因为它来自身份不明的开发者 等报错,在此状态下可以尝试以下做法。

1
2
3
sudo spctl --master-disable
sudo xattr -r -d com.apple.quarantine /Applications/Sketch.app/
// 输入 sudo xattr -r -d com.apple.quarantine 后将应用程序拖入 teminal 中

(以及 Catalina 真的好耐看啊!)

Homebrew国内源

https://gitee.com/cunkai/HomebrewCN

苹果电脑标准安装脚本:(推荐 优点全面 缺点慢一点)

1
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

苹果电脑极速安装脚本:(优点安装速度快 缺点update功能需要命令修复 )

1
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" speed

Linux 标准安装脚本:

1
rm Homebrew.sh ; wget https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh ; bash Homebrew.sh

苹果电脑卸载脚本:

1
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/HomebrewUninstall.sh)"

Linux卸载脚本:

1
rm HomebrewUninstall.sh ; wget https://gitee.com/cunkai/HomebrewCN/raw/master/HomebrewUninstall.sh ; bash HomebrewUninstall.sh

删除 .DS_Store

删除当前目录及其子目录下的所有.DS_Store 文件:

1
find . -name '*.DS_Store' -type f -delete

禁止.DS_store生成:

1
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE

恢复.DS_store生成:

1
defaults delete com.apple.desktopservices DSDontWriteNetworkStores

将 .DS_Store 加入到 .gitignore

1
echo .DS_Store >> ~/.gitignore

Python 镜像

1
2
3
4
5
清华大学镜像:https://pypi.tuna.tsinghua.edu.cn/simple/
阿里云:https://mirrors.aliyun.com/pypi/simple/
中科大镜像:https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣镜像:https://pypi.douban.com/simple/
中科大镜像2:https://pypi.mirrors.ustc.edu.cn/simple/

Dev-Util

Google Maps API

网址 功能说明
1 https://snazzymaps.com/ 带有 JSON 代码和可下载示例的 Google 地图配色方案的存储库
2 https://googlemapsmania.blogspot.com/search/label/Styled%20Maps
3 https://mapstyle.withgoogle.com/

数据可视化

来源:“凯度信息之美奖”(The Kantar Information is Beautiful Awards)

  1. 最佳信息之美奖(Most Beautiful)-《天空中的密探》-作者:Peter Aldous 和 Charles Sefie(美国)

美国政府的空中监视行为截止到目前几乎不为人知。BuzzFeed News通过分析从航班追踪网站Flightradar24上得到的大约200架已辨别的联邦飞机位置数据,通过动态化的地图和路线图,借助VR技术形成了一幅前所未有的美国政府监视行动规模图景,为大家清晰展现一个政府监视下的美国。

解读 :RUC工作坊作品:解析年度最佳数据可视化《天空中的密探》,清晰展现一个政府监视下的美国

  1. 数据可视化项目(Dataviz Project)金奖作品 -《数据美食》 - 作者:Moritz Stefaner和Susanne Jaschko(德国)

(在伊朗,一半全球前500的网站被封禁,但是70%的年轻网络用户试用代理服务器访问这些网站。该图用意大利调味饭中不同颜色的米粒代表这些数据。其中上半部分的黄色米粒代表可访问的网站,下半部分代表被封禁的网站,下半部分的黄色米粒代表通过代理服务器进行访问的网站)

食物可以作为展示数据的工具吗?数据是什么味道?

数据美食工作坊将美食作为一种工具来展示数据。该工作坊由德国艺术设计网站Prozessagenten发起,由数据可视化专家Moritz Stefaner负责艺术设计。该工作坊会采用当地的食物来展示当地相关的数据,比如说用当地鱼类做的鱼汤来展示当地渔业的数据,用披萨来展示芬兰首都赫尔辛基的不同种族人口比率等。

  1. 交互可视化类(Interactive)金奖作品《航运地图》 - 作者:Robin Houston 和 Duncan Clark(英国)

基于2012全年全球商业航运数据的交互式3D地图,展示了现代商业航运的巨大规模,大型商船的航运路线,不同类型商船的地理分布和它们的碳排放量。这幅地图以动画片的形式呈现,在缓缓的音乐中还伴随着关于对商业航运的重要性、运输货物的重要河流及地区等的讲解。

  1. 数据可视化网站(Dataviz Website)金奖作品《流动的数据》作者:Nathan Yau(邱南森)

Flowingdata.com网站由数据统计师Nathan Yau运营,持续更新原创或整合的数据可视化内容。该网站上现在有大量的数据可视化作品、数据可视化学习教程和指南等。

  1. 商业项目(Commercial/biz Project)金奖作品《数据美国》

该网站由德勤(Deloitte)、Datawheel数据公司和麻省理工学院媒体实验室Macro Connections共同创建。数据美国是一个开放的免费资源平台,提供美国政府多家统计部门的官方数据,现有180多万个数据可视化成果,范围涵盖工业、教育、职场等多个领域。

  1. 年度最佳工作室(Studio of the Year)- Polygraph工作室

Polygraph斩获了今年的“年度最佳工作室”奖。工作室研究的话题广泛,相比用文字枯燥的表述,他们更喜欢借助画面、符号等动态信息开展对不同课题的研究。代表作品为《对话电影》和《音乐品味的变革》。

  • 《对话电影》探讨了性别、社会背景、票房数据等因素对于电影的影响。通过数据鲜明反映出了当今电影的多元化趋势。
  • 《音乐品味的变革》通过研究1958年至2015年公告牌歌曲的排名变化,展现各个时代音乐的流行趋势。
  1. 最佳团队奖(Outstanding Team)FiveThirtyEight 网站

美国FiveThirtyEight网站团队获得此奖。该网站成立于2008年,特点是基于大量数据来预测新闻。最具代表性的作品便是通过棒球比赛数据成功预测出奥巴马将赢得美国总统大选。网站在不牺牲严密性和准确性的前提下,让数据新闻变得生动且通俗易懂,更加吸引读者。代表作品是《2016年美国大选预测》。话说小编很想知道这次特朗普当选FiveThirtyEight的预测是否靠谱啊。

  1. 最佳个人奖(Outstanding Individual)Moritz Stefaner(德国)- 天神项目——季风能源预测

天气预报的预测范围局限于未来几周,气候预报的预测范围放眼于未来几年。对于能源交易商来说,了解未来几个月的风况则最为重要。基于复杂的气候模型,该项目将尝试用新的方法预测未来几个月的风况,为风能基地提供帮助。

  1. 数据可视化项目(Dataviz Project)金奖作品《数据美食》- 作者:Moritz Stefaner和Susanne Jaschko(德国)

(在伊朗,一半全球前500的网站被封禁,但是70%的年轻网络用户试用代理服务器访问这些网站。该图用意大利调味饭中不同颜色的米粒代表这些数据。其中上半部分的黄色米粒代表可访问的网站,下半部分代表被封禁的网站,下半部分的黄色米粒代表通过代理服务器进行访问的网站)

食物可以作为展示数据的工具吗?数据是什么味道?

数据美食工作坊将美食作为一种工具来展示数据。该工作坊由德国艺术设计网站Prozessagenten发起,由数据可视化专家Moritz Stefaner负责艺术设计。该工作坊会采用当地的食物来展示当地相关的数据,比如说用当地鱼类做的鱼汤来展示当地渔业的数据,用披萨来展示芬兰首都赫尔辛基的不同种族人口比率等。

  1. 《洛杉矶及芝加哥的收入差距》 - 作者:Herwig Scherabon(美国)

作者通过两张大图将洛杉矶和芝加哥的收入差距可视化。图中两座城市的矩形建筑物高度对应了每个区域的收入水平,清晰地展现了现代城市中的贫富差距。文中指出,大多数情况下,收入分化与种族隔离相关,暗指城市规划背后的政治操控。

Tornado 试用思考

Tornado 在物联网上结合 twisted 蛮好用的。tornado 主要用于 websocket/tcp 这些长连接数据流的场景,结合 async 很有效,python 生态里暂时应该没有更好的替代框架。tornado支持把底层事件循环换成 asyncio 的循环。接着 gevent 还可以把 asyncio 的循环再 patch掉。这样 tornado 可以轻松异步调用任何支持 asyncio 或 gevent 的库。同时在 Windows 上使用 gevent (IOCP) 的 tornado 会有非常恐怖的并发能力。如果供 web CRUD 或者 restful 接口设计,优势不大。几个主流 python 框架更多是互补关系,不是竞争关系。

Duplicate Refresh of FetchRequest in the Sheet Detents Change

Sheet detent 改变的时候 Fetchrequest 都会被重新请求一次。这样在用户频繁的 sheet 交互中会造成严重的性能问题

  1. Debounce 输入防抖处理:防止用户快速输入时频繁触发后台任务。使用 Combine 的 .debounce 方法来减少频繁的输入请求,这样只有在用户停止输入一定时间后才会触发搜索操作,减少不必要的后台任务。DispatchQueue 或 Combine 可以用于实现此功能。
  2. 防止不必要的刷新:每次 sheet detent 改变时导致 FetchRequest 重新刷新,可能是因为 SwiftUI 在某些条件下会重新计算视图。如果 FetchRequest 在视图中定义,视图重新计算时会重新发起查询。我们可以考虑将 FetchRequest 与 View 逻辑分离,使用 @ObservedObject 或 @StateObject 来持久化状态,利用 @ObservedObject 或 @StateObject 来创建和管理一个 ViewModel,将数据获取逻辑从视图中分离出来,这样可以更好地控制数据的刷新逻辑,并且在 View 重新计算时不会重新发起请求,避免 FetchRequest 在视图生命周期中的自动刷新。

JVM Reflection

JVM为每个加载的classinterface创建了对应的Class实例来保存classinterface的所有信息;

获取一个class对应的Class实例后,就可以获取该class的所有信息;

通过Class实例获取class信息的方法称为反射(Reflection);

JVM总是动态加载class,可以在运行期根据条件来控制加载class。

Binding get 和 set 实现对任意数据源的双向绑定

闭包(closures)在编程中有许多重要作用,尤其在 Swift 语言中,它们提供了强大的功能和灵活性。以下是闭包的主要作用和适用场景:

​ 1. 匿名函数:闭包允许你创建没有名字的内联函数,用于临时任务或一次性操作。

​ 2. 捕获和存储状态:闭包可以捕获其上下文中的变量,并在以后使用这些变量,即使变量的原始作用域已经销毁。

​ 3. 回调和异步操作:闭包常用于回调函数中,处理异步操作的结果,例如网络请求、动画完成处理等。

​ 4. 函数作为参数和返回值:闭包可以作为参数传递给函数,也可以作为函数的返回值,从而实现高阶函数和函数式编程。

​ 5. 简化代码和提高可读性:在许多情况下,闭包可以使代码更简洁和更具可读性,尤其是在处理集合、排序和过滤时。

适用场景

1. 回调函数

回调函数是闭包最常见的使用场景之一。它们允许你在某个操作完成后执行特定的代码,例如网络请求完成后处理响应数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func fetchData(completion: @escaping (Data?, Error?) -> Void) {
// 模拟网络请求
DispatchQueue.global().async {
let data = Data() // 假设获取了一些数据
DispatchQueue.main.async {
completion(data, nil)
}
}
}

fetchData { data, error in
if let data = data {
print("Data received: \(data)")
} else if let error = error {
print("Error: \(error.localizedDescription)")
}
}

2. 处理集合

闭包用于 Swift 的标准库方法,如 map、filter 和 reduce,可以简化集合的处理。

1
2
3
4
5
6
7
8
9
10
let numbers = [1, 2, 3, 4, 5]

let squaredNumbers = numbers.map { $0 * $0 }
print(squaredNumbers) // 输出: [1, 4, 9, 16, 25]

let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // 输出: [2, 4]

let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 输出: 15

3. 排序

闭包用于定义自定义的排序逻辑。

1
2
3
4
let names = ["Charlie", "Alice", "Bob"]

let sortedNames = names.sorted { $0 < $1 }
print(sortedNames) // 输出: ["Alice", "Bob", "Charlie"]

4. 动画和视图更新

闭包常用于动画的开始和结束处理,以及视图的状态更新。

1
2
3
4
5
6
7
UIView.animate(withDuration: 0.5, animations: {
myView.alpha = 0.0
}) { finished in
if finished {
print("Animation completed")
}
}

5. 自定义操作

闭包允许你在某些操作中传递自定义的行为,例如自定义操作的实现。

1
2
3
4
5
6
func performOperation(_ operation: (Int, Int) -> Int, on a: Int, and b: Int) -> Int {
return operation(a, b)
}

let result = performOperation({ (a, b) in a * b }, on: 4, and: 2)
print(result) // 输出: 8

6. 延迟执行

闭包用于延迟执行代码,直到某个条件满足或某个事件发生。

1
2
3
4
5
6
7
8
9
func delay(seconds: Double, completion: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}

delay(seconds: 2.0) {
print("This message is printed after a 2-second delay")
}