Java入門級教程17——利用Java SPI機制制作驗證碼、利用Java RMI機制實現分布式登錄驗證系統

目錄

1.制作驗證碼——java SPI機制

1.1 類所屬包情況

1.2 具體實現

1.2.1 核心接口:ICode?

1.2.2 接口實現類:驗證碼的具體生成邏輯

1.2.3 服務工廠類:CodeServiceFactory(核心:SPI 服務發現)

1.2.4 SPI 配置文件

1.2.5 主程序:App(運行入口)

1.2.6 注釋掉不同的配置

2.Java RMI (遠程方法調用)

2.1 定義

2.2 實現分布式登錄驗證系統

2.2.1 數據庫準備

2.2.2 在idea中啟動Java的RMI服務

2.2.3 在eclipse實現登錄


1.制作驗證碼——java SPI機制

1.1 類所屬包情況

1.2 具體實現

1.2.1 核心接口:ICode?

定義驗證碼生成的標準接口,所有驗證碼生成實現類都需要實現該接口

package com.hy.interfaces;public interface ICode {public String makeCode();
}

1.2.2 接口實現類:驗證碼的具體生成邏輯

① 數字驗證碼實現:NumberCodeImpl

package com.hy.interfaces.impl;import java.util.Random;
import com.hy.interfaces.ICode;public class NumberCodeImpl implements ICode {// 數字字符源(0-9)private String[] nums = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };@Overridepublic String makeCode() {String code = "";for (int i = 0; i < 4; i++) { // 生成4位驗證碼// 隨機獲取字符源中的一個元素String s = String.valueOf(new Random().nextInt(nums.length));// 確保字符不重復:如果已包含則重新生成(i--回退循環)if (!code.contains(s)) {code += s;} else {i--;}}return code;}
}

② 中文驗證碼實現:ChineseCodeImpl

package com.hy.interfaces.impl;import java.util.Random;
import com.hy.interfaces.ICode;public class ChineseCodeImpl implements ICode {// 中文字符源(自定義漢字)private String[] nums = { "趙", "錢", "孫", "李", "王", "五", "馬", "六", "天", "地" };@Overridepublic String makeCode() {String code = "";for (int i = 0; i < 4; i++) { // 生成4位驗證碼// 隨機獲取字符源中的一個元素String s = nums[new Random().nextInt(nums.length)];// 確保字符不重復:如果已包含則重新生成(i--回退循環)if (!code.contains(s)) {code += s;} else {i--;}}return code;}
}

1.2.3 服務工廠類:CodeServiceFactory(核心:SPI 服務發現)

利用 Java 的 ServiceLoader 類實現 SPI 機制的服務發現:通過接口(ICode.class)動態加載其所有實現類

package com.hy.service;import java.util.Iterator;
import java.util.ServiceLoader;
import com.hy.interfaces.ICode;public class CodeServiceFactory {public static String createCode(Class targetClass) {// 1. 通過ServiceLoader動態加載實現了targetClass(此處為ICode)的服務實現類ServiceLoader s = ServiceLoader.load(targetClass);// 2. 獲取實現類的迭代器Iterator its = s.iterator();ICode code = null;// 3. 迭代獲取最后一個實現類(若有多個實現,取最后一個)while (its.hasNext()) {code = (ICode) its.next();}// 4. 調用實現類的makeCode()生成驗證碼String checkCode = code.makeCode();return checkCode;}
}

1.2.4 SPI 配置文件

#?開頭的行是注釋,不會被加載,需要實現哪個,就把其余注釋掉

com.hy.interfaces.impl.NumberCodeImpl
#com.hy.interfaces.impl.ChineseCodeImpl

1.2.5 主程序:App(運行入口)

主方法通過無限循環,每 6 秒調用一次工廠類的createCode方法,生成驗證碼

package com.hy.javaspi;import com.hy.interfaces.ICode;
import com.hy.service.CodeServiceFactory;public class App {public static void main(String[] args) {while (true) { // 無限循環// 調用工廠類生成驗證碼(基于ICode接口的實現類)String checkCode = CodeServiceFactory.createCode(ICode.class);System.out.println("獲取的驗證碼為:" + checkCode);try {Thread.sleep(6000); // 每6秒生成一次} catch (InterruptedException e) {e.printStackTrace();}}}
}

1.2.6 注釋掉不同的配置

① 使用數字驗證碼

com.hy.interfaces.impl.NumberCodeImpl
#com.hy.interfaces.impl.ChineseCodeImpl

輸出結果:

獲取的驗證碼為:2834
獲取的驗證碼為:9651
獲取的驗證碼為:0753
獲取的驗證碼為:4702

...

② 使用中文驗證碼

#com.hy.interfaces.impl.NumberCodeImpl
com.hy.interfaces.impl.ChineseCodeImpl

輸出結果:

獲取的驗證碼為:五李孫地
獲取的驗證碼為:錢孫六李
獲取的驗證碼為:趙馬地王
獲取的驗證碼為:馬五李地

...

2.Java RMI (遠程方法調用)

2.1 定義

Java RMI(Remote Method Invocation,遠程方法調用)是 Java 原生的分布式通信機制,允許一個 JVM 中的對象(客戶端調用另一個 JVM 中的對象(服務端)的方法,就像調用本地方法一樣,無需顯式處理網絡通信細節。

2.2 實現分布式登錄驗證系統

2.2.1 數據庫準備

-- 創建t_emps表 --
CREATE TABLE t_emps(eid INT PRIMARY KEY auto_increment, -- 員工的編號ename VARCHAR(20) NOT NULL, -- 員工的姓名epwd CHAR(8) NOT NULL, -- 員工的密碼ebirthday datetime, -- 員工的出生年月,不設計年齡字段,會造成字段冗余esalary DOUBLE NOT NULL, -- 員工的工資eaddress VARCHAR(100), -- 員工的地址estate INT NOT NULL -- 員工的狀態
)-- 刪除t_emps表 --
DROP TABLE t_emps-- 插入數據 --
INSERT INTO t_emps(ename,epwd,ebirthday,esalary,eaddress,estate)
VALUES('張三','11111','2000-05-28',90000.56,'南京',1);INSERT INTO t_emps(ename,epwd,ebirthday,esalary,eaddress,estate)
VALUES('李四','22222','2004-06-15',88000.69,'鹽城',1);INSERT INTO t_emps(ename,epwd,ebirthday,esalary,eaddress,estate)
VALUES('李老八','22222','1996-12-30',5600,'無錫',1);INSERT INTO t_emps(ename,epwd,ebirthday,esalary,eaddress,estate)
VALUES('趙二','22222','1996-12-30',5800,'無錫',0);-- 查詢表 --
SELECT * FROM t_emps

實現效果:

2.2.2 在idea中啟動Java的RMI服務

步驟一:在idea中新建Maven項目,并在pom.xml文件中添加依賴

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.24</version>
</dependency>

步驟二:具體實現

① 類所屬包情況

② 數據訪問層:Dao類(數據庫交互)

通過 JDBC 連接 MySQL 數據庫,實現 “登錄驗證” 的數據庫交互邏輯

package com.hy.dao;import java.sql.*;public class Dao {Connection conn; // 數據庫連接對象// 構造方法:初始化數據庫連接public Dao() {try {// 1. 加載MySQL JDBC驅動(MySQL 8.0+使用com.mysql.cj.jdbc.Driver)Class.forName("com.mysql.cj.jdbc.Driver");// 2. 建立數據庫連接// 連接URL:jdbc:mysql://主機:端口/數據庫名// 用戶名:root,密碼:修改為自己的密碼conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysql2025", "root", "yourpassword");} catch (ClassNotFoundException e) {e.printStackTrace(); // 驅動類未找到異常} catch (SQLException e) {e.printStackTrace(); // 數據庫連接異常}}// 登錄驗證方法:檢查用戶名和密碼是否匹配public int checkLogin(String username, String userpwd) {// SQL查詢:統計符合條件的用戶數量(ename=用戶名且epwd=密碼)String sql = "select count(ename) from t_emps where ename = ? and epwd =?";int count = 0; // 匹配的用戶數量(0或1)try {// 使用PreparedStatement預編譯SQL,防止SQL注入PreparedStatement pstmt = this.conn.prepareStatement(sql);pstmt.setString(1, username); // 填充第一個參數(用戶名)pstmt.setString(2, userpwd);  // 填充第二個參數(密碼)// 執行查詢,獲取結果集ResultSet rs = pstmt.executeQuery();// 讀取結果集中的計數(count(ename))while (rs.next()) {count = rs.getInt(1); // 第一列的結果(0或1)}} catch (SQLException e) {e.printStackTrace(); // SQL執行異常} finally {// 關閉數據庫連接(避免資源泄露)if (null != conn) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}return count; // 返回匹配數量(1表示登錄成功,0表示失敗)}
}

③ 遠程接口:IData(定義 RMI 通信標準)

定義客戶端與服務端的 “通信協議”,明確可遠程調用的方法,是 RMI 通信的基礎(客戶端與服務端必須完全一致)。

package com.hy.data.interfaces;import java.rmi.Remote;
import java.rmi.RemoteException;// 客戶端與服務端的遠程通信接口(必須繼承Remote)
public interface IData extends Remote {// 遠程方法:查詢消息(必須聲明拋出RemoteException)public String queryMessage() throws RemoteException;// 遠程方法:登錄驗證(必須聲明拋出RemoteException)public String checkLogin(String username, String userpwd) throws RemoteException;
}

④?遠程接口實現:UserDataImpl(服務端業務邏輯)

實現IData遠程接口,封裝服務端業務邏輯(調用 Dao 層操作數據庫),并通過 RMI 框架導出為 “可遠程訪問的對象”。

package com.hy.impl;import com.hy.dao.Dao;
import com.hy.data.interfaces.IData;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;// 遠程接口的實現類(必須繼承UnicastRemoteObject或手動實現序列化)
public class UserDataImpl extends UnicastRemoteObject implements IData {// 構造方法:必須拋出RemoteException(因為父類UnicastRemoteObject的構造方法拋出該異常)public UserDataImpl() throws RemoteException {super(); // 調用父類構造方法,自動處理對象的網絡傳輸(序列化/反序列化)}// 實現遠程方法:返回固定消息@Overridepublic String queryMessage() throws RemoteException {return "RMI分布式從遠程傳過來的數據為:RMI、webservice、hessian、thrift、googleRPC、Dubbo";}// 實現遠程方法:調用Dao進行登錄驗證@Overridepublic String checkLogin(String username, String userpwd) throws RemoteException {Dao dao = new Dao(); // 創建數據訪問對象// 調用Dao的checkLogin方法,若返回值>0(即存在匹配用戶),返回"登錄成功",否則返回"登錄失敗"if (dao.checkLogin(username, userpwd) > 0) {return "登錄成功";}return "登錄失敗";}
}

⑤?RMI 服務端:ServerRMI(啟動并發布服務)

啟動 RMI 注冊表(服務注冊中心)、創建遠程對象實例、將遠程對象綁定到指定 URL,供客戶端查找和調用。

package com.hy.serverrmi;import com.hy.data.interfaces.IData;
import com.hy.impl.UserDataImpl;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;public class ServerRMI {public static void main(String[] args) {try {// 1. 創建遠程對象實例(UserDataImpl實現了IData接口)IData datas = new UserDataImpl();// 2. 在本地9200端口注冊RMI注冊表(類似“服務注冊中心”)LocateRegistry.createRegistry(9200);// 3. 將遠程對象綁定到RMI URL(客戶端通過該URL查找服務)// 格式:rmi://主機:端口/服務名稱Naming.bind("rmi://127.0.0.1:9200/userdatas", datas);System.out.println("Java的RMI服務已經啟動成功");} catch (RemoteException e) {e.printStackTrace(); // 遠程對象創建或注冊表啟動異常} catch (MalformedURLException e) {e.printStackTrace(); // RMI URL格式錯誤} catch (AlreadyBoundException e) {e.printStackTrace(); // 服務名稱已被綁定(重復發布)}}
}

輸出結果:

Java的RMI服務已經啟動成功

2.2.3 在eclipse實現登錄

① 類所屬包情況

② 遠程接口:IData(客戶端與服務端的通信契約)

客戶端與服務端的 “通信協議”,定義客戶端可以遠程調用的方法。

package com.hy.data.interfaces;import java.rmi.Remote;
import java.rmi.RemoteException;// 遠程接口:客戶端和服務端必須共享此接口(包路徑、方法定義完全一致)
public interface IData extends Remote {// 遠程方法1:查詢消息(服務端返回預設字符串)public String queryMessage() throws RemoteException;// 遠程方法2:登錄驗證(接收用戶名和密碼,返回登錄結果)public String checkLogin(String username, String userpwd) throws RemoteException;
}

③?客戶端實現類:App(發起遠程調用的核心邏輯)

接收用戶輸入(賬號密碼),通過 RMI 框架查找服務端遠程對象,發起遠程調用,最后展示調用結果。

package com.hy.javamiclinet;import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Scanner;
import com.hy.data.interfaces.IData;public class App {// 遠程對象引用:客戶端通過該引用調用服務端方法static IData data = null;// 靜態代碼塊:初始化遠程對象引用(程序啟動時執行)static {try {// 關鍵:通過RMI URL查找服務端綁定的遠程對象// URL格式:rmi://服務端IP:端口/服務名稱(需與服務端綁定的URL完全一致)data = (IData) Naming.lookup("rmi://127.0.0.1:9200/userdatas");} catch (MalformedURLException e) {e.printStackTrace(); // URL格式錯誤(如端口無效、協議錯誤)} catch (RemoteException e) {e.printStackTrace(); // 遠程通信異常(如服務端未啟動、網絡不通)} catch (NotBoundException e) {e.printStackTrace(); // 服務名稱未綁定(服務端未發布該服務)}}// 調用遠程方法:queryMessage(查詢消息)public void queryMsg() {try {// 看似調用本地對象方法,實際通過網絡調用服務端的實現String message = data.queryMessage();System.out.println("客戶端遠程調用服務端的結果為:" + message);} catch (RemoteException e) {e.printStackTrace(); // 遠程調用過程中發生異常}}// 調用遠程方法:checkLogin(登錄驗證)public void checkLogin(String username, String userpwd) {try {// 傳遞參數(用戶名和密碼)到服務端,調用遠程驗證方法String result = data.checkLogin(username, userpwd);System.out.println("客戶端遠程調用服務端登錄的結果為:" + result);} catch (RemoteException e) {e.printStackTrace(); // 遠程調用異常(如參數傳輸失敗、服務端處理出錯)}}// 主方法:程序入口,接收用戶輸入并發起登錄驗證public static void main(String[] args) {App app = new App(); // 創建客戶端實例// 接收用戶輸入(用戶名和密碼)System.out.println("請輸入用戶姓名:");Scanner s1 = new Scanner(System.in);String username = s1.next(); // 讀取用戶名System.out.println("請輸入用戶密碼:");Scanner s2 = new Scanner(System.in);String userpwd = s2.next(); // 讀取密碼// 調用登錄驗證方法(遠程調用)app.checkLogin(username, userpwd);// 可選:調用查詢消息方法(注釋掉了,取消注釋可執行)// app.queryMsg();}
}

輸出結果:

請輸入用戶姓名:
張三
請輸入用戶密碼:
11111
客戶端遠程調用服務端登錄的結果為:登錄成功

請輸入用戶姓名:
張三
請輸入用戶密碼:
22222
客戶端遠程調用服務端登錄的結果為:登錄失敗

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96202.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96202.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96202.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ES6筆記5

1. Promise相當于一個容器&#xff0c;保存著未來才要結束的事件&#xff08;異步操作&#xff09;的一個結果&#xff0c;各種異步操作都可以用同樣方法處理 axios特點&#xff1a;對象的狀態不受外界影響&#xff0c;處理異步操作&#xff0c;3個狀態&#xff0c;Pending&…

解決idea2021maven依賴導入后還是找不到包,爆紅無法導入

1.依賴導入后pom.xml文件以及Maven,此兩處代碼還是爆紅 2.解決方法 由技術大佬同事幾分鐘解決,他記憶深刻之前搞過很久,一看就知道哪里出問題了 我之前是配過Maven的本地倉庫的但是沒有用,這次出問題之后長教訓了,技術大佬說盡量用自己的本地倉庫,不要用idea的Maven倉庫,容易…

【硬件-筆試面試題-81】硬件/電子工程師,筆試面試題(知識點:詳細講講同步時鐘與異步時鐘通信)

題目匯總版--鏈接&#xff1a; 【硬件-筆試面試題】硬件/電子工程師&#xff0c;筆試面試題匯總版&#xff0c;持續更新學習&#xff0c;加油&#xff01;&#xff01;&#xff01;-CSDN博客 【硬件-筆試面試題-81】硬件/電子工程師&#xff0c;筆試面試題&#xff08;知識點…

php計算一個模擬增長過程函數

private function calculateGrowth($progress) {// 使用多個增長階段模擬不均勻性if ($progress < 0.3) {// 前30%時間&#xff1a;緩慢增長 30 %return pow($progress / 0.3, 0.7) * 0.3;} elseif ($progress < 0.7) {// 中間40%時間&#xff1a;快速增長 50%return 0.3…

華為USG6000v2 NAT模式下IPSEC IKE V1 實驗

USG6000v2 NAT模式下IPSEC 實驗 拓撲圖公網配置OSPF路由協議&#xff08;網絡要求能通就行&#xff09; 一、 總部配置 &#xff08;一&#xff09;交換機配置 1、 總部交換機到防火墻網段 192.168.10.0/24 2、 交換機G0/0設置成access端口劃分vlan 10&#xff0c;網關 192.168…

android 里設計context的作用

Android中的Context是一個核心設計機制&#xff0c;其作用主要體現在以下幾個方面&#xff1a; 1. 提供應用程序環境信息 Context作為抽象類&#xff0c;封裝了應用與系統交互所需的全局環境信息&#xff0c;包括資源訪問、組件啟動、系統服務調用等基礎能力。它本質上是應用…

能發彈幕的簡單視頻網站

界面參考了Youtube&#xff0c;后端使用Spring Boot&#xff0c;前端Vue&#xff0c;vuetifyjs。支持自動生成封面圖&#xff0c;發送彈幕、AI內容審核等功能。 一個簡單的視頻網站 網站名稱是 TikTok 與 YouTube 的縫合&#xff0c;Logo 為豆包 AI 生成 主要界面參考了 Yout…

了解網站安全監測系統的重要性

在當今數字化時代&#xff0c;網站已經成為企業發展和品牌推廣的關鍵渠道之一。然而&#xff0c;隨之而來的是網絡安全威脅的增加&#xff0c;包括數據泄露、惡意攻擊和病毒感染等問題。為了保護網站和用戶信息的安全&#xff0c;網站安全監測系統變得至關重要。1. 網站安全監測…

fastadmin安裝后后臺提示putenv()報錯,不顯示驗證碼

1.安裝fastadmin后&#xff0c;訪問項目后臺&#xff0c;提示報錯&#xff1a;Warning: putenv() has been disabled for security reasons in /www/wwwroot/app.aaa.cn/thinkphp/base.php on line 50 這時候驗證碼還不顯示&#xff0c;怎么解決呢&#xff1f;2.打開php.ini文件…

C語言深度入門系列:第二篇 - 變量與數據類型:程序世界的基本粒子與容器

C語言深度入門系列&#xff1a;第二篇 - 變量與數據類型&#xff1a;程序世界的基本粒子與容器 本章目標 本章將深入探討程序如何“記住”信息。你將徹底理解變量的本質是內存中的一塊空間&#xff0c;數據類型是解釋這塊內存中0和1的規則。我們將超越簡單的int, float用法&…

十一旅游中國氣象攻略:如何評估降雨、大風與紫外線

一、十一期間的中國氣候態要點(10 月上旬) 冷空氣南下增多:華北—東北易大風降溫;長江以南易出現冷暖空氣交匯降雨。 臺風未完全退場:華南沿海與海南、華東沿海仍可能受外圍環流與風雨影響。 晝夜溫差擴大:西北、華北、內陸盆地早晚涼,白天熱,霧/霜風險抬頭。 高原與…

鴻蒙項目篇-21-創建項目、修改軟件文字/圖標

目錄 【預覽】修改配置文件 module.json5 創建項目 初次-運行預覽 拷貝圖片 用于替換 【實操】修改配置文件 module.json5 點擊,顯示引用 ctrl + 點擊,引用追蹤 置頂模擬器 最終代碼 總結 先規劃再行動【高效】以終為始【不偏離方向/目標】 【預覽】修改配置文件 m…

Linux服務器的系統安全強化超詳細教程

Linux服務器幾乎承擔著最重要的計算和存儲角色&#xff0c;它是企業網站、數據庫、應用中間件、開發環境乃至云原生容器平臺的核心。正因為Linux服務器的廣泛應用&#xff0c;它也成為攻擊者頻繁鎖定的目標。系統一旦被攻破&#xff0c;不僅業務會面臨中斷&#xff0c;更嚴重的…

計算機畢設 java 高校會議室預約管理系統 基于 SSM 框架的高校會議室管理平臺 Java+MySQL 的預約全流程管控系統

計算機畢設java高校會議室預約管理系統z14559 &#xff08;配套有源碼 程序 mysql數據庫 論文&#xff09;本套源碼可以先看具體功能演示視頻領取&#xff0c;文末有聯xi 可分享在高校會議室資源緊張的背景下&#xff0c;傳統預約依賴人工登記、信息傳遞滯后&#xff0c;存在預…

Redis的持久化機制RDB和AOF詳解

本文為您介紹redis的持久化機制以及持久化的選型。 目錄 持久化策略 RDB(RedisDatabase)快照 AOF(Append Only File) 混合持久化策略 RDB與AOF對比 持久化策略使用建議 Redis數據備份策略建議 補充知識 save與bgsave對比 bgsave的寫時復制(COW)機制 持久化策略 Red…

Vue 3 實戰:從零到一用 vue-pdf-embed 打造功能齊全的 PDF 查看器

你好&#xff0c;Vue 開發者們&#xff01; 在 Web 開發中&#xff0c;我們經常會遇到需要在頁面中直接展示 PDF 文件的需求&#xff0c;例如預覽合同、顯示報告或在線閱讀文檔。你可能會想到用 <iframe> 或者一些重量級的庫&#xff0c;但它們往往不夠靈活或過于臃腫。…

adb的常用命令

adb devices 用USB數據線連接電腦&#xff0c;查看連接上的設備 adb tcpip 5555 切換計算機的adb為wifi連接模式 adb connect 192.168.2.250:5555 連接手機的ip地址&#xff0c;如果連接成功&#xff0c;則可拔掉數據線 adb 查看adb的相關信息&#xff0c;包括版本號&#xff0…

穩態太陽光模擬器 | 多源分布式設計的要點有哪些?

穩態太陽模擬器的多源分布式設計&#xff0c;是一種通過多組獨立光源單元分布式排布、結合穩態光學調控技術&#xff0c;實現對太陽光譜、輻照強度及輻照均勻性精準復現的高端光模擬技術。其核心優勢在于突破傳統模擬光源在長期工作穩定性、大面積輻照均勻性及能量傳遞效率上的…

代碼隨想錄 day 35 動態規劃

第九章 動態規劃part03 正式開始背包問題&#xff0c;背包問題還是挺難的&#xff0c;雖然大家可能看了很多背包問題模板代碼&#xff0c;感覺挺簡單&#xff0c;但基本理解的都不夠深入。 如果是直接從來沒聽過背包問題&#xff0c;可以先看文字講解慢慢了解 這是干什么的。 …

大數據探索性分析——抽樣技術應用

2.3 概率抽樣 一、簡單隨機抽樣 # 數據預處理 LoanStats3c read.csv("D:/OneDrive - stu.fynu.edu.cn/大四上學期/ysq-大數據探索性分析/data/2數據集二&#xff1a;Loan Data--Lending Club/LoanStats3c/LoanStats3c.csv", header TRUE, fill TRUE, comment.char…