一、如何免费使用ChatGPT
1)登录openai官网https://openai.com/,注册账号后获取免费体验;但目前已经很难成功注册openai账号了,需要魔法上网的同时代理不能使用香港、俄罗斯等地区,需要国外邮箱和国外手机号,满足这些条件也不一定能注册成功。

2)使用https://poe.com/ChatGPT替代openai,该网站接入的是gpt-3.5,注册账号后可以免费使用。
二、ChatGPT能做什么
作为一个开发人员,想要了解和使用ChatGPT,以提高工作效率为切入口,无疑是一个很好的方向(奉旨摸鱼);那我们就要先了解,ChatGPT在程序开发方向能做些什么:
1)给代码加注释
看过一个段子:我最讨厌那些写代码不写注释的人,和那些叫我写注释。。。好吧,这些脏活累活就交给ChatGPT来完成吧。
1.1、简约版输入
重新生成下面的代码片段,但请在每行代码中添加注释。{ 代码片段 }
源码:
public class BindHelper {
	private static final String TAG = "BindHelper";
	private static final long CONFIG_TIME_OUT = 100;
	public static final int BINDING_SUCCESS = 1;
	public static final int BINDING_FAILED  = 0;
	public static final int BINDING_ING     = 2;
	public static final int BINDING_IDLE    = 3;
	ITuyaActivator mTuyaActivator;
	ActivatorBuilder builder;
	IBinder iBinder;
	Context mContext;
	String mToken ;
	public BindHelper(Context mContext,IBinder iBinder) {
		this.mContext = mContext;
		this.iBinder = iBinder;
	}
	public void starBind(){
	}
	public void stopBind(){
	}
	public void onDestroy(){
	}
	protected ITuyaSmartActivatorListener mActivatorListener = new ITuyaSmartActivatorListener(){
		@Override
		public void onError(String errorCode, String errorMsg) {
			
		}
		@Override
		public void onActiveSuccess(DeviceBean devResp) {
			
		}
		@Override
		public void onStep(String step, Object data) {
		}
	};
	public int getBindSta(){
		return  BINDING_STA;
	}
}添加注释后:
/**
 * 用于设备绑定的帮助类
 */
public class BindHelper {
    // 日志标签
    private static final String TAG = "BindHelper";
    // 绑定超时时间
    private static final long CONFIG_TIME_OUT = 100;
    // 绑定成功的状态
    public static final int BINDING_SUCCESS = 1;
    // 绑定失败的状态
    public static final int BINDING_FAILED = 0;
    // 正在绑定的状态
    public static final int BINDING_ING = 2;
    // 空闲状态
    public static final int BINDING_IDLE = 3;
    // 设备绑定器
    ITuyaActivator mTuyaActivator;
    // 设备绑定器构造器
    ActivatorBuilder builder;
    // 绑定回调
    IBinder iBinder;
    // 上下文
    Context mContext;
    // 绑定用的 Token
    String mToken;
    // 构造函数
    public BindHelper(Context mContext, IBinder iBinder) {
        this.mContext = mContext;
        this.iBinder = iBinder;
    }
    // 开始绑定设备
    public void starBind() {
    }
    // 停止绑定设备
    public void stopBind() {
    }
    // 销毁
    public void onDestroy() {
    }
    // TuyaSmartActivatorListener 监听器
    protected ITuyaSmartActivatorListener mActivatorListener = new ITuyaSmartActivatorListener() {
        @Override
        public void onError(String errorCode, String errorMsg) {
        }
        @Override
        public void onActiveSuccess(DeviceBean devResp) {
        }
        @Override
        public void onStep(String step, Object data) {
        }
    };
    // 获取绑定状态
    public int getBindSta() {
        return BINDING_STA;
    }
}输入描述缺陷:
1.这个描述有个不好的地方,它要求在每一行的代码中添加注释,实际上完全没有必要,过多的注释只会增加阅读的时间成本。
2.我们完全可以要求它在遵循既有注释规范的基础上,仅在必要的地方添加注释,基于这点,我们将这个描述修改如下:
1.2、升级版输入
 请参照以下由>分隔的注释规范,对以下由```分隔的代码片段进行审查,并在注释规范要求的地方补上中文注释:
>1.对于所有的方法,都需要使用 Javadoc 注释。注释内容除了包含返回值、参数和异常说明外,还需要指出该方法的作用或实现的功能。
2.对于所有的类,都需要添加创建者和创建日期的注释。>
```代码片段```
添加注释后:
/**
 * 创建者:Unknown
 * 创建日期:Unknown
 * 描述:用于设备绑定的助手类
 */
public class BindHelper {
    // 定义常量
    private static final String TAG = "BindHelper";
    private static final long CONFIG_TIME_OUT = 100;
    public static final int BINDING_SUCCESS = 1;
    public static final int BINDING_FAILED = 0;
    public static final int BINDING_ING = 2;
    public static final int BINDING_IDLE = 3;
    // 定义变量
    ITuyaActivator mTuyaActivator;
    ActivatorBuilder builder;
    IBinder iBinder;
    Context mContext;
    String mToken;
    /**
     * 描述:构造函数
     * @param mContext 上下文
     * @param iBinder 绑定器
     */
    public BindHelper(Context mContext, IBinder iBinder) {
        this.mContext = mContext;
        this.iBinder = iBinder;
    }
    /**
     * 描述:开始设备绑定
     */
    public void starBind() {
    }
    /**
     * 描述:停止设备绑定
     */
    public void stopBind() {
    }
    /**
     * 描述:销毁
     */
    public void onDestroy() {
    }
    // TuyaSmartActivatorListener 监听器
    protected ITuyaSmartActivatorListener mActivatorListener = new ITuyaSmartActivatorListener() {
        /**
         * 描述:设备绑定出错的回调
         * @param errorCode 错误码
         * @param errorMsg 错误信息
         */
        @Override
        public void onError(String errorCode, String errorMsg) {
        }
        /**
         * 描述:设备绑定成功的回调
         * @param devResp 设备响应
         */
        @Override
        public void onActiveSuccess(DeviceBean devResp) {
        }
        /**
         * 描述:设备绑定过程中的回调
         * @param step 当前步骤
         * @param data 数据
         */
        @Override
        public void onStep(String step, Object data) {
        }
    };
    /**
     * 描述:获取绑定状态
     * @return 绑定状态
     */
    public int getBindSta(){
        return  BINDING_STA;
    }
}2)编码规范
2.1、简约版输入
遵循Kotlin的Google风格指南,重写一下代码:{输入代码}
源码:
val allowedValues = arrayListOf("a", "b", "c")
fun foo(): Int { 
    return 1 
}
for (i in 0..n - 1) { /*……*/ 

输入描述缺陷:
1.这个描述有几个不好的地方:没有提供指南的参考来源,无法验证其权威性。
2.没有指出不遵循指南的地方,而是直接重写,无法验证其风险性。
3.没有提供指南的原文描述,无法验证其准确性。
基于以上几点,我们将这个 Prompt 重写如下:
2.2、升级版输入
请参照以下由>分隔的编码规范,对以下由```分隔的代码片段进行审查,并按照下列步骤完成任务:1.指出代码片段里不符合编码规范要求的地方2.提供编码规范里对应的原文描述3.提供符合编码规范要求的修改后的代码>1.总是使用不可变集合接口(Collection, List, Set, Map)来声明无需改变的集合。使用工厂函数创建集合实例时,尽可能选用返回不可变集合类型的函数:2.对于由单个表达式构成的函数体,优先使用表达式形式。3.使用 until 函数在一个开区间上循环>
```代码片段```


3)代码转换器
3.1简约版输入
将这段代码从 Java 翻译成 Kotlin {代码片段}
 
 
    在Android中构建UI有两种方式,以XML标签为代表的静态布局,和以Java API 为代表的动态布局。前者常用于设置默认的布局样式,后者常用于运行时布局的动态调整。如果想减少对多文件的管理,就需要将XML标签转为Java代码;而如果想精简视图类的Java代码,就需要将部分Java代码转为XML标签。这种转换常常需要手动地重写,代码量一多的话简直是噩梦。现在,我们尝试把这项工作交给 ChatGPT,为此,我们将这个描述重写如下:
3.2、升级版
请将以下这个基于Android平台的XML布局文件(由```分隔)转换为Java代码实现,要求:
1.导入基于AndroidX的相关的类2.以Activity类型为上下文3.不同类型的视图用空行隔开并补上注释说明```代码片段```
源码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/sdk_toast_style"
    android:gravity="center">
    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center_horizontal"
        android:padding="@dimen/dp_20"
        android:text=""
        android:textColor="#ffffff"
        android:textSize="@dimen/sp_14" />
</RelativeLayout>转换Java代码:
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 创建 RelativeLayout 布局
        RelativeLayout relativeLayout = new RelativeLayout(this);
        relativeLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        ));
        relativeLayout.setBackgroundResource(R.drawable.sdk_toast_style);
        relativeLayout.setGravity(Gravity.CENTER);
        // 创建 TextView 视图
        TextView textView = new TextView(this);
        textView.setId(R.id.message);
        textView.setLayoutParams(new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT
        ));
        textView.setGravity(Gravity.CENTER_HORIZONTAL);
        textView.setPadding(getResources().getDimensionPixelSize(R.dimen.dp_20), 0, 0, 0);
        textView.setText("");
        textView.setTextColor(Color.parseColor("#ffffff"));
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.sp_14));
        // 将 TextView 添加到 RelativeLayout 中心
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT
        );
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        textView.setLayoutParams(layoutParams);
        relativeLayout.addView(textView);
        setContentView(relativeLayout);
    }
}4)代码解释
 
 
     5)编写应用程序
5.1、功能需求
请按照以下由>分隔的具体步骤,提供Android平台对应的完整Kotlin代码实现,包括Activity文件、布局文件以及AndroidManifest.xml文件,以完成一个“查看手机相片”的需求。
过程中要求:
1.提示我要在哪个目录创建哪个文件;2.不使用任何第三方框架;3.在必要的地方添加中文注释;>
1.页面A提供一个按钮,点击可以打开Android系统的文件浏览器,并选择系统相册中的某一张图片;2.在用户选中了某张图片后,跳转到页面B以全屏预览该图片>

下面是ChatGPT编写“查看手机相片”需求的代码:
MainActivity.kt
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
class MainActivity : AppCompatActivity() {
    private val REQUEST_CODE_CHOOSE_IMAGE = 1
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        chooseImageButton.setOnClickListener {
            openGallery()
        }
    }
    private fun openGallery() {
        // 创建选择图片的 Intent
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        // 启动选择图片的 Activity
        startActivityForResult(intent, REQUEST_CODE_CHOOSE_IMAGE)
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE_CHOOSE_IMAGE && resultCode == RESULT_OK && data != null) {
            val selectedImageUri: Uri = data.data ?: return
            // 获取图片文件的绝对路径
            val selectedImagePath = getRealPathFromUri(selectedImageUri) ?: return
            // 跳转到图片预览页面
            val intent = Intent(this, PreviewActivity::class.java)
            intent.putExtra(PreviewActivity.EXTRA_IMAGE_PATH, selectedImagePath)
            startActivity(intent)
        }
    }
    private fun getRealPathFromUri(uri: Uri): String? {
        val proj = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = contentResolver.query(uri, proj, null, null, null)
        cursor?.let {
            if (it.moveToFirst()) {
                val columnIndex = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
                return it.getString(columnIndex)
            }
        }
        return uri.path
    }
}activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="16dp">
    <Button
        android:id="@+id/chooseImageButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择图片"/>
</LinearLayout>PreviewActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_preview.*
class PreviewActivity : AppCompatActivity() {
    companion object {
        const val EXTRA_IMAGE_PATH = "extra_image_path"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_preview)
        // 获取传递过来的图片路径
        val imagePath = intent.getStringExtra(EXTRA_IMAGE_PATH) ?: return
        // 加载图片并显示
        Glide.with(this).load(File(imagePath)).into(imageView)
    }
}activity_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>
</RelativeLayout>AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.myapplication">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".PreviewActivity"/>
    </application>
</manifest>ChatGPT编写的“查看手机相片”需求,确实存在一些遗漏,如权限申请,使用glide库加载图片没有增加库依赖;手动补充后,整体需求效果是实现了的,虽然无法完全替代开发者,但一定程度上大大提高了开发者的开发效率。
当然你可以主动让ChatGPT添加权限和库依赖,慢慢调教它,在后续的需求开发中它将会考虑的更加全面,这也是它为大家所吹捧的原因之一 ,关联学习能力。



















