精华内容
下载资源
问答
  • 在这里,能够做到,就是给你描绘美好C++世界,讲述其中各色公民、风俗见闻,为各位旅行者指引方向和路径。等各位完成这奇妙C++世界之旅之后,自然会有自己答案。  从现在开始,寻找答案吧!  1.2 C++...
  • 会找例子来慢慢的逐渐深入的带大家进入powershell的世界,今天我们学的是 关于powershell2.0版本和3.0版本对于重启计算机指令的更新的几个新参数比较。 属于图形化界面的朋友们 对于重新启动计算机不会很陌生,...

    我会找例子来慢慢的逐渐深入的带大家进入powershell的世界,今天我们学的是 关于powershell2.0版本和3.0版本对于重启计算机指令的更新的几个新参数比较。


    属于图形化界面的朋友们 对于重新启动计算机不会很陌生,但是如果要是使用powershell如何做到呢?


    比起早期版本的PowerShell 2.0中重新启动计算机重新启动计算机,新的3.0版本powershell cmdlet将提供更好的灵活性和控制的管理。

    PowerShell脚本,需要间歇性重启远程计算机之间执行一个脚本来处理此cmdlet在新版本中有更好的控制。

    - 在PowerShell 3.0,重新启动计算机有15个参数,除常见的参数

    105716110.png


    - PowerShell 2.0中总共有9个参数重新启动计算机指令(win7的是自带powershell2.0哦)


    105717242.png


    1
    2
    3
    4
    5
    6
    7
    8
    9
    PS C:\Users\Administrator> get-help Restart-Computer | Select -ExpandProperty parameters |
    >> select -ExpandProperty parameter measure-object
    >>
    Count    : 9
    Average  :
    Sum      :
    Maximum  :
    Minimum  :
    Property :


    CANTGIS已经做好了一个小的Excel工作表来比较重新启动计算机新的和旧的参数指令

    105717526.jpg

    从cantgis这个小表我们可以看出PowerShell 3.0中有6个重新启动计算机的身份验证参数更名为DcomAuthentication


    重新启动计算机指令 cmdlet,允许我们作为后台作业运行重新启动操作。

    此cmdlet的Windows PowerShell 3.0中的辉煌的功能之一,我们可以等待重启完成后,再运行下一个命令,指定一个等待超时和查询间隔,等待特定的服务,可在重新启动计算机。

    这一特性使得它的实际使用重新启动计算机需要重新启动电脑之间执行的脚本。

    我们也可以使用WSMAN协议,重新启动计算机,DCOM调用被阻塞的情况下通过防火墙规则或企业策略。

    PowerShell 2.0中,此功能不可用。现在,让我们来谈谈一些很酷的功能,可用的PowerShell 3.0中引入的新的参数设置。

    示例 重新启动计算机

    我们可以在脚本中使用此参数,重新启动计算机,然后继续处理完成后重新启动。

    等待参数默认情况下,会无限期地等待电脑重新启动,但我们可以使用Timeout参数指定持续时间的等待和延迟参数等特定服务。

    3.0新参数之-Wait

    1
    Restart-Computer-ComputerNameServer01 -Wait

    此命令说明 我现在要重新启动的是 远程计算机Server01,并等待。

    默认情况下,它会检查WMI,WinRM的,和PowerShell连接移动到下一行脚本。

    下面我贴出这个cantgis的远程计算机示例图他会默认进行WMI,WinRM的检查,PowerShell连接,建立返回我的PowerShell提示符


    110812570.png

    110812572.png

    110812744.png

    110813731.png

    110813358.png

    3.0新参数之-For

    总结上面这个参数是有效的只有等待参数。有效值为:

    • 默认:等待重新启动Windows PowerShell的计算机

    • PowerShell的:可以运行在电脑上的Windows PowerShell远程会话命令。

    • WMI:接收一个的Win32_ComputerSystem查询的计算机答复。

    • WinRM的:建立一个远程会话的计算机使用WS-Management

    现在新推出的powershell ISE在PowerShell 3.0具有智能感知自动填充这些值

    112527825.png


    此命令重新启动远程计算机Server01和等待,直到WinRM服务是在远程服务器上运行起来。

    1
    Restart-Computer-ComputerNameServer01 -Wait-ForWinRM

    110951265.png



    3.0新参数之超时-Timeout

    指定的等待时间的持续时间,以秒为单位。当超时过后,重新启动计算机返回命令提示符下,即使不重新启动计算机。默认值为-1,表示无限期超时。Timeout参数是有效的只有等待参数。

    我指定超时时间为10秒,重新启动电脑,我的电脑在10秒内没有重新启动,并花了更长的时间,我立刻返回到PowerShell提示符:

    1
    Restart-Computer-ComputerNameServer01 -Wait-ForWinRM -Timeout10

    111301888.png

    3.0新参数之延迟-Delay

    这个参数往往决定所指定的参数,以确定它是否可以重新启动计算机后Windows PowerShell的查询服务。默认值是5(秒),这个参数是有效的只有等待和参数。

    下面的PowerShell示例我已经说明相同两个截图,相当于重新启动过程的进度。我已经指定了一个6秒的延迟,所以延迟后每6秒PowerShell的查询为WinRM连接到服务器,直到它能够验证的连接已经成功建立。

    111417531.png

    111418666.png


    3.0新参数之-Protocol

    指定要使用的协议重新启动计算机。有效值为WSMAN和DCOM。默认值是DCOM。这些设置旨在为企业基于DCOM重新启动失败,因为被封锁DCOM,如防火墙规则等。

    1
    Restart-Computer-ComputerNameServer01 -ProtocolWSMan

    111955346.png

    此命令重新启动远程计算机Server01和使用WSMAN协议。



    3.0新参数之-WsmanAuthentication

    指定的机制,是用来验证用户的凭据当使用WSMAN协议。有效值基本CredSSP的,默认情况下,Digest,Kerberos身份,协商。默认值是默认

    112238194.png


    1
    Restart-Computer-ComputerNameServer01 -WSManAuthenticationKerberos

    此命令重新启动远程计算机Server01和使用Kerberos身份验证。如果用户不具有的权限重新启动远程服务器,它会报出一个拒绝访问错误。


    好了! 今天 主要学习了 新的参数关于重新启动计算机,相信大家已经了解并且掌握了相关技术操作。




         本文转自cantgis 51CTO博客,原文链接:http://blog.51cto.com/cantgis/1222976,如需转载请自行联系原作者





    展开全文
  • 仍在更新此存储库内容,因此目前可能缺少一些内容 该存储库包含2015年CogSci会议上jspsych教程材料。 这些材料旨在与演示文稿一起使用,但是即使您没有参加会议,您也可能会发现它们很有用。 演示幻灯片 可以...
  • 分享知识和经验是我的义务,别无它。 ——云风 内容简介 本书忠实地记录了作者十余年来对游戏编程的所思、所感、所悟。全书按照作者本人学习和实践的过程,带着读者从基础的计算机知识到高级的编程技术,从非常...
  • 分享知识和经验是我的义务,别无它。 ——云风 内容简介 本书忠实地记录了作者十余年来对游戏编程的所思、所感、所悟。全书按照作者本人学习和实践的过程,带着读者从基础的计算机知识到高级的编程技术,从非常...
  • 在现在Siri的世界里,语音指令是极其重要的。Android原生提供Speech To Text功能,为什么不把它用在我们的程序中! 将会展示如何在程序中使用Android的Speech To Text API,现在开始写我们的demo程序。 ...
    Android有一个非常酷的特性很多开发者都还不知道。Any.DO之类应用的语音到文本转换功能很有创意。在现在Siri的世界里,语音指令是极其重要的。Android原生提供Speech To Text功能,为什么不把它用在我们的程序中!

    我将会展示如何在程序中使用Android的Speech To Text API,现在开始写我们的demo程序。

    Demo程序
    这个程序很简单。他有一个Mic符号按钮。点击之后我们触发Android的Speech To Text意图(Intent)显示一个对话框来接收语音输入。输入的语音然后会被转换成文本并显示到一个text view中。

    第一步:在Eclipse中创建基本的Android项目
    在Eclipse中创建一个Hello World Android项目。打开 New > Project > Android Project,项目名填 SpeechToTextDemo,选择Android运行时2.1或sdk7。我给定了包名:net.viralpatel.android.speechtotextdemo

    做完上面的步骤,你就有了一个基本的Android Hello World程序

    第二步:更改布局
    在我们的demo中布局很简单。只有一个图像按钮来触发Speech to Text API和一个TextView来显示从语音转换过来的文本。

    打开layout/main.xml并替换为下面的内容:
    File: res/layout/main.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView1"
        android:layout_toLeftOf="@+id/textView1"
        android:gravity="center"
        android:orientation="vertical" >
     
        <ImageButton
            android:id="@+id/btnSpeak"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:contentDescription="@string/speak"
            android:src="@android :drawable/ic_btn_speak_now" />
     
        <TextView
            android:id="@+id/txtText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:textAppearance="?android:attr/textAppearanceLarge" />
     
    </LinearLayout>


    第三步:触发Speech to Text API的Android Java代码
    打开SpeechToTextDemoActivity 类并替换为下面的代码:
    File: SpeechToTextDemoActivity.java
    package net.viralpatel.android.speechtotextdemo;
     
    import java.util.ArrayList;
     
    import android.app.Activity;
    import android.content.ActivityNotFoundException;
    import android.content.Intent;
    import android.os.Bundle;
    import android.speech.RecognizerIntent;
    import android.view.Menu;
    import android.view.View;
    import android.widget.ImageButton;
    import android.widget.TextView;
    import android.widget.Toast;
     
    public class MainActivity extends Activity {
     
        protected static final int RESULT_SPEECH = 1;
     
        private ImageButton btnSpeak;
        private TextView txtText;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            txtText = (TextView) findViewById(R.id.txtText);
     
            btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
     
            btnSpeak.setOnClickListener(new View.OnClickListener() {
     
                @Override
                public void onClick(View v) {
     
                    Intent intent = new Intent(
                            RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
     
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
     
                    try {
                        startActivityForResult(intent, RESULT_SPEECH);
                        txtText.setText("");
                    } catch (ActivityNotFoundException a) {
                        Toast t = Toast.makeText(getApplicationContext(),
                                "Opps! Your device doesn't support Speech to Text",
                                Toast.LENGTH_SHORT);
                        t.show();
                    }
                }
            });
     
        }
     
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
     
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
     
            switch (requestCode) {
            case RESULT_SPEECH: {
                if (resultCode == RESULT_OK && null != data) {
     
                    ArrayList<String> text = data
                            .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
     
                    txtText.setText(text.get(0));
                }
                break;
            }
     
            }
        }
    }

    Android Speech to text Android API的核心是包 android.speech和类android.speech.RecognizerIntent。我们触发一个意图(android.speech.RecognizerIntent)显示对话框来识别语音输入,这个Activity转换语音为文本并把结果传回我们正在调用的Activity。当我们调用android.speech.RecognizerIntent意图时,必须使用 startActivityForResult()来接听文本结果。

    注意在上面的代码中我们是怎样创建并触发意图intent android.speech.RecognizerIntent的,同时使用.putExtra()方法添加了一个参数。调用RecognizerIntent时,必须提供RecognizerIntent.EXTRA_LANGUAGE_MODE,在这里我们设置为 en-US

    由于我们的RecognizerIntent通过startActivityForResult()触发,我们重写了 onActivityResult(int requestCode, int resultCode, Intent data)方法来处理结果数据。RecognizerIntent会把语音转换为文本并把结果通过键RecognizerIntent.EXTRA_RESULTS作为ArrayList传回来。只有RESULT_OK返回时才会出现。我们只需要使用 txtText.setText()把从结果中拿到的文本设置到text view texText中。

    在这里值得注意的一件事是在不支持speech to text API的设备/Android版本中应该怎样处理。在这种情况下,当我们视图启动Activity时ActivityNotFoundException异常会被抛出。在上面的例子中,我们捕获了这个异常并使用Toast显示了一个提示信息“Opps! Your device doesn’t support Speech to Text”。

    Android应用程序的屏幕截图
    到这里就结束了! 在Android模拟器或真实设备上执行应用程序,将会看到下面的输出。
     
     
     
    展开全文
  • 我的世界服务器端(可在单人游戏中使用!)mod用于检查Fabric mod的更新。 注意:仅适用于上传到CurseForge的mod。 如何使用? 将mod放入您的mods文件夹中,并确保您运行一次。 然后,打开在配置文件夹中找到的“ ...
  • 现在几乎满世界的人都在问! 外面有人么? 这里是 USS AngularJS, 我们遇到麻烦了,我们服务讲得是克灵贡语(Klingon) 而我们控制器不能同它们Ferengi 指令通信了. 有人能帮助我们么! 已经不知道有多少次遇到...
  • 看完《华盛顿邮报》上后,开始想知道如何用Python进行这样模拟,实际上是否可以扩展这个想法并使之更现实。 一会儿,想到了用matplotlib作为可视化工具用纯Python编写模拟本身。 但是,对于大量交互...
  • 获得jarfile之后,将其放入任何我的世界版本的Fabric安装中的mods文件夹中。 需要Fabric API。 指令 前缀: } }help聊天以获取命令和模块。 }help modules聊天模块中的}help commands模块, }help commands中的}...
  • 在任何移动机器人技术项目中,知道如何估计机器人位置对于任何应用程序都是至关重要。 要确定机器人在其环境中位置,需要某种模型来根据对机器人控制输入来估计其位置。 最常见是,我们使用机器人线速度...
  • 目标产品要求编写单片机应用程序其实我们前面已经开始这样做过了这一课我们不是讲如何 来设计具体程序而是教您设计单片机程序基本方法不过在讲解之前还是有必要先了解一下单 片机程序设计语言 一.程序设计...
  • 这就是我的目标,也正是这一点,才让本书从众多相关图书中脱颖而出。另一方面,本书还包括介绍纯Java游戏的章节,通过合理均衡地分配各部分内容,希望能同时满足Java追随者和C爱好者的需要。  Android SDK兼容性 ...
  •  Joseph Sack 世界知名SQL Server技术专家,微软认证数据库管理员(MCDBA),有10多年SQL Server开发和管理工作经验。目前就职于微软公司高级现场工程组(Premier Field Engineering team)。除本书外,他撰写...
  • 面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装对象,这些对象通过一个受保护接口访问其他对象。 4. 多态性:  多态性是指允许不同类对象对同一消息作出响应。多态性包括参数化...
  • Linux(幸福Linux), Xlinux 等若干种,推荐同学们使用的发行版本是 Red Hat(事实标 准)和 Xlinux(安装最容易)。 二.安装Linux好处? Linux核心具有 Windows 无法比拟稳定性和高效率,在不使用 X ...
  • 语音转文字demo

    2017-07-08 01:11:00
    在现在Siri的世界里,语音指令是极其重要的。Android原生提供Speech To Text功能,为什么不把它用在我们的程序中! 将会展示如何在程序中使用Android的Speech To Text API,现在开始写我们的demo程序。 Demo...
    Android有一个非常酷的特性很多开发者都还不知道。Any.DO之类应用的语音到文本转换功能很有创意。在现在Siri的世界里,语音指令是极其重要的。Android原生提供Speech To Text功能,为什么不把它用在我们的程序中!
     
    我将会展示如何在程序中使用Android的Speech To Text API,现在开始写我们的demo程序。
     
    Demo程序
    这个程序很简单。他有一个Mic符号按钮。点击之后我们触发Android的Speech To Text意图(Intent)显示一个对话框来接收语音输入。输入的语音然后会被转换成文本并显示到一个text view中。
     
    第一步:在Eclipse中创建基本的Android项目
    在Eclipse中创建一个Hello World Android项目。打开 New > Project > Android Project,项目名填 SpeechToTextDemo,选择Android运行时2.1或sdk7。我给定了包名: net.viralpatel.android.speechtotextdemo
     
    做完上面的步骤,你就有了一个基本的Android Hello World程序
     
    第二步:更改布局
    在我们的demo中布局很简单。只有一个图像按钮来触发Speech to Text API和一个TextView来显示从语音转换过来的文本。
     
    打开layout/main.xml并替换为下面的内容:
    File: res/layout/main.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView1"
        android:layout_toLeftOf="@+id/textView1"
        android:gravity="center"
        android:orientation="vertical" >
     
        <ImageButton
            android:id="@+id/btnSpeak"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:contentDescription="@string/speak"
            android:src="@android :drawable/ic_btn_speak_now" />
     
        <TextView
            android:id="@+id/txtText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:textAppearance="?android:attr/textAppearanceLarge" />
     
    </LinearLayout>

     

     
    第三步:触发Speech to Text API的Android Java代码
    打开SpeechToTextDemoActivity 类并替换为下面的代码:
    File: SpeechToTextDemoActivity.java
    package net.viralpatel.android.speechtotextdemo;
     
    import java.util.ArrayList;
     
    import android.app.Activity;
    import android.content.ActivityNotFoundException;
    import android.content.Intent;
    import android.os.Bundle;
    import android.speech.RecognizerIntent;
    import android.view.Menu;
    import android.view.View;
    import android.widget.ImageButton;
    import android.widget.TextView;
    import android.widget.Toast;
     
    public class MainActivity extends Activity {
     
        protected static final int RESULT_SPEECH = 1;
     
        private ImageButton btnSpeak;
        private TextView txtText;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            txtText = (TextView) findViewById(R.id.txtText);
     
            btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
     
            btnSpeak.setOnClickListener(new View.OnClickListener() {
     
                @Override
                public void onClick(View v) {
     
                    Intent intent = new Intent(
                            RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
     
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
     
                    try {
                        startActivityForResult(intent, RESULT_SPEECH);
                        txtText.setText("");
                    } catch (ActivityNotFoundException a) {
                        Toast t = Toast.makeText(getApplicationContext(),
                                "Opps! Your device doesn't support Speech to Text",
                                Toast.LENGTH_SHORT);
                        t.show();
                    }
                }
            });
     
        }
     
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
     
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
     
            switch (requestCode) {
            case RESULT_SPEECH: {
                if (resultCode == RESULT_OK && null != data) {
     
                    ArrayList<String> text = data
                            .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
     
                    txtText.setText(text.get(0));
                }
                break;
            }
     
            }
        }
    }

     

    Android Speech to text Android API的核心是包 android.speech和类 android.speech.RecognizerIntent。我们触发一个意图(android.speech.RecognizerIntent)显示对话框来识别语音输入,这个Activity转换语音为文本并把结果传回我们正在调用的Activity。当我们调用android.speech.RecognizerIntent意图时,必须使用 startActivityForResult()来接听文本结果。
     
    注意在上面的代码中我们是怎样创建并触发意图intent android.speech.RecognizerIntent的,同时使用.putExtra()方法添加了一个参数。调用RecognizerIntent时,必须提供 RecognizerIntent.EXTRA_LANGUAGE_MODE,在这里我们设置为 en-US。
     
    由于我们的RecognizerIntent通过startActivityForResult()触发,我们重写了 onActivityResult(int requestCode, int resultCode, Intent data)方法来处理结果数据。RecognizerIntent会把语音转换为文本并把结果通过键RecognizerIntent.EXTRA_RESULTS作为ArrayList传回来。只有RESULT_OK返回时才会出现。我们只需要使用 txtText.setText()把从结果中拿到的文本设置到text view texText中。
     
    在这里值得注意的一件事是在不支持speech to text API的设备/Android版本中应该怎样处理。在这种情况下,当我们视图启动Activity时ActivityNotFoundException异常会被抛出。在上面的例子中,我们捕获了这个异常并使用Toast显示了一个提示信息“Opps! Your device doesn’t support Speech to Text”。
     
    Android应用程序的屏幕截图
    到这里就结束了! 在Android模拟器或真实设备上执行应用程序,将会看到下面的输出。
     
     
     
     

    转载于:https://www.cnblogs.com/yangjies145/p/7135207.html

    展开全文
  • 如何使用SASS编写可重用CSS JavaScript是如何工作系列 JavaScript是如何工作:引擎,运行时和调用堆栈概述 JavaScript是如何工作:深入V8引擎&编写优化代码5个技巧 JavaScript如何工作:...
  • iPhone开发秘籍(第2版)--详细书签版

    热门讨论 2012-12-11 13:42:25
    2.12 使用编译器指令 57 2.12.1 获得特定于iPhone定义 58 2.12.2 运行时检查 58 2.12.3 记忆标记 59 2.12.4 折叠方法 60 2.13 针对发布进行构建 60 2.14 清除构建 61 2.14.1 针对App Store进行编译 62 ...
  • iPhone开发秘籍(第2版)--源代码

    热门讨论 2012-12-11 13:51:22
    2.12 使用编译器指令 57 2.12.1 获得特定于iPhone定义 58 2.12.2 运行时检查 58 2.12.3 记忆标记 59 2.12.4 折叠方法 60 2.13 针对发布进行构建 60 2.14 清除构建 61 2.14.1 针对App Store进行编译 62 ...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    是一名武汉大学电子科技大3学生,学了电子线路、数字逻辑、汇编和接口、C语言,但是总是感觉很迷茫,觉好象什么都不会。怎么办? 答:大学过程是一个理论过程,实践机会比较少,往往会造成理论与实践相...
  • The Art of Assembly Language

    2009-07-30 19:06:48
    第1章 进入汇编语言的世界 1.1 本章概述 1.2 HLA程序的结构 1.3 运行第一个HLA程序 1.4 基本的HLA数据声明 1.5 布尔值 1.6 字符值 1.7 Intel80x86处理器简介 1.8 基本的机器指令 1.9 基本的HLA控制结构 1.10 HLA标准...
  • 开头 这个世界都是并发,编程里更是这样,俗话说:并发知识大,一口吃不下。想成为一名优秀 Java 开发,学好并发,绝对是你走入高薪...说了这么多缓存必要性,那么使用缓存是不是就是一个很简单事情了呢,

    开头

    这个世界都是并发的,编程里更是这样,俗话说:并发知识大,一口吃不下。想成为一名优秀的 Java 开发,学好并发,绝对是你走入高薪行列的必备能力之一。

    并发涉及的知识点,其实十分琐碎。学完记不住,记住了用不对。在并发底层原理中,不仅涉及 Java 语言,更涉及 JVM、操作系统、内存、CPU 指令等,令人一头雾水。

    这份笔记+学习脑图可以帮你系统地学习Java 并发编程知识,并告别碎片化获取知识的弊端。

    如何保证缓存和数据库一致性

    说了这么多缓存的必要性,那么使用缓存是不是就是一个很简单的事情了呢,我之前也一直是这么觉得的,直到遇到了需要缓存与数据库保持强一致的场景,才知道让数据库数据和缓存数据保持一致性是一门很高深的学问。

    从远古的硬件缓存,操作系统缓存开始,缓存就是一门独特的学问。这个问题也被业界探讨了非常久,争论至今。我翻阅了很多资料,发现其实这是一个权衡的问题。值得好好讲讲。

    以下的讨论会引入几方观点,我会跟着观点来写代码验证所提到的问题。

    不更新缓存,而是删除缓存

    大部分观点认为,做缓存不应该是去更新缓存,而是应该删除缓存,然后由下个请求去去缓存,发现不存在后再读取数据库,写入缓存。

    观点引用:《分布式之数据库和缓存双写一致性方案解析》孤独烟

    原因一:线程安全角度

    同时有请求A和请求B进行更新操作,那么会出现

    (1)线程A更新了数据库

    (2)线程B更新了数据库

    (3)线程B更新了缓存

    (4)线程A更新了缓存

    这就出现请求A更新缓存应该比请求B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存。这就导致了脏数据,因此不考虑。

    原因二:业务场景角度

    有如下两点:

    (1)如果你是一个写数据库场景比较多,而读数据场景比较少的业务需求,采用这种方案就会导致,数据压根还没读到,缓存就被频繁的更新,浪费性能。

    (2)如果你写入数据库的值,并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值,无疑是浪费性能的。显然,删除缓存更为适合。

    其实如果业务非常简单,只是去数据库拿一个值,写入缓存,那么更新缓存也是可以的。但是,淘汰缓存操作简单,并且带来的副作用只是增加了一次cache miss,建议作为通用的处理方式。

    先操作缓存,还是先操作数据库

    那么问题就来了,我们是先删除缓存,然后再更新数据库,还是先更新数据库,再删缓存呢?

    先来看看大佬们怎么说。

    《【58沈剑架构系列】缓存架构设计细节二三事》58沈剑:

    对于一个不能保证事务性的操作,一定涉及“哪个任务先做,哪个任务后做”的问题,解决这个问题的方向是:如果出现不一致,谁先做对业务的影响较小,就谁先执行。

    假设先淘汰缓存,再写数据库:第一步淘汰缓存成功,第二步写数据库失败,则只会引发一次Cache miss。

    假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cache中是旧数据,数据不一致。

    沈剑老师说的没有问题,不过没完全考虑好并发请求时的数据脏读问题,让我们再来看看孤独烟老师《分布式之数据库和缓存双写一致性方案解析》:

    先删缓存,再更新数据库

    该方案会导致请求数据不一致

    同时有一个请求A进行更新操作,另一个请求B进行查询操作。那么会出现如下情形:

    (1)请求A进行写操作,删除缓存

    (2)请求B查询发现缓存不存在

    (3)请求B去数据库查询得到旧值

    (4)请求B将旧值写入缓存

    (5)请求A将新值写入数据库

    上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。

    所以先删缓存,再更新数据库并不是一劳永逸的解决方案,再看看先更新数据库,再删缓存这种方案怎么样?

    先更新数据库,再删缓存这种情况不存在并发问题么?

    不是的。假设这会有两个请求,一个请求A做查询操作,一个请求B做更新操作,那么会有如下情形产生

    (1)缓存刚好失效

    (2)请求A查询数据库,得一个旧值

    (3)请求B将新值写入数据库

    (4)请求B删除缓存

    (5)请求A将查到的旧值写入缓存

    ok,如果发生上述情况,确实是会发生脏数据。

    然而,发生这种情况的概率又有多少呢?

    发生上述情况有一个先天性条件,就是步骤(3)的写数据库操作比步骤(2)的读数据库操作耗时更短,才有可能使得步骤(4)先于步骤(5)。可是,大家想想,数据库的读操作的速度远快于写操作的(不然做读写分离干嘛,做读写分离的意义就是因为读操作比较快,耗资源少),因此步骤(3)耗时比步骤(2)更短,这一情形很难出现。

    先更新数据库,再删缓存依然会有问题,不过,问题出现的可能性会因为上面说的原因,变得比较低!

    (补充说明:我用了“先更新数据库,再删缓存”且不设过期时间策略,会不会有问题呢?由于先缓存和更新数据库不是原子的,如果更新了数据库,程序歇逼,就没删缓存,由于没有过期策略,就永远脏数据了。)

    所以,如果你想实现基础的缓存数据库双写一致的逻辑,那么在大多数情况下,在不想做过多设计,增加太大工作量的情况下,请先更新数据库,再删缓存!

    我非要数据库和缓存数据强一致怎么办

    那么,如果我非要保证绝对一致性怎么办,先给出结论:

    没有办法做到绝对的一致性,这是由CAP理论决定的,缓存系统适用的场景就是非强一致性的场景,所以它属于CAP中的AP。

    所以,我们得委曲求全,可以去做到BASE理论中说的最终一致性

    最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性

    大佬们给出了到达最终一致性的解决思路,主要是针对上面两种双写策略(先删缓存,再更新数据库/先更新数据库,再删缓存)导致的脏数据问题,进行相应的处理,来保证最终一致性。

    缓存延时双删

    问:先删除缓存,再更新数据库中避免脏数据?

    答案:采用延时双删策略。

    上文我们提到,在先删除缓存,再更新数据库的情况下,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。

    那么延时双删怎么解决这个问题呢?

    (1)先淘汰缓存

    (2)再写数据库(这两步和原来一样)

    (3)休眠1秒,再次淘汰缓存

    这么做,可以将1秒内所造成的缓存脏数据,再次删除。

    那么,这个1秒怎么确定的,具体该休眠多久呢?

    针对上面的情形,读者应该自行评估自己的项目的读数据业务逻辑的耗时。然后写数据的休眠时间则在读数据业务逻辑的耗时基础上,加几百ms即可。这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。

    如果你用了mysql的读写分离架构怎么办?

    ok,在这种情况下,造成数据不一致的原因如下,还是两个请求,一个请求A进行更新操作,另一个请求B进行查询操作。

    (1)请求A进行写操作,删除缓存

    (2)请求A将数据写入数据库了,

    (3)请求B查询缓存发现,缓存没有值

    (4)请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值

    (5)请求B将旧值写入缓存

    (6)数据库完成主从同步,从库变为新值

    上述情形,就是数据不一致的原因。还是使用双删延时策略。只是,睡眠时间修改为在主从同步的延时时间基础上,加几百ms。

    采用这种同步淘汰策略,吞吐量降低怎么办?

    ok,那就将第二次删除作为异步的。自己起一个线程,异步删除。这样,写的请求就不用沉睡一段时间后了,再返回。这么做,加大吞吐量。

    所以在先删除缓存,再更新数据库的情况下,可以使用延时双删的策略,来保证脏数据只会存活一段时间,就会被准确的数据覆盖。

    在先更新数据库,再删缓存的情况下,缓存出现脏数据的情况虽然可能性极小,但也会出现。我们依然可以用延时双删策略,在请求A对缓存写入了脏的旧值之后,再次删除缓存。来保证去掉脏缓存。

    总目录展示

    该笔记共八个节点(由浅入深),分为三大模块。

    高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。该笔记将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。

    一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,将用一个节点来专门讲解如何设计秒杀减库存方案。

    高可用。 虽然介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。笔记的最后,将带你思考可以从哪些环节来设计兜底方案。


    篇幅有限,无法一个模块一个模块详细的展示(这些要点都收集在了这份《高并发秒杀顶级教程》里),觉得有需要的码友们,麻烦各位转发一下(可以帮助更多的人看到哟!)点这里,即可获得免费下载的方式!!

    由于内容太多,这里只截取部分的内容。需要这份《高并发秒杀顶级教程》的小伙伴,麻烦各位帮忙点赞分享支持一下(可以帮助更多的人看到哟!)
    .qq.com/doc/DSmxTbFJ1cmN1R2dB)

    [外链图片转存中…(img-KR4D71Lt-1623234511911)]

    [外链图片转存中…(img-MLOqwfJE-1623234511915)]

    由于内容太多,这里只截取部分的内容。需要这份《高并发秒杀顶级教程》的小伙伴,麻烦各位帮忙点赞分享支持一下(可以帮助更多的人看到哟!)

    展开全文
  • Rational Rose教程

    热门讨论 2009-04-18 17:56:24
    本教程通过指导你一步步地进行一个复杂业务问题真正实现解决,教给你如何使用Rose。 估计完成时间:完成整个教程需要花大约10小时。当然可以从任何部分开始和结束,剩下部分以后再看。每一部分还有完成该部分...
  • 在黑客的世界里,当你拋出一个技术问题时,最终是否能得到有用的回答,往往取决于你所提问和追问的方式。本指南将教你如何正确的提问以获得你满意的答案。 不只是黑客,现在开源(Open Source)软件已经相当盛行,你...
  •  Ivor Horton是世界著名计算机图书作家,主要从事与编程相关咨询及撰写工作,曾帮助无数程序员步入编程殿堂。他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了...
  • 在黑客的世界裡,當你拋出一個技術問題時,最終是否能得到有用的回答,往往取決於你所提問和追問的方式。本指南將教你如何正確的提問以獲得你滿意的答案。 不只是黑客,現在開放原始碼(Open Source)軟體已經相當...
  • 第十二章 创造我们的世界 161 12.1 程序流程 161 12.2 程序结构 162 12.3 基本方法 163 12.4 SLG编程要点 163 12.4.1 电脑AI 163 12.5 RPG & ARPG编程要点 163 12.5.1 迷宫的生成 163 12.5.2 脚本技术 163 12.6...

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

我的世界指令如何使用