由于PPT需要,特意搜集了一下苹果ARM SOC M1显微图像
进程资源图理解与化简
一 了解进程资源图
二 化简资源分配图
方法步骤
- 第一步:先看系统还剩下多少资源没分配,再看有哪些进程是不阻塞(“不阻塞”即:系统有足够的空闲资源分配给它)的
- 第二步:把不阻塞的进程的所有边都去掉,形成一个孤立的点,再把系统分配给这个进程的资源回收回来
- 第三步:看剩下的进程有哪些是不阻塞的,然后又把它们逐个变成孤立的点。
- 第四步:最后,所有的资源和进程都变成孤立的点。这样的图就叫做“可完全简化”。
如果一个图可完全简化,则不会产生死锁;如果一个图不可完全简化(即:图中还有“边”存在),则会产生死锁。这就是“死锁定理”。
实例
解析:
R1有两个资源,一个分配给了P1,一个分配给了P3,此时P2申请R1的资源,因为R1此时没有可用资源,P2堵塞。
R2有三个资源,已经给P1,P2,P3,各自分配了一个资源,而P1此时又再次申请资源R2,P1堵塞
R3有两个资源,已经分配给P2一个,P2申请一个资源,分配给它,所以P3是非阻塞结点
化简的话,看从没有阻塞的结点开始,删去P3周围所有的边,使其成为一个孤立的点,然后看剩下的资源按上述步骤再次进行分配,若到最后只剩下一群孤立的点,则说明该资源图是可以化简的。
参考链接
Visual Studio Code调试Flutter报错“[CHROME]:need to run as root or suid”
在最新的Ubuntu 22.04系统上使用Visual Studio Code调试Flutter应用,Chrome使用Snap安装,通过指定 CHROME_EXECUTABLE=/snap/bin/chromium,在调试的时候,报错如下:
1 2 3 4 5 6 |
Launching lib/main.dart on Chrome in debug mode... lib/main.dart:1 [CHROME]:need to run as root or suid Failed to launch browser after 3 tries. Command used to launch it: /snap/bin/chromium --user-data-dir=/tmp/flutter_tools.SEVTFD/flutter_tools_chrome_device.AMHTFX --remote-debugging-port=38457 --disable-background-timer-throttling --disable-extensions --disable-popup-blocking --bwsi --no-first-run --no-default-browser-check --disable-default-apps --disable-translate http://localhost:42407 Failed to launch browser. Make sure you are using an up-to-date Chrome or Edge. Otherwise, consider using -d web-server instead and filing an issue at https://github.com/flutter/flutter/issues. Exited (sigterm) |
解决方法就是指定真实的Chrome安装路径,直接调用,而不是通过Snap的沙箱,解决沙箱无法调试的问题,如下:
1 2 |
#export CHROME_EXECUTABLE=/snap/bin/chromium export CHROME_EXECUTABLE=/snap/chromium/current/usr/lib/chromium-browser/chrome |
参考链接
How to get the snap-based chromium to access a separately mounted filesystem?
ssh默认不支持rsa了
今天升级ubuntu 22.04/Window 11后最基本的ssh登陆突然出问题了, 提示有几种:
1 2 3 4 |
Unable to negotiate with UNKNOWN port 65535: no matching host key type found. Their offer: ssh-rsa,ssh-dss lost connection sign_and_send_pubkey: no mutual signature supported |
1 2 3 4 5 |
Git Pull failed Unable to negotiate with xx.xx.xx.xx port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. |
一查发现…好嘛, openssh觉得ssh-rsa加密方式不安全, 直接从8.8开始默认不允许这种密钥用于登陆了…
解决方法是可以在~/.ssh/config
里面加这么一段解决:
1 2 3 |
Host * PubkeyAcceptedKeyTypes +ssh-rsa HostKeyAlgorithms +ssh-rsa |
第一行说明对所有主机生效, 第二行是将 ssh-rsa 加会允许使用的范围, 第三行是指定所有主机使用的都是 ssh-rsa 算法的key。
实测两行都得要写才行, 没有第二行提示没有 ssh-rsa 这么个类型
没有第三行就提示 sign_and_send_pubkey: no mutual signature supported。
参考链接
解决远程桌面执行sudo启动X应用报错“Gtk-WARNING **: 12:39:47.296: cannot open display: :10.0”
通过远程桌面(RDP)连接到远程Ubuntu服务器桌面,执行调用X窗口应用的时候,报错如下:
1 2 3 4 5 6 7 8 9 |
$ sudo update-manager No protocol specified Unable to init server: Could not connect: Connection refused No protocol specified Unable to init server: 无法连接: Connection refused No protocol specified Unable to init server: 无法连接: Connection refused (update-manager:2547): Gtk-WARNING **: 12:39:47.296: cannot open display: :10.0 |
原因因为:
XServer默认情况下不允许别的用户的图形程序的图形显示在当前屏幕上。
如果需要别的用户的图形显示在当前屏幕上,则应以当前登陆的用,也就是切换身份前的用户执行如下命令。
当前登陆普通用户执行:xhost +
1 2 3 4 |
$ xhost + access control disabled, clients can connect from any host $ sudo update-manager |
参考链接
佳能打印机MG3600 Series重新配置Wi-Fi
重要事项
-
设备通过无线路由器连接到互联网时,如果将其连接到处于直接连接模式的打印机,设备和无线路由器之间的现有连接将被禁用。 在这种情况下,根据设备的不同,设备连接可能会自动切换至移动数据连接。 当使用移动数据连接连接到互联网时,根据合同,可能会产生费用。
(出现在一个新窗口中)
-
如果打印机上的Wi-Fi指示灯(A)闪烁,按停止按钮(B)。
-
按住打印机上的Wi-Fi按钮(C)直至电源指示灯(D)闪烁。
-
按彩色按钮(E),然后按Wi-Fi按钮(C)。
-
确保Wi-Fi指示灯快速闪烁且电源指示灯亮起。
-
请返回应用程序屏幕继续进行设置。
-
手机上安装 “佳能打印”软件,然后搜索经过上述操作后,新出现的Wi-Fi热点,然后根据说明操作。
- 如果配置打印机连接的路由器,启用了 “Wi-Fi多频合一”(比如:TP-Link ) 则会出现无法在 “佳能打印”软件上输入 SSID 的密码的情况。这种情况下,需要在配置的时候,暂时关闭 “Wi-Fi多频合一”。在配置完成后,可以打开 “Wi-Fi多频合一” 。
参考链接
Android/iOS手机朝向获取
对于iOS手机:
苹果公司给出了一个枚举,如下:
1 2 3 4 5 6 7 8 9 |
typedef NS_ENUM (NSInteger, UIDeviceOrientation) { UIDeviceOrientationUnknown, UIDeviceOrientationPortrait, // 竖向,home键向下 UIDeviceOrientationPortraitUpsideDown, // 竖向,home键向上 UIDeviceOrientationLandscapeLeft, // 横向,home键向右 UIDeviceOrientationLandscapeRight, // 横向,home键向左 UIDeviceOrientationFaceUp, // 屏幕平放,向上 UIDeviceOrientationFaceDown // 屏幕平放,向下 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) { UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown, UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft } |
2、对于获取手机屏幕
(1)
1 2 3 4 5 |
[[ UIDevice currentDevice ] beginGeneratingDeviceOrientationNotifications ]; dispatch_async ( dispatch_get_main_queue (), ^{ NSLog ( @"=========%zd" ,[[ UIDevice currentDevice ] orientation ]); }); [[ UIDevice currentDevice ] endGeneratingDeviceOrientationNotifications ]; |
(2)
1 |
UIInterfaceOrientation orientation = [ UIApplication sharedApplication ]. statusBarOrientation ; |
3、对于当前手机是不是横屏或者竖屏的判断
(1)判断是否是竖屏
1 2 3 |
static inline BOOL UIDeviceOrientationIsPortrait( UIDeviceOrientation orientation) { return ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown ); } |
(2)判断是否是横屏
1 2 3 |
static inline BOOL UIDeviceOrientationIsLandscape( UIDeviceOrientation orientation) { return ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight ); } |
对于Android手机:
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 |
public class SimpleOrientationActivity extends Activity { OrientationEventListener mOrientationListener; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOrientationListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) { @Override public void onOrientationChanged(int orientation) { Log.v(DEBUG_TAG, "Orientation changed to " + orientation); } }; if (mOrientationListener.canDetectOrientation()) { Log.v(DEBUG_TAG, "Can detect orientation"); mOrientationListener.enable(); } else { Log.v(DEBUG_TAG, "Cannot detect orientation"); mOrientationListener.disable(); } } @Override protected void onDestroy() { super.onDestroy(); mOrientationListener.disable(); } } |
判断手机方向的具体判断代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
if (OrientationEventListener.ORIENTATION_UNKNOWN == orientation) { return; //手机平放时,检测不到有效的角度 } // 我们只关心 0, 90, 180 ,270 测试发现,很多设备返回的数据是很混乱的,但是这四个度数比较稳定 if((0 == orientation % 90) && (orientation < 360) && (orientation >= 0)) { //只检测是否有四个角度的改变 if (orientation > 350 || orientation < 10) { //0度 orientation = 0; } else if (orientation > 80 && orientation < 100) { //90度 orientation = 90; } else if (orientation > 170 && orientation < 190) { //180度 orientation = 180; } else if (orientation > 260 && orientation < 280) { //270度 orientation = 270; } else { return; } Log.i("MyOrientationDetector ", "onOrientationChanged:" + orientation); } |
对于 Flutter:
使用 native_device_orientation 插件完成相同的检测功能。
参考链接
Flutter找不到Android模拟器解决
Flutter配置好后,在Android Studio中找不到设备
完成Flutter的Android配置之后,连上设备,运行flutter doctor,发现已经识别了一个可用设备了
1 |
[✓] Connected device (1 available) |
但是用Android Studio新建Flutter项目之后,却一直显示未找到设备。
1 |
No connected devices found; please connect a device, or see flutter.io/setup for getting started ins |
最后在Stack Overflow上找到了解决方案:
就是要配置一下flutter关联的android sdk路径和android studio文件夹,我的设置完sdk路径就可以正常找到device了,问题解决~。
粗体部分替换成自己的android sdk路径:
1 |
flutter config --android-sdk /path/to/android/sdk |
粗体部分替换成自己的android studio文件夹路径(我的不用配置这个就成功了):
1 |
flutter config --android-studio-dir /path/to/android/studio |
参考链接
LocalAuthentication开发实践
在iPhone 5s加入Touch ID后,指纹识别的功能在App中逐渐受到青睐,特别是对于本地安全较高的应用(如带支付的App)指纹识别是必备的功能,它既能解决在验证过程中输入密码的繁琐过程,同时指纹识的安全等级更高。那么,要想在自己开发的应用中使用指纹识别,就必须要LocalAuthentication.framework提供的API,下面将详细地介绍如何使用这个框架来实现指纹识别功能。
基础用法
我们先来看下面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
LAContext *context = [[LAContext alloc] init]; NSError *error = nil; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"输入指纹进行验证" reply:^(BOOL success, NSError * _Nullable error) { if (success) { NSLog(@"验证成功"); } else { NSLog(@"验证失败"); } }]; } else { NSLog(@"识别功能不可用"); } |
移动端系统生物认证技术详解
相信大家对于生物认证应该不会陌生,使用指纹登陆或者 FaceId 支付等的需求场景如今已经很普遍,所以基本上只要涉及移动端开发,不管是 Android 、iOS 或者是 RN 、Flutter 都多多少少会接触到这一业务场景。
当然,不同之处可能在于大家对于平台能力或者接口能力的熟悉程度,所以本篇主要介绍 Android 和 iOS 上使用系统的生物认证需要注意什么,具体流程是什么,给需要或者即将需要的大家出一份汇总的资料。